标签:
struts2学习笔记
1.用户登录案例
1. 新建web项目
2. 2.导入struts2的jar包
3. 配置web.xml配置struts2的核心过滤器
<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>*.action</url-pattern> </filter-mapping> |
4. 在src编写struts.xml
Jar包struts2-core-2.3.4.jar中Struts-default.xml复制前段即可
5. 编辑login.jsp
<form action="login.action" method="post" > 用户名:<input type="text" name="username"/><br> 密 码:<input type="password" name="password"/><br> <input type="submit" value="登录"/> </form> |
注:action的提交地址.action是扩展名,默认为.action;action的扩展名和web.xml中配置的struts2的核心过滤器匹配;也就是如果表单中提交的地址以.aciton结尾,那么在配置filter的url-pattern时一定是:
6. 编写loginAction类
package com.struts2Test.pj;
public class loginAction {
public String username; public String password;
public String execute(){ if("lipeng".equals(username)||"123".equals(password)){ return "success"; }else{ return "failed"; } } 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; } }
|
注:action表单中的属性名要和action中的一致(username/password jsp和action中要一致)
Struts2中会自动将表单中提交的数据设置到loginAction的对应属性上,并且可在jsp中直接获取,不用手动像request设置。
7. 在Struts.xml中配置loginAction
<action name="login" class="com.struts2Test.pj.loginAction"> <result name="success">/success.jsp</result> <result name="failed">/login.jsp</result> </action> |
8. 访问测试:
|
执行流程
2.线程安全
1. 线程安全:在一个进程中有多个线程并发执行,每个线程执行过程中变量值是相同的,执行结果也是相同的。
2. Struts线程安全吗?(线程安全好吗?好,并发的时候不会出问题,就是效率低)
每次请求都会重新创建新的Action对象,所以线程安全
由于action对象是struts2 反射生成的,所以要求action类要有一个公共的无参数的构造方法。
3.Struts.xml配置详解
常量配置方式一:
1. 解决乱码
<constant name="struts.i18n.encoding" value="UTF-8"/> |
注:和constant和package同级别
2. 自定义扩展名
<!--extends必须写,直接或者间接继承struts-default, name自定义 --> <!-- 一个pagckage下面可有多个action --> <package name="login" namespace="/" extends="struts-default"> |
注:namespace可为空,加上之后访问时候需带上namespace属性值(namespace/action)
3. 友好的提示信息
<constant name="struts.devMode" value="true"></constant><!-- 友好的提示信息 --> |
常量配置方式二:在src下添加struts.properties,在里面设置值
4 .团队协作配置
<!-- 团队协作配置 --> <include file="config/struts2Test/strutsxml/login.xml"></include> |
5.struts.xml 的加载顺序
struts-default.xml ——struts-plugin.xml —— struts.xml
6.Package的配置
|
7.Action的配置
<!-- name是action请求不需要加.action class 处理action请求对应的java类,class要求包名+类名,并且该类是有公共的无参构造方法的。 method:配置处理请求的方法,默认为execute;方法要满足公共的,返回值类型是String无参 action中的method和action中的name无关 --> |
8.Result的配置
result指结果集; name:请求的处理方法的返回值,默认是success 【<result name="success">/success.jsp</result>】 type:结果的处理类型(请求,转发);默认是dispather转发 【<result name="success" type="dispather">/success.jsp</result>】 chain:指action链,链接下一个action 【<result name="success" type="chain">logout</result>】 dispather:转发,如果有数据需要带到前台渲染只能用转发 redirect:重定向,也可以重定向一个action; 如果是重定向到jsp页面可以直接重定向; 如果是重定向到另一个action,需注意是否配置了action的后缀名,如果有要求有后缀名那么重定向的action一定要加上后缀名称 redirectAction:重定向到另一个action,不用加action的后缀名 |
9. 全局配置
<!-- 配置全局结果集 --> <global-results> <result name="failed">/login.jsp</result> </global-results> |
在action的配置中,如果不去配置class属性,将会由默认的action来执行,默认的action是ActionSupport类
10.Action的实现方式
1.定义一个pojo类:好处自定义一个普通的java类,不具有侵入型
public class HelloAction { public String execute(){ System.out.println("hello struts2"); return "success"; } } |
2. 实现一个Action接口,使得编写的代码更加规范
public class interfaceAction implements Action{ @Override public String execute() throws Exception { System.out.println("implements Action ..."); // return "success"; return Action.SUCCESS; } } |
3. 继承 ActionSupport类
好处:可以集成一些ActionSupport实现功能,如:验证;官方推荐使用
public class extendAction extends ActionSupport{ @Override public String execute() throws Exception { System.out.println("extends ActionSupport..."); return super.execute(); } } |
11.以对象的方式处理数据(属性驱动)
Jsp <form action="register.action" method="post" > 用户名:<input type="text" name="user.username"/><br> 密 码:<input type="password" name="user.password"/><br> age:<input type="text" name="user.age"/><br> email:<input type="text" name="user.email"/><br> <input type="submit" value="提交"/> </form>
Xml <action name="register" class="com.struts2Test.pj.registerAction"> <result name="success">/show.jsp</result> </action>
Action
public class registerAction extends ActionSupport{ public User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; }
@Override public String execute() throws Exception { System.out.println("registerAction..."); System.out.println(user); return Action.SUCCESS; } } 注:前端可直接获取对象 ${user} 跟对象名称一致即可 |
12.模型驱动(ModelDriver)
建议在实体属性比较多时,采用模型驱动
Jsp <form action="regmodel.action" method="post" > 用户名:<input type="text" name="username"/><br> 密 码:<input type="password" name="password"/><br> age: <input type="text" name="age"/><br> email:<input type="text" name="email"/><br> <input type="submit" value="提交"/> </form> |
Struts.xml <action name="regmodel" class="com.struts2Test.pj.modelDriverAction" method="register"><!—注意这里指定了方法--> <result name="success">/show.jsp</result> </action> |
modelDeiverAction
public class modelDriverAction implements ModelDriven<User>{ private User user = new User();// 这里必须要new一个对象
/**这里必须get set对象才可在前端拿到值**/ public User getUser() { return user; } public void setUser(User user) { this.user = user; }
public String register(){ System.out.println(user); return Action.SUCCESS; }
@Override public User getModel() { // TODO Auto-generated method stub return user; } } |
13.获取serletAPI
1.struts2有2种方式获取servletAPI:一种是解耦,一种是耦合;解耦使得struts2来进行测试的时候不需要启动服务器。在一定程序上是提高了开发效率
2.使用解耦的方式来获取servletAPI通过ActionContext对象获取。
ActionContext.getContext().getSession().put("User", username); |
3.通过ActionContext对象直接获取ServletHttpRequest
14.ActionContext
Struts1的Action必须依赖于web容器,他的execute方法自动获得HttpServletRequest、HttpServletResponse对象,从而可以跟web容器进行交互
Struts2的Action不用依赖于web容器,本身就是一个普通的java类而已。但是,在web开发中我们往往需要获得request、session、application等对象。这个时候可以通过ActionContext来处理。
ActionContext正如其名,是Action执行的上下文,他内部有个map属性,存放了Action执行时需要用到的对象。
在每次执行Action之前都会创建新的ActionContext对象,所以ActionContext是线程安全的。新New的ActionContext是保存在一个ThreadLocal变量中,即采用ThreadLocal模式。ThreadLocal变量为每个线程提供独立的变量值的副本,是每个线程都可以采用独立的使用自己的副本,而不会和其他线程发生冲突。
通过ActionContext获取到Session、request、application并不是真正的HttpServletRequest、
HttpServletResponse、ServletContext对象,而是将这三个对象里面的值重新包装成了map对象。这样的封装,我们及获取了我们需要的值,同时避免了跟web容器直接打交道,实现了完全的解耦。
1.What is ActionContext?
ActionContext是map结构的容器。ActionContext是Action的上下文,存放Action执行过程中数据信息。ActionContext存放Action的数据,ActionInvocation.request的数据,session的数据,application的数据,local的数据等。每次请求时会为当前线程创建一个新的ActionContext。而ActionContext采用了ThreadLocal的方式来存放ActionContext所以ActionContext是线程安全的。
2..获取ActionContext
ActionContext.getContext()获取。由于ActionContext是线程安全的,并且是通过静态方法获取的,所以在本线程中的非Action类中,也可以直接访问。
注意点:ActionContext是基于请求创建的,所以在非请求的线程中是不能使用ActionContext对象的。如:filter的init()方法。
4. ActionContext的简图
15.OGNL
1.使用ognl
Map<String, Object> map = new HashMap<String ,Object>(); map.put("name", "李四"); map.put("age", "22"); student stu = new student(); stu.setName("li"); Object obj = Ognl.getValue("#name",map, stu); System.out.println(obj); |
Struts2中使用ognl表达式是通过struts2的标签来取值的,
在jsp中导入struts2标签库
<%@ taglib prefix="s" uri="/struts-tags" %> |
注意:要使用struts2的标签,那么要通过struts2过滤器来启用,如果过滤器的配置为*.action结尾时,不能直接访问jsp页面的,需要通过action跳转。如果过滤器配置为*时,可以直接访问jsp页面。
Struts2推荐不直接访问jsp页面,推荐使用action来控制
16.类型转换
1.在servlet中,如果表单提交非字符串的时候,需要进行类型转换:如,年龄…
String strAge = req.getParameter(“age”); Int age = 0; If(strAge!=null){ Age = Integer.parseInt(strAge); } |
2.在struts2中,常见的数据类型struts2已经自动的进行了类型转换。无需手动转换。
3.在某些情况下,有自定义的类型时,struts2不能完成类型转换,那么需要手动转换,如果该自定义类型使用的频率较高时,手动转换重复代码将会增多——使用struts2提供的类型转换器来进行类型转换。
4. 案例:比如坐标点
5. 使用类型转换步骤:
a) 编写类型转换器——继承strutsTypeConverter类
b) 编写xwork-conversion.propertites的配置文件,放于src下;内容为要转换的类型=类型转换器
6.
17. validate()服务端验证
1. <action name="register" class="com.struts2Test.pj.registerAction"> 2. <result name="success">/show.jsp</result> 3. <result name="input">/register.jsp</result> 4. <!-- INPUT:Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果验证没有通过,将自动返回到该视图。 --> 5. </action>
|
1. package com.struts2Test.pj; 2. 3. import com.opensymphony.xwork2.Action; 4. import com.opensymphony.xwork2.ActionSupport; 5. import com.struts2Test.beans.User; 6. 7. public class registerAction extends ActionSupport{ 8. 9. public User user; 10. 11. public User getUser() { 12. return user; 13. } 14. 15. public void setUser(User user) { 16. this.user = user; 17. } 18. 19. @Override 20. public String execute() throws Exception { 21. System.out.println("registerAction..."); 22. System.out.println(user); 23. return Action.SUCCESS; 24. } 25. 26. /** 27. * 服务端验证,如果action类继承了ActionSupport类, 28. * 那么该action类将会继承ActionSupport的相关功能: 29. * 如,验证功能 30. * 执行流程是validate——>execute 31. */ 32. @Override 33. public void validate() { 34. //retuslt 35. if(user.age>100||user.age<1){ 36. this.addActionError("年龄不合法"); 37. } 38. super.validate(); 39. } 40. }
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ 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=UTF-8"> <title>注册</title> </head> <body> <s:actionerror cssErrorStyle="errorMessage"/><!-- 此标签用于显示错误信息 --> <form action="register.action" method="post" > 用户名:<input type="text" name="user.username"/><br> 密 码:<input type="password" name="user.password"/><br> 年 龄:<input type="text" name="user.age"/><br> 邮 箱:<input type="text" name="user.email"/><br> <input type="submit" value="提交"/> </form> </body> </html> |
18.拦截器
1.在action前后执行的代码。Struts2的核心功能都是通过拦截器来实现。
2.拦截器栈:由多个拦截器组成
3.作用:对于action的一些公关处理代码可以放到拦截器中实现。比如:权限控制,日志等等
4.多个拦截器直接按的执行是采用责任链设计模式实现
5.拦截器执行流程
6. 拦截器的实现步骤:
a) 编写拦截器(实现interceptor接口或者继承AbstractInterceptor类)
b) 在struts.xml中配置拦截器
c) 在action中引用拦截器
标签:
原文地址:http://blog.csdn.net/lp1052843207/article/details/51992476