Struts2自学笔记

【StrutsPrepareAndExecuteFilter类】
注:该类的init方法会读取类路径下的的struts.xml文件,并且独到struts.xml文件中的内容会以javabean的形式存放在内存中,以后struts2对用户的每次请求处理将使用内存中的数据,而不是每次都读取struts.xml文件

【struts2的处理流程】
struts2对于用户的每一次请求都会创建一个Action,所以struts2中的Action是线程安全的当用户发送请求时,核心控制器(web.xml中配置的过滤器)负责拦截由<url-pattern>/*<url-patter>指定的所有用户请求,它会过滤用户的请求。默认情况下,如果用户请求的路径不带后缀或者以.action结尾,这是请求将被转入struts2框架进行处理。当请求转入struts2框架处理时,会先经过一系列的拦截器,再到action

【action名称的搜索顺序】
Action的搜索会依据URL请求一级一级往前推,如果在当前目录中找不到,就会到上一级目录中去寻找,直到寻找到位置;如果找到包之后并没有action,struts2就会到默认的额命名空间下寻找action

【为Action的属性注入值(配置文件中)】
Struts.xml配置:
<action name="login3" class="struts2.helloworld.day01.LoginAction3">
<param name="imagePath">/image</param>
<result name="success">/WEB-INF/page/image.jsp</result>
</action>
Action类:
private String imagePath;
public String execute(){
return "success";
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public String getImagePath() {
return imagePath;

注入值需要使用setXXX方法,所以在Action类中必须有setXXX方法。
******param放在result之外,与重定向带参数区分开来******

【指定Struts2处理的请求后缀】
在struts.xml文件中配置:
<constant name="struts.action.extension" value="do"/>
多个值用逗号分隔开struts2加载常量的顺序:struts-default.xml→struts-plugin.xml→struts.xml→struts.properties→web.xml
其他常用的常量:
1)默认编码集
<constant name="struts.i18n.encoding" value="UTF-8">
2)设置浏览器是否缓存静态图片
<constant name="struts.server.static.browerCache" value="true">
3)配置文件后,系统是否自动使用
<constant name="struts.configuration.xmlreload" value="true">
4)更加详细的错误信息
<constant name="struts.devMode" value="true">
5)与spring集成时,指定创建action对象的工厂
<constant name="struts.objectFactory"value="spring">

【动态方法调用和通配符的使用】
struts2中有两种方式实现动态方法调用
1)/..../xxx!method.action(不推荐使用)可通过配置常量禁止使用此动态方法访问
2)使用通配符:
<action name="login_*" class="struts2.helloworld.day01.LoginAction3" method="{1}">
<result name="success">/WEB-INF/page/image.jsp</result>
</action>
其中{1}可以用在类名中,或者返回的路径中

【Action配置中各项的默认值】
1.没有为action指定class属性,默认是ActionSupport
2.没有为action指定method属性,默认执行action中的execute方法
3.如果没有指定result的name属性,默认值为success
4.如果没有指定返回result的type属性,默认值为dispatcher
【配置视图转发类型】
服务器内部转发时,才能访问web-inf里面的jsp页面;而重定向的请求无法访问web-info里面的jsp页面
1.重定向到URL
<result type="redirect">...</result>
当重定向访问某个页面需要带上参数时,需要使用${属性名}表达式访问action中的属性,
名称需和action中的属性相对应如:employAdd.jsp?username=${username}(URL形式)

注意:
1)如果传递的是中文,就先对中文进行URL编码(URLEncoder.encode("中国","UTF-8"));
2)重定向之后,上一次所有的请求数据将丢失
3)可以使用result中的param标签,带入参数,如下:
<action name="hello3"class="struts2.helloworld.day01.HelloWorldAction2">
<result type="redirect"> <param name="location">/index.jsp</param>
<param name="reportType">pie</param>
<param name="width">100</param>
<param name="height">100</param>
</result>
</action>
提交请求后,地址栏会自动生成如下链接:
http://localhost:8080/Struts2Demo/index.jsp?reportType=pie&width=100&height=100

2.重定向到Action
<result type="redirectAction">xxx.action</result>与redirect不同的是,这中类型的重定向是指向action而非URL的
注意:
1)重定向请求数据全部丢失
2)可以使用result中的param标签,带入参数,如下:
<result name="showReportResult" type="redirectAction">
         <param name="actionName">generateReport</param>
         <param name="reportType">pie</param>
         <param name="width">100</param>
         <param name="height">100</param>
         <param name="empty"></param>
         <param name="suppressEmptyParameters">true</param>
      </result>
****最后一个参数,指示是否在浏览器的地址栏显示参数值为空的参数,默认值为false
提交请求后,地址栏自动生成如下链接:
http://localhost:8080/Struts2Demo/package1/login.action?reportType=pie&width=100&height=100&suppressEmptyParameters=true

3.plainText类型
以源码的形式显示返回内容
<action name="login2">
<result type="plainText">
<param name="location">/list.jsp</param>
<param name="charSet">ISO-8859-1</param>
</result>
</action>

【请求参数的接收】
Struts2底层会通过反射技术为响应的属性或者复合属性赋值
1.普通类型的参数(属性驱动)
页面输入值的属性名称和action类中属性名称一致(setXXX()方法的xxx),这样struts2能够自动为属性赋值

2.符合类型的参数(模型驱动)
如果属性多了,那么可以用模型驱动的方式,使用实体类的方式封装好各个属性,在action类中只需要传递一个实体类就可以了
ActionClass{
private User user;

public void setUser(User user){
this.user=user;
}
}
而在页面只需要把各个输入值的名称与user的各个属性相匹配即可
①<input type="text" name="userName"/>
②<input type="text" name="user.userName"/>(看上去更加清晰明了)

【类型转换器】
当用户提交的请求,里面的参数都是以String的形式传递给struts2的action的,为了避免在赋值的时候出现类型不匹配的情况,就需要进行类型转换,struts2有内置的类型转换器,用户也可以写自己的类型转换器,如果不继承struts2提供的类型转换器,那么用户需要通过request获取到用户提交的参数,进行类型转换。
1.局部类型转换器
针对特定action中的特定属性进行类型转换
1)建立ActionName-conversion.properties这个名称格式类型的Properties文件,文件内容为:
属性名=类型转换器类名(完整类名)
2)编写转换类,继承DefaultTypeConverter,重写convertValue(Map context,Object value,Class toType)方法
2.全局类型转换器
为某种类型的变量配置类型转换器
1)建立xwork-conversion.properties文件,放在src目录下,文件内容为:
完整类名=类型转换器类名(完整类名)
2)2)编写转换类,继承DefaultTypeConverter,重写convertValue(Map context,Object value,Class toType)方法

注:
(1)当struts2拦截到用户发出的请求,通过参数拦截器,获取到用户提交的参数,然后先进行类型转换,如果类型转换失败则会被struts2提供的一个conversionError这个拦截器所拦截,并且将错误记录actionFieldError中,这样再执行execute()方法时,就会直接进入Input视图。
(2)在自定义类型转换器时,可以继承DefaultTypeConverter的子类StrutsTypeConverter,这个抽象类中提供了两个方法:
convertFromString(...):将字符串类型转换为复合类型
convertToString(...):将复合类型转换成字符串类型

【Struts2中访问或添加request/session/appliaction的属性】
Struts2中避免直接访问servlet api,底层对它们进行了封装。可以通过ActionContext类进

行访问,获得Map集合
方式一:
/**
* 以map的形式访问和设置request,response,application中的值
* @return
*/
public String res(){

ActionContext act = ActionContext.getContext();
act.getApplication().put("app", "application scope");//往

application级别设置attribute
act.getSession().put("ses", "session scope");//往session级别设置

attribute
act.put("req", "request scope");//往request级别设置attribute
return "success";
}

/**
* 以servlet API的形式访问和设置request,response,application中的值
* @return
*/
public String res1(){
//用Struts2提供的ServletActionContext获取request对象
HttpServletRequest request = ServletActionContext.getRequest();
//servletcontext相当于application
ServletContext sc = ServletActionContext.getServletContext();
sc.setAttribute("app1", "app1 scope");//相当于往application中设置

attribute
request.getSession().setAttribute("sess1", "sess1 scope");
request.setAttribute("req1", "req1 scope");
return "success";
}
方式二:实现接口,由struts2运行时注入


【输入校验】
1.重写validate方法
1)validate()方法实现全部方法的校验
2)validateXxx()方法实现某个方法的校验

2.基于XML配置方式实现
1)基于xml实现对全部的方法的校验
ActionClass-validation.xml

2)基于xml实现对某个方法的校验
ActionClass-actionname-validation.xml(actionname为struts.xml中配置的action名称)
在xml配置的校验器中,又分为字段校验器和非字段校验器:
字段校验器:
<field name="xxx">
<field-validator type="xxxx">
<param>...</param>
</field-validator>
</field>
非字段校验器:
<validators>
<validator type="xx">
<param>...</param>
</validator>
</validators>

3.客户端校验
<s:form action="xxx" validate="true">..</form>
通过查看源文件发现,struts2框架会自动生成校验的javascript代码

4.输入校验流程
1)类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性
2)如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息封装到fieldErrors里,不管类型转换是否出现异常,都会进入第3步
3)系统通过反射技术先调用action中的validateXxx()方法
4)再调用action中的validate()发那个发
5)经过上面的4步,如果系统中的fieldErrors存在错误性信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为Input的视图。如果系统中fieldErrors没有任何错误信息,系统将执行action中的处理方法。

【拦截器(实例)】
Struts2的拦截器也是也是依靠动态代理技术实现的,与Spring的AOP有异曲同工的效果
1.拦截器
public class HelloInterceptor1 implements Interceptor {

@Override
public void destroy() {}
@Override
public void init() {}

@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object user = ActionContext.getContext().getSession().get("user");
if(null!=user){//如果登录则执行action中的方法
return invocation.invoke();//本质是执行了action中的方法,

返回值给了代理对象
}else {
ActionContext.getContext().getSession().put("message", "no

permission");
return "message";
}
//return "success";
}

}
2.action类
public class HelloWorldAction7 {

private String message;

public String execute() {
message = "execute";
return "success";
}

public String addUser() {
message = "addUser";
return "success";
}

public void setMessage(String message) {
this.message = message;
}

public String getMessage() {
return message;
}
}
3.struts.xml配置文件
<package name="day03" namespace="/package4" extends="struts-default">
<interceptors>
<interceptor name="permisionInterceptor"
class="struts2.helloworld.day03.HelloInterceptor1"></interceptor>
<interceptor-stack name="permisionStack">
<!--当为一个action显式指定了拦截器,如果不加入默认的拦截器栈,action将会失去struts2中自带的拦截器功能-->
<interceptor-ref
name="defaultStack"></interceptor-ref>
<interceptor-ref
name="permisionInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="login_*" class="struts2.helloworld.day03.HelloWorldAction7" method="{1}">
<result name="success">/WEB-INF/day03/success.jsp</result>
<result name="message">/WEB-INF/day03/message.jsp</result>
<interceptor-ref name="permisionStack"></interceptor-ref>
</action>
</package>

4.页面
1)login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
request.getSession().setAttribute("user","logined");
%>
2)quit.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
request.getSession().removeAttribute("user");
%>
3)success.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Basic Struts 2 Application - Welcome</title>
</head>
<body>
${message }
</body>
</html>

猜你喜欢

转载自changluo.iteye.com/blog/1824967
今日推荐