Struts2笔记

来源:互联网 发布:英雄连2 单位数据 编辑:程序博客网 时间:2024/05/21 10:47

这里写图片描述

1Structs2

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

2MVC模式过程

JSP + JavaBean = Model1JSp + Servlet + JavaBean = Model2(典型的MVC)

这里写图片描述

这里写图片描述

3Jar 包下载

http://struts.apache.org/download.cgi#struts255

4配置Structs核心文件

web.xml,只要和web应用整合,就要运用到这个文件

JSP+servlet+javaBean 就需要把servlet在web.xml中配置,当然,你也可以用注解的方式声明

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  <display-name>structs-timer</display-name>  <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>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

这里写图片描述


这里写图片描述
这里写图片描述

struts.xml

The content of element type “package” must match “(result-types?,interceptors?,default-
interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-
mappings?,action*)”.配置的节点有先后顺序

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd">    <!--引入其他配置文件,可以把每个功能模块独立到一个xml配置文件中-->    <include file="structs-User.xml"></include>    <constant name="struts.enable.DynamicMethodInvocation" value="false" />    <constant name="struts.devMode" value="true" />     <!-- name Package的表示,为了让其他的package引用,继承 -->    <package name="default" namespace="/" extends="struts-default">    <!--包的命名空间,对应路径,/test,则action都在 localhost:8080/projectname/test/xx.action,可包含多个action -->    <action name="action名称" class="类的路径com.peng.action.TimerAction">            <!-- 默认成功 -->            <result>/success.jsp</result>        </action>    </package></struts>

配置 action 之后,可以通过路径后加入路径访问

http://localhost:8080/structs-timer/timer.action
http://localhost:8080/structs-timer/timer

其他的一些配置

    <!--常量值-->    <constant name="struts.devMode" value="true" />     <constant name="struts.action.extension" value="action" /><package name="default" namespace="/" extends="struts-default">        <!-- 注册拦截器 -->        <interceptors>            <interceptor name="mytimer"             class="com.peng.interceptor.TimerInterceptor"></interceptor>        </interceptors>        <!-- 全局 result 配置 -->           <global-results>            <result name="inplut">/error.jsp</result>            <result name="error">/error.jsp</result>        </global-results>        <action name="timer" class="com.peng.action.TimerAction">            <!-- 默认成功 -->            <result>/success.jsp</result>            <!-- 为Action显式引用拦截器后,默认的拦截器defaultStack不再生效,需要手工引用 -->            <interceptor-ref name="defaultStack"></interceptor-ref>            <!-- 引用拦截器 -->            <interceptor-ref name="mytimer"></interceptor-ref>            <!-- 参数设置,对应action中的get/set方法 -->            <param name="url">http:www.qq.com</param>        </action>    </package>

常量值

 <!-- 指定全局国际化资源文件mess。mess.properties在src目录下 -->    <constant name="struts.custom.i18n.resources" value="mess"/>    <!-- 指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出-->    <constant name="struts.i18n.encoding" value="UTF-8"/>    <!-- 自定义后缀修改常量,*.do,*.action都会被识别。无后缀不能被识别-->    <constant name="struts.action.extension" value="do,go"/>    <!-- 如果想将无后缀也识别,请在上处常量设置value="do,go," --    <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭-->     <constant name="struts.serve.static.browserCache" value="false"/>    <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 -->    <constant name="struts.configuration.xml.reload" value="true"/>    <!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->    <constant name="struts.devMode" value="true" />    <!-- 默认的视图主题 -->    <constant name="struts.ui.theme" value="simple" />    <!-- 与spring集成时,指定由spring负责action对象的创建 -->    <constant name="struts.objectFactory" value="spring" />   <!--  该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性    为 false-->    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>    <!-- 上传文件的40M大小限制-->    <constant name="struts.multipart.maxSize" value="41943040"/>

这里写图片描述

这里写图片描述

5Structs的过滤器

在 web.xml 中配置的

 <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项目启动的时候,过滤器就生效

这里写图片描述
2.1.3版本后
这里写图片描述
StrutsPrepareAndExecuteFilter,可以在执行action之前,添加自己的过滤器

6回顾在页面中访问Servlet

TestServlet.java

//package com.peng.servlet;import java.io.IOException;import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@SuppressWarnings("serial")@WebServlet("/pppp")//注解的方式public class TestServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("成功了到达action....pppp ");        RequestDispatcher rd = req.getRequestDispatcher("mypage.jsp");//跳转到mypage.jsp        rd.forward(req, resp);    }   }

另一种方式:注册servlet的方式

    <servlet>        <servlet-name>TestServlet</servlet-name>        <servlet-class>com.peng.servlet.TestServlet</servlet-class>    </servlet>    <!-- servlet映射 -->    <servlet-mapping>        <servlet-name>TestServlet</servlet-name>        <url-pattern>/pppp</url-pattern>    </servlet-mapping>

通过下面的路径访问

http://localhost:8080/ServletTest/pppp

7在Structs中访问 servlet

Structs本来就是servlet的升级产品,控制Action的使用本来就是Structs的功能,因为Structs的拦截,直接访问servlet是不能成功的

解决方式

一.修改web.xml 文件配置
原来是

 <url-pattern>/*</url-pattern>

修改为

 <url-pattern>*.action</url-pattern>

即不对action进行拦截
方法二
在struts.xml中的的节点下面添加struts2处理的请求后缀 常量:

<!--  该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。  --> <constant name="struts.action.extension" value="action" />

这样的话,每个 action 都必须加后缀 xxx.action,才能正常访问,当然你也可以设置其他的后缀,servlet也可以正常访问了

http://localhost:8080/structs-timer/TestServlet
http://localhost:8080/structs-timer/timer.action
http://localhost:8080/structs-timer/timer.action 不能访问

更多方法:http://blog.sina.com.cn/s/blog_7ffb8dd50101aw8l.html

8 Action的搜索顺序

这里写图片描述

如果这个路径可以

http://localhost:8080/struts2/helloworld.action

http://localhost:8080/struts2/aaa/bbb/helloworld.action

也可以

9 动态方法调用

动态方法调用就是为了解决一个Action对应多个请求的处理时Action太多

一个Action就一个execute()方法,一个模块写一个action,action只有一个默认的execute()方法,那action多的不是上天了吗

三种方式解决

1.指定method属性
2.感叹号方式
3.通配符方式

1.指定method属性

建立一个action包,存放action,src下存放structs.xml.在WebContent下建立相应的jsp文件

action中加入了两个方法 add ,update,都返回SUCCESS

HelloWorldAction.java

//package com.struts2.action;import com.opensymphony.xwork2.ActionSupport;public class HelloWorldAction extends ActionSupport {    public String add(){        return SUCCESS;    }    public String update(){        return SUCCESS;    }    @Override    public String execute() throws Exception {        System.out.println("执行Actoin");        return SUCCESS;    }}

structs.xml文件中做相应的更改

..        <action name="helloworld"  class="com.struts2.action.HelloWorldAction">            <result >/result.jsp</result>               </action>        <action name="addAction" method="add" class="com.struts2.action.HelloWorldAction">            <result >/add.jsp</result>        </action>        <action name="updateAction" method="update" class="com.struts2.action.HelloWorldAction">            <result >/update.jsp</result>        </action>   ..
http://localhost:8080/Struts2_Test/addAction 访问的是add.jsphttp://localhost:8080/Struts2_Test/updateAction 访问的是update.jsp

方法多的时候,也不方便啊,不推荐使用,看其他的

2感叹号方式

首先在structs.xml中开启一个常量

    <!-- 动态调用方法 --> <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> 

更改struct.xml文件的action

     <action name="helloworld_*" method="{1}" class="com.struts2.action.HelloWorldAction">            <result >/result.jsp</result>            <result name="add">/add.jsp</result>            <result name="update">/update.jsp</result>        </action>

更改HelloWorldAction ,注意方法的return值要相应改变

public class HelloWorldAction extends ActionSupport {    public String add(){        return "add";    }    public String update(){        return "update";    }    @Override    public String execute() throws Exception {        System.out.println("执行Actoin");        return SUCCESS;    }}
http://localhost:8080/Struts2_Test/helloworld.action 访问的是result.jsphttp://localhost:8080/Struts2_Test/helloworld!add.action 访问的是add.jsphttp://localhost:8080/Struts2_Test/helloworld!update.action 访问的是update.jsp

官方不推荐使用

3通配符方式

关闭感叹号的方式,设为 false

<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant> 

统配符的方式

<action name="helloworld_*" method="{1}" class="com.struts2.action.HelloWorldAction">            <result >/result.jsp</result>            <result name="add">/{1}.jsp</result>            <result name="update">/{1}.jsp</result>        </action>
public class HelloWorldAction extends ActionSupport {    public String add(){        return "add";    }    public String update(){        return "update";    }    @Override    public String execute() throws Exception {        System.out.println("执行Actoin");        return SUCCESS;    }}
http://localhost:8080/Struts2_Test/helloworld.action 访问的是result.jsphttp://localhost:8080/Struts2_Test/helloworld_add.action 访问的是add.jsp

当然action也可匹配多个

<action name="*_*" method="{2}" class="com.struts2.action.{1}Action">            <result >/result.jsp</result>            <result name="add">/{2}.jsp</result>            <result name="update">/{2}.jsp</result>        </action>
http://localhost:8080/Struts2_Test/HelloWorld_add.action 访问的是add.jsp

大写的HelloWorld,因为是类的路径啊

11默认Action

..    <default-action-ref name="index"></default-action-ref>        <action name="index">            <result>/error.jsp</result>        </action>

12Structs后缀

<!-- 不加后缀,不用加后缀就能访问,加了,就一定要后缀,因为默认为action啊 -->     <constant name="struts.action.extension" value="html"></constant> 

13处理结果类型

这里写图片描述

return 类型

这里写图片描述

1返回input的示例

配置Action

<action name="LoginAction" method="login" class="com.struts2.action.LoginAction">            <result >/success.jsp</result>            <result name="input">/login.jsp</result></action> 

有类型转换等错误时(表单验证不正确),返回input,在登录界面登录时,还是会返回登录界面

User.java

//package com.struts2.po;import java.util.List;public class User {    private String username;    private String password;    private int age;    private List<User> bookList;    //getter and setter}
<form action="LoginAction.action" method="post">        用户名:<input type="text" name="username"><%-- <s:fielderror name="username"></s:fielderror>  --%><br>        书籍1:<input type="text" name="bookList[0].username"><br>        书籍2:<input type="text" name="bookList[1].username"><br>        密码:<input type="password" name="password"><br>        年龄:<input type="text" name="age"><br>        <input type="submit" value="提交"/>    </form>

LoginAction.jsp

//package com.struts2.action;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;import com.struts2.po.User;public class LoginAction extends ActionSupport implements ModelDriven<User>{    private User user = new  User();    public String login(){    System.out.println(user.getUsername());        System.out.println(user.getBookList().get(0).getUsername());        System.out.println(user.getBookList().get(1).getUsername());        return SUCCESS;    }    @Override    public User getModel() {        return user;    }   }

这里写图片描述

即使没有在 LoginAction 中,显式的声明格式类型错误,structs自动检测

显式声明校验条件
LoginAction.jsp

package com.struts2.action;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;import com.struts2.po.User;public class LoginAction extends ActionSupport implements ModelDriven<User>{    private User user = new  User();    public String login(){        if(user.getUsername()==null                ||"".equals(user.getUsername())){            this.addFieldError("username", "用户名为空");            return INPUT;        }        System.out.println(user.getUsername());        System.out.println(user.getBookList().get(0).getUsername());        System.out.println(user.getBookList().get(1).getUsername());        return SUCCESS;    }    @Override    public User getModel() {        return user;    }   }

运用structs的<s:fielderror ></s:fielderror>标签显示全部错误信息
想显示特定指定的错误信息,如上文的this.addFieldError("username", "用户名为空");则可以用

<s:fielderror fieldName="username"/><s:fielderror>    <s:param>username</s:param> <!--显示指定的 username字段的 错误消息-->  <s:fielderror/> 
 <%@ taglib prefix="s" uri="/struts-tags"%> ...<form action="LoginAction.action" method="post">        用户名:<input type="text" name="username"> <s:fielderror ></s:fielderror><br>        书籍1:<input type="text" name="bookList[0].username"><br>        书籍2:<input type="text" name="bookList[1].username"><br>        密码:<input type="password" name="password"><br>        年龄:<input type="text" name="age"><br>        <input type="submit" value="提交"/>    </form>

运行结果:
这里写图片描述

首先是类型检查,之后才是自己声明的校验

2全局结果和局部结果

有很多时候一个< result>可供很多< action>使用,这时可以使用< global-results>标签来定义全局的< result>

<package name=".." namespace="/" extends="struts-default">     <global-results>      <result name="mainpage">/main.jsp</result>     </global-results> </package>

3处理结果的type类型

<result name="success" type="">/success.jsp</result>

默认为 dispatcher 支持 JSP 技术

<package name="struts-default" abstract="true">        <result-types>            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />            <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />        </result-types> </package>

默认 dispatcher 跳转的方式请求不变–>可以去WEB-INF下面的页面
redirect 重定向—>请求发生了改变,不能去WEB-INF下面的页面
redirectAction 跳转到另一个Action下
plainText 查看原文

<action name="source">            <result type="plainText">                <param name="charSet">utf-8</param>                <param name="location">/login.jsp</param>            </result></action>
0 0
原创粉丝点击