1.拷贝jar包
2.在web.xml中配置Struts2的前端控制器StrutsPrepreAndExecuteFilter
<?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_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 配置Struts2的前端控制器 --> <filter> <filter-name>action2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>action2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> 3.提供一个Pojo类(Action类),提供一个公共无参数的execute方法 public class HelloAction(){ public String sayHello(){ System.out.println("你好,师姐"); return "success"; } }
4.新建一个源目录resources,拷贝struts.xml文件在此,配置HelloAction
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="helloPkg" extends="struts-default" namespace="crm"> <action name="hello" class=" org.wjw.struts.hello.HelloAction" method="sayHello"> <result name="success" type="dispatcher" >WEB-INF/views/hello/hello.jsp</ressult> </action> </package> </struts>
5.部署项目,访问Action
协议 + 主机地址 + 端口号 + 上下文路径 + 命名空间 + 资源名称+[.action]
二、常量配置
<constant name="struts.devMode" value="true" /> <constant name="struts.action.extension" value="action,do,," />
常见的常量配置
--------------------------------------
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出 <constant name="struts.i18n.encoding" value="UTF-8"/> 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 <constant name="struts.action.extension" value="action"/> 设置浏览器是否缓存静态内容,默认值为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" />:修改struts.xml之后,不要重启Tomcat. 默认的视图主题 <constant name="struts.ui.theme" value="simple" /> 是否支持动态方法调用 <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
三、配置中的三个元素
1.package元素
常见属性:
name,extends,namespace,abstract
2.action元素
常见属性:
name,class,method
3.result元素
常见属性:
name(默认为success,input)
type(默认为dispatcher)
常见的属性: name:Action方法返回的逻辑视图名称. 缺省值:success type:结果的跳转类型.该类型的值在struts-default.xml中已经预定义好了. 缺省值:dispatcher 常见的type值(结果类型): dispatcher: 表示从Action请求转发到页面(JSP). redirect: 表示从Action重定向到页面(JSP). chain: 表示从Action请求转发到另一个Action. redirectAction: 表示从Action重定向到另一个Action. stream: 表示返回流. 文件下载时使用. <param name="">表示参数:name缺省值:location(地址)
四、Action类的编写方式
定义一个类,继承于com.opensymphony.xwork2.ActionSupport类
五、Action多方法的调用
<allowed-methods></allowed-methods>
Action中多个Action方法会造成<action>配置的臃肿. 解决方案: 方案1: DMI:动态方法调用 :官方不推荐. 格式: action名!方法名 比如: emp!edit emp!list 在Struts2新的版本中,默认的关闭了DMI.若我们需要使用DMI,就需要配置常量,启用动态方法调用. 此时:<action/>元素不需要指定method属性值. <constant name="struts.enable.DynamicMethodInvocation" value="true"/> --------------------------------------------------------------------------------- 方案2: 使用通配符的方式类配置: 通配符:* <action name="emp_*" class="org.fkjava.struts.manymethod.EmployeeAction" method="{1}"> Action的名字: emp_Action方法: 比如:emp_list,那么{1}的值就是list emp_edit,那么{1}的值就是edit 两个通配符: <action name="*_*" class="org.fkjava.struts.manymethod.{1}Action" method="{2}"> Action名字:Action类名_Action方法. 比如:Employee_list,表示调用的EmployeeAction中的list方法 比如:Department_edit,表示调用DepartmentAction中的edit方法.
六、Action访问servletapi的三种方式
1.Action类实现感知接口 2.通过ServletActionContext工具类(共享数据还是setAttribute) 三个方法: getRequest(); getResponse(); getServletContext(); 3.通过ActionContext工具类(Map来表示,共享数据put,获取数据get) 什么是ActionContext: Action的环境对象,每一次请求都是一个新的Action对象, 一个ActionContext对象封装了这一次请求的相关数据. ActionContext使用了ThreadLocal模式,所以说是线程安全的. 获取request对象: ActionContext.getContext(); 获取session对象 ActionContext.getContext.getSession(); 获取application对象 ActionContext.getContext.getApplication();
七、Action获取请求参数的两种方式
在Servlet中,因为线程安全的问题,不能在Servlet中定义成员变量; 但是在Struts2中,Action是每次请求都重新创建,所以肯定在Action中定义模型属性; 1.Action作为Model对象,通过setter方法封装(属性注入) 2.通过独立的model对象,页面ognl表达式封装 两种写法: 一个字段(domain对象),并提供getter和setter方法; 一个字段,new出一个domain对象,提供getter方法
八、Struts2的执行流程(所有的对象都是ObjectFactory创建的)
经过一系列过滤器(Filter)-->FilterDispatcher(前端控制器) 询问ActionMapper是否需要调用Action--> 需要调用Action,前端控制器把请求交给ActionProxy-->ActionProxy通过Configuration Manager 询问配置文件,找到需要调用的Action类-->ActionProxy创建ActionInvocation实例 -->ActionInvocation调用action的前后,会调用拦截器--> action完成后,ActionInvocation根据配置文件找到对应的返回结果
九、拦截器Interceptor介绍
拦截器:Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. AOP:面向切面编程.其实现原理:动态代理模式 当通用的功能代码被封装在拦截器里面(代码模块化), 就可以对不同的Action,根据功能需要,来配置相应功能的拦截器了 拦截器:可以在某个Action方法之前或者之后执行 目的:增强了Action的功能 体现了代码复用特点
十、struts2内置的拦截器
常见的拦截器: 1:params拦截器 这个拦截器偷偷的把请求参数设置到相应的Action的属性去的,并自动进行类型转换。 2.modelDriven拦截器 如果Action实现ModelDriven接口,它将getModel()取得的模型对象存入OgnlValueStack中。 3.execption拦截器 顾名思义,在抛出异常的时候,这个拦截器起作用。最好把它放在第一位,让它能捕获所有的异常。 4.validation拦截器 调用验证框架读取 *-validation.xml文件,并且应用在这些文件中声明的校验。 5.token拦截器 核对当前Action请求(request)的有效标识,防止重复提交Action请求。 6.fileUpload拦截器 用来处理文件上传 7.workflow拦截器 调用Action的validate方法,一旦有错误返回,重新定位到INPUT结果视图 8.servletConfig 通过感知接口,获取感应对象
十一、自定义拦截器
主配置文件sturts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <!-- 配置常量 --> <constant name="struts.devMode" value="true" /> <constant name="struts.action.extension" value="action,do,," /> <!-- <include file="org/fkjava/struts2/_01_/interceptor/struts-login.xml" /> --> <!-- <include file="org/fkjava/struts2/_02_/upload/struts-upload.xml" /> --> <!-- <include file="org/fkjava/struts2/_04_/valuestack/struts-valuestack.xml" /> --> <include file="org/fkjava/struts2/_05_/validation/struts-validation.xml" /> </struts>
1.定义一个拦截器类
实现Interceptor接口或者继承AbstractInterceptor类(重写intercept方法)
public class CheckLoginInterceptor extends AbstractInterceptor{ private static final long serialVersionUID = 1L; @Override public String intercept(ActionInvocation invocation) throws Exception { //获取Session对象中的用户信息 String username = (String) ActionContext.getContext().getSession().get("USER_IN_SESSION"); if(username!=null){ return invocation.invoke(); } return "input"; } }
2.声明/注册拦截器,引用拦截器(根据需要配置拦截器,需要的拦截的就action配置,过滤器通过获取uri,与不拦截的uri进行比较,相同就直接放行)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="intePkg" extends="struts-default" namespace="/"> <!-- 注册拦截器 --> <interceptors> <interceptor name="checkLogin" class="org.fkjava.struts2.interceptor.CheckLoginInterceptor"/> <!-- 设置拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="checkLogin"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <!-- 设置当前包默认拦截器 --> <default-interceptor-ref name="myStack"/> <!-- 定义全局的结果视图 --> <global-results> <result name="input">/views/login/login.jsp</result> </global-results> <action name="login" class="org.fkjava.struts2._01_.interceptor.LoginAction" method="login"> <!-- 设置局部的拦截器引用 --> <interceptor-ref name="defaultStack"/> <result name="success" type="redirectAction">main</result> </action> <action name="main"> <result>/views/login/wecome.jsp</result> </action> </package> </struts>
十二、文件上传
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <h3>文件上传</h3> <form action="/upload" method="post" enctype="multipart/form-data"> 头像:<input type="file" name="headImg"><br> <input type="submit" value="提交"> </form>
Action
public class UploadAction extends ActionSupport { @Setter //与页面的文件name一致 private File headImg; @Setter //文件名称 xxxFileName xxx与headImg一样 private String headImgFileName; private static final long serialVersionUID = 1L; @Override public String execute() throws Exception { String dir = ServletActionContext.getServletContext().getRealPath("/upload"); System.out.println(dir); File dest = new File(dir, headImgFileName); if(!dest.exists()){ dest.mkdir(); } //保存上传的文件 FileUtils.copyFile(headImg, dest); return NONE; } }
十三、文件下载
Struts.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="uploadPkg" extends="struts-default" namespace="/down"> <action name="download" class="org.fkjava.struts2._03_.down.DownloadAction"> <result name="success" type="stream"> <param name="contentDisposition">attachment;fileName="${fileName}"</param> <param name="inputName">downloadFile</param> </result> </action> </package> </struts>
Action
public class DownloadAction extends ActionSupport { private static final long serialVersionUID = 1L; @Setter private String fileName; public String getFileName() throws Exception { fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1"); return fileName; } public InputStream getDownloadFile() throws Exception{ String dir = ServletActionContext.getServletContext().getRealPath("/WEB-INF/download"); File f = new File(dir, fileName); return new FileInputStream(f); } @Override public String execute() throws Exception { return "success"; } }
十四、OGNL和值栈(OGNL获取共享数据,valuestack是封装请求数据)
1.struts2的标签: <%@ taglib uri="/struts-tags" prefix="s" %> 再通过<s:property value=”OGNL的语法”>标签来获取数据. 2. 一个Action->一个请求对象-->一个ValueStack Struts2框架把ValueStack对象保存在名为“struts.valueStack”的request属性中。 3.获取valueStack对象 ServletActionContext.getRequest().getAttribute("struts.valueStack"); ActionContext.getContext().getValueStack(); 4.ValueStack的内部结构 root和context 从root中获取数据: 直接使用属性名获取. ---><s:property value="属性名"/> 从context中获取数据: #key ---><s:property value="#key"/> 5.把数据存放到root 方式1:ValueStack对象.getRoot().add(0, Obejct val);//把数据压入栈顶 方式2:ValueStack对象.getRoot().push(Object val):等价于valueStack对象.getRoot().add(0, Obejct val); 方式3:ValueStack对象.set(String propertyName,Object value); 方式4.在Action中提供一个可访问的属性(getter方法). 6.把数据存放到context 方式1:ValueStack对象.getContext().put(String key,Object value); 方式2:ActionContext对象.getContext().put(String key,Object value);
原文地址:http://blog.51cto.com/10913595/2073855