• 第十部分_Struts2.1详述与MVC设计模式


    讲了诸多原理性的东西,下面该来看看如何实践了:

    首先,在MyEclipse中新建一个Web Project,命名为struts2(注意这里我用的版本是struts2.1.6),规范级别选择Java EE 5.0,当然了,我们仍然需要告诉Tomcat我们的项目在哪里,因此到Tomcat安装目录下的conf文件夹下的server.xml文件,为了节约时间,我们把test项目的上下文放到注释中,以免每次启动tomcat,都要加载该项目,相关配置部分如下:

     <!--
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
                   prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
    <Context path="/test" docBase="D:JavaWeb	estWebRoot" reloadable="true"/>
    
            -->
    
    <Context path="/struts2" docBase="D:JavaWebstruts2WebRoot" reloadable="true"/>
    
    
          </Host>
        </Engine>
      </Service>
    </Server>
    

    重启tomcat服务器,访问http://localhost:8080/struts2,页面出现"This is my JSP page." 表示我们的项目已经纳入Tomcat的管理之下了。我们将structs2框架集成到我们新建的项目中,其实就是将structs2提供的JAR包添加到项目了,其中我们需要的JAR包有(在解压好的structs的解压文件中的lib目录下)commons-fileupload-1.2.1.jar、commons-logging-1.0.4.jar、freemarker-2.3.13.jar、ognl-2.6.11.jar、struts2-core-2.1.6.jar、xwork-core-2.1.2.jar共六个文件选中复制,回到MyEclipse,粘贴到WebRoot下面的WEB-INF下的lib目录下,这样这些第三方库就可以为我们所用了。

    下面,我们用struts2写一个经典的hello world,标志学习struct2的起步:

    在WebRoot下新建一个helloworld.jsp文件,将body中的内容更改为Hello World。当然我们可以直接访问http://localhost:8080/struts2/helloworld.jsp。但是这里我们通过struct2的控制实现间接访问:在src目录下新建一个包com.test.action,然后再改包下建立一个名为helloworld的类,定义一个execute方法:

    package com.test.action;
    
    public class helloworld
    {
    	public String execute() throws Exception
    	{
    		return "success";
    	}
    }
    

    struts2的一个核心的东西是一个配置文件,该文件的默认名字为struts.xml,这个文件就描述了整个流程的转发以及执行过程。在src下新建一个名为struts的xml文件,解压缩struts2目录下的apps下的struts2-blank文件,展开下面的WEB-INF,打开src,打开java,找到struts.xml文件,打开将其头部的dtd(验证我们的struts.xml文件)信息粘贴到我们的新建的xml文件中(这里访问的时候并不是去网络中找dtd文件,这样的话dtd文件较大的话会拖慢运行速度,实际上它是先到本机中寻找,找不到再到网络中找,我们这里就是在本机的struts2-core-2.1.6.jar下面的struts-2.0.dtd中):

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    

    利用MyEclipse的提示功能完整的xml文件内容如下(其中extends="struts-default"是为了引入本机struts2-core-2.1.6.jar下面的struts-default.xml,这样我们就拥有了struts2的基本功能):

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="struts2" extends="struts-default"> <action name="helloworld" class="com.test.action.HelloWorld"> <result name="success">/helloworld.jsp</result> </action> </package> </struts>

      MyEclipse会自动的把这个文件copy一份复制到项目的WEB-INF目录下的classes目录下,我们之所以建立在src目录下,是为了在IDE中可以编辑它。

    接下来,在web.xml中配置如下(配置之前需要的相关信息可以在D:Program Filesstruts-2.1.6docsstruts2-coreapidocs里找到index.html中找到org.apache.struts2包下面的FilterDispatcher类,里面有一个信息:Deprecated. Since Struts 2.1.3, useStrutsPrepareAndExecuteFilter instead orStrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one,用来提示我们用新的类代替旧的类,可以看到StrutsPrepareAndExecuteFIlter的包名为:org.apache.struts2.dispatcher.ng.filter

    ):

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
    	xmlns="http://java.sun.com/xml/ns/javaee" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      
      <filter>
      	<filter-name>struts2</filter-name>
      	<filter-class>
      		org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
      	</filter-class>
      </filter>
      
      <filter-mapping>
      	<filter-name>struts2</filter-name>
      	<url-pattern>/*</url-pattern>
      </filter-mapping>
      
      
    </web-app>
    

    注意:过滤器也是在web应用启动的时候被加载的,相当于servlet配置了一个load-on-startup属性一样。

    访问http://localhost:8080/struts2/helloworld.action,输出hello world即为成功。

    最后,最重要的事情是,程序的运转流程

    首先我们在地址栏键入http://localhost:8080/struts2/helloworld.action,请求访问helloworld.action这个资源,请求到达了Tomcat服务器端,于是Tomcat到web.xml中找到了filter-mapping,因为其url-pattern被我们设定为/*,于是所有的客户想要访问的所有资源都需要经它过滤,经filter-name找到相应的filter(web应用启动时便被加载了),这里就是我们的struts2,根据这个filter-name找到响应的filter-class:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,流程转到struts.xml中,首先找到相应的包:struts2,然后找相应的action:name属性为helloworld,与该名字所对应的是class:com.test.action.HelloWorld进行处理,流程转到HelloWorld类,执行其execute方法,返回值为success,之后流程又返回到struts.xml中的action,找到result中name属性为success的,于是流程转到helloworld.jsp,于是我们的hello world输出来了。

    此外一个,可能的疑惑是,一个客户请求对应一个request和response,作为doGet和doPost的两个参数,为什么我们整个过程中都没有看到过request和response对象呢,然而程序仍然能正常运转,但是,这只是表面上来看是这样的,底层它既然是基于HTTP协议的一个框架,肯定是有request和response,只不过struts2巧妙的把它们隐藏起来了,因此我们看不到他们。

    上面的程序是处理一个静态的页面,下面我们来一个复杂点的,涉及到动态的页面。下面我们就用struts2来实现一个简单的登录系统:

    首先新建一个login.jsp:

    <body>
      <form action="login.action">
        username: <input type="text" name="username" size="20"/><br>
        password: <input type="password" name="password" size="20"/><br/>
        
        <input type="submit" value="submit"> 
       </form>
      </body>
    

    然后,新建一个类,名为LoginAction(其中的username 和 password作为成员变量必须与表单中的一致,并且为其生成set和get注入方法):

    package com.test.action;
    
    public class LoginAction
    {
    	private String username;
    	
    	private String password;
    
    	public String getUsername()
    	{
    		return username;
    	}
    
    	public void setUsername(String username)
    	{
    		this.username = username;
    	}
    
    	public String getPassword()
    	{
    		return password;
    	}
    
    	public void setPassword(String password)
    	{
    		this.password = password;
    	}
    	
    	public String execute() throws Exception
    	{
    		return "success";
    	}
    }
    

    接下来,配置struts.xml,在原来的基础上增加一个名为login的action:

    <struts>
    		
    		<package name="struts2" extends="struts-default">
    		
    			<action name="helloworld" class="com.test.action.HelloWorld">
    				<result name="success">/helloworld.jsp</result>
    			</action>
    			
    			<action name="login" class="com.test.action.LoginAction">
    				<result name="success">/result.jsp</result>
    			</action>
    		</package>
    	
    </struts>
    

    最后,完成我们还缺少的一环,处理客户信息,新建一个result.jsp:

     <body>
        username: ${requestScope.username }<br/>
        password: ${requestScope.password }
      </body>
    

    重启Tomcat,访问:http://localhost:8080/struts2/login.jsp,输入zhangsan,12345,跳转到http://localhost:8080/struts2/login.action?username=zhangsan&password=12345,并且显示username和password信息,即为成功。这种Get提交方式不太安全,因此可以把表单的提交该为post方式。

    学习内容:

    • Struts2入门及基本配置
    • Struts2核心概念及原理
    • Struts2类型转换
    • Struts2输入校验
    • Struts2实现文件上传及下载
    • Struts2深入探索(源代码)
    • Struts2的拦截器(Intercepter)
    • Struts2的国际化(Internationalization)
    • Struts2标签库

    Struts2是什么?

      Struts2 = Struts + WebWork

    为何Struts2使用XWork?

      XWork是一个通用命令模式的框架,WebWork = WebWork Core + XWork,Struts2 = Struts 2 Core + XWork。Struts2把Web功能转换提供给XWork。

    XWork提供了什么?

      实现独立运行的命令模式框架:Action作为命令对象存在于XWork中

      增加了高级功能

        拦截器:包括设置表单参数,处理文件上传等

        结果(Result):包括多个Action之间的链接,转向表示层

        简单的IoC(或称DI,依赖注入)容器,可给Action对象注入值(Spring)

        强大的对象查询语言-OGNL

        自动类型转换

        元数据驱动的验证框架

        插件机制

    Struts Core提供了什么?

    • 封装HTTP请求/响应对象为Map
    • 处理Session/Application范围
    • ServletDispatcher转换HTTP请求执行Action
    • 提供了Web层的拦截器
    • 将Result转换为具体的redirect&dispatch,或者其它表示层

    系统架构:

    • 接收到请求
    • FilterDispatcher找到合适的Action
    • 拦截器调用
    • Action中的方法执行("核心"业务)
    • Result进行输出

    Action:

      Action是命令对象;Action应尽量简单;Action和任何Web对象无关;Action接口只有一个方法:

    public interface Action
    {
        public String execute() throws Exception;
    }
    

    需要注意的一点:Struts2下载包内不包含XWork源码,如有需要需从XWork网站下载。

    Struts2基本开发配置(完成Struts2 Hello Workd):

    • 启动MyEclipse
    • 创建Web Project
    • 添加必需的Struts2 jar文件
    • 向web.xml加入struts2过滤器
    • 创建Action类HelloWorldAction
    • 创建JSP表示层页面HelloWorld.jsp
    • 创建struts.xml并加入action定义
    • 运行测试

      执行流程为:action->FilterDispatcher->HelloWorldAction.execute()->"success"->struts.xml找到Result->显示HelloWorld.jsp

      看不到的过程-拦截器:设置表单参数;设置请求属性

    开发简单登录应用:

    • 编写表单页面login.jsp
    • 编写登录结果页面login_result.jsp
    • 编写Action类UserAction
    • 给struts.xml加入Action定义
    • 运行测试
    • 执行流程
    • 改进:登录失败返回输入页面

    Struts2和1的异同点

      不同点:FormBean被Action属性取代;ActionForWard被Result取代;Action类中不直接出现Servlet对象;引入了package的概念;引入了拦截器的概念;Struts2的开发大大简化

      相同点:都是MVC架构;均提供了控制器和流程跳转功能;监听特定的URL地址来实现功能.action;均提供了切换view层的功能;提供了类似的标签库:表单和逻辑;都支持国际化功能

    补充:package与action的关系,就好像Java中的包和类的关系一样,一个package可以包含多个action,Java中的包是有名字的,struts也是如此,这个名字是可以随意起的,此外,struts中的包还允许继承,如我们的struts.xml中,extends="struts-default",在MyEclipse中打开Struts2-core-2.1.6.jar,可以看到里面有一个struts-default.xml的文件, 可以看到他的包<package name="struts-default" abstract="true">,因此我们的struts.xml继承了这个名字为struts-default的包,具有了该包定义的所有功能,abstract为true表示该包为抽象包,不能直接用,我们自己写的struts就是一个具体的包。

    下面我们用struts标签库来写一个login2.jsp:

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="/struts-tags" prefix="s" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login2.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
       	<s:form action="login.action">
       		<s:textfield name="username" label="username"></s:textfield><br/>
       		<s:password name="password" label="password"></s:password>
       		<s:submit value="submit"></s:submit>
       	</s:form>
      </body>
    </html>
    

    注意<%@ taglib uri="/struts-tags" prefix="s" %>和body中的内容是我们自己添加的。此外我们可以按住Ctrl键,鼠标点击,跟进其源代码,在<s:textfield...这一行,跟进去发现一个8000多行的tld(struts-tags.tld)文件,其<uri>/struts-tags</uri>,此即我们的taglib的uri的来源。

    此外,还用注意的一点,标准的HTML表单默认提交方法是Get,而Struts2的表单默认的提交方式是Post。还有,表单中的.action可以省略,它是struts2默认的后缀名。

  • 相关阅读:
    ACL最大权限及相关命令
    ACL权限设置
    Linux权限管理--ACL权限简介
    Linux用户信息文件/etc/passwd
    本地光盘yum源的搭建
    响应式 和 移动 web
    svg
    vi 命令
    html 语法
    运营给的广告设计稿如何做
  • 原文地址:https://www.cnblogs.com/Code-Rush/p/4656233.html
Copyright © 2020-2023  润新知