一、struts2的基础知识
1. struts2的使用优势
自动封装参数
参数校验
结果的处理(转发和重定向)
国际化
显示等待页面
表单的防止重复提交
2. 搭建struts2框架
2.1 导包
2.2 书写action类
public class HelloAction { public String hello() { System.out.println("Hello world!"); return "success"; } }
2.3 书写src/struts.xml
<?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"> <struts> <package name="hello" namespace="/hello" extends="struts-default"> <action name="HelloAction" class="com.java.hello.HelloAction" method="hello"> <result name="success">/hello.jsp</result> </action> </package> </struts>
2.4 将struts2核心过滤器配置到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>/*</url-pattern> </filter-mapping>
3. Struts2的访问流程
4. struts.xml配置详解
<?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"> <struts> <!-- 修改常量配置的方式 --> <!-- i18n:国际化,解决post提交乱码 --> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <!-- 指定访问action时的后缀名 http://localhost:8080/struts2_day01/hello/HelloAction.action --> <constant name="struts.action.extension" value="action"></constant> <!-- 指定struts是否以开发模式运行 开发阶段使用 非开发阶段需要设为false 1. 热加载主配置。(不需要重启即可生效) 2. 提供更多的错误提示信息,方便开发时调试 --> <constant name="struts.devMode" value="true"></constant> <!-- package:将action配置封装在一起,一个package中配置很多的action name属性:给包起个名字,起到标识作用,不能与其他包重名 namespace属性:给action的访问路径中定义一个命名空间 extends属性:继承一个 制定包 必须 abstracts属性:包是否为抽象的;标识属性,标识该包不能独立运行,专门被继承 --> <package name="hello" namespace="/hello" extends="struts-default"> <!-- action元素:配置action类 name属性:决定了Action访问资源名 class:Action类的完整类名 method属性:决定调用action的哪个方法来处理请求 --> <action name="HelloAction" class="com.java.hello.HelloAction" method="hello"> <!-- result元素:结果配置 name属性:表示结果处理的名称,与Action类的返回值对应 type属性:指定调用哪一个result类来处理结果,默认使用转发 标签体:填写页面的相对路径 --> <result name="success">/hello.jsp</result> </action> </package> <!-- 引入其他的struts文件 --> <include file="com/java/dynamic/struts.xml"></include> <include file="com/java/struts_default/struts.xml"></include> </struts>
5. 动态方法的调用(两种方式)
5.1 第一种方式
在struts.xml中配置动态方法调用是否开启,默认是个关闭的,需要开启。
<!-- 配置动态方法调用是否开启 默认是关闭的,需要开启 --> <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
浏览器中访问的url为
http://localhost:8080/struts2_day01/dynamic/Demo1Action!find.action
5.2 第二种方式
在struts.xml中配置如下:
<package name="dynamic" namespace="/dynamic" extends="struts-default"> <!-- 配置动态方法调用(常用方式) --> <action name="Demo1Action_*" class="com.java.dynamic.Demo1Action" method="{1}"> <result name="success">/hello.jsp</result> </action> </package>
通配符方式,使用{1}取出第一个星号通配的方法名
浏览器中访问的url为
http://localhost:8080/struts2_day01/dynamic/Demo1Action_delete.action
二、 struts的进阶
1. 结果跳转的方式
1.1 转发(默认)
<!-- 转发(默认) --> <action name="Demo1Action" class="com.java.result.Demo1Action" method="execute"> <result name="success" type="dispatcher">/hello.jsp</result> </action>
1.2 重定向
<!-- 重定向 --> <action name="Demo2Action" class="com.java.result.Demo2Action" method="execute"> <result name="success" type="redirect">/hello.jsp</result> </action>
1.3 转发到action
<!-- 转发到Action --> <action name="Demo3Action" class="com.java.result.Demo3Action" method="execute"> <result name="success" type="chain"> <!-- action的名称 --> <param name="actionName">Demo1Action</param> <!-- action所在的命名空间 --> <param name="namespace">/</param> </result> </action>
1.4 重定向到action
<!-- 重定向到Action --> <action name="Demo4Action" class="com.java.result.Demo4Action" method="execute"> <result name="success" type="redirectAction"> <!-- action的名称 --> <param name="actionName">Demo1Action</param> <!-- action所在的命名空间 --> <param name="namespace">/</param> </result> </action>
2. 访问servlet API的方式
2.1 通过ActionContext
1 /** 2 * 通过ActionContext访问Servlet的API 3 * @author vanguard 4 * 5 */ 6 public class Demo5Action extends ActionSupport { 7 @Override 8 public String execute() throws Exception { 9 //request域 不推荐这种方式 10 Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request"); 11 //推荐使用Action域充当request域 12 ActionContext.getContext().put("name", "requestTom"); 13 //session域 ->Map 14 Map<String, Object> session = ActionContext.getContext().getSession(); 15 session.put("name", "sessionJack"); 16 //application域 ->Map 17 Map<String, Object> application ActionContext.getContext().getApplication(); 18 application.put("name", "applicationTom"); 19 //获得表单中的参数Map集合 20 Map<String, Object> parameters ActionContext.getContext().getParameters(); 21 return SUCCESS; 22 } 23 }
2.2 通过ServletActionContext访问Servlet的API
/** * 通过ServletActionContext访问Servlet的API * @author vanguard * */ public class Demo6Action extends ActionSupport { @Override public String execute() throws Exception { //原生request HttpServletRequest request = ServletActionContext.getRequest(); //通过request获得session HttpSession session = request.getSession(); //原生response HttpServletResponse response = ServletActionContext.getResponse(); //原生ServletContext对象 ServletContext servletContext = ServletActionContext.getServletContext(); return SUCCESS; } }
2.3 通过实现接口的方式
/** * 通过实现接口的方式访问Servlet的api * @author vanguard * */ public class Demo7Action extends ActionSupport implements ServletRequestAware { private HttpServletRequest request; @Override public String execute() throws Exception { System.out.println("原生request" + request); return SUCCESS; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } }
3. 如何获得页面传递的参数
3.1 属性驱动获得参数
<form action="${pageContext.request.contextPath }/Demo8Action" method="post"> name:<input type="text" name="name"><br> age:<input type="text" name="age"><br> birthday:<input type="text" name="birthday"><br> <input type="submit" value="提交" > </form>
Demo8Action.java
/** * 属性驱动获得参数 * @author vanguard * */ public class Demo8Action extends ActionSupport { //参数名称相同的属性 private String name; //自动类型转换 只能转换八大基本类型以及对应的包装类 private Integer age; //支持特定类型的字符串转化成Date类型 yyyy-MM-dd private Date birthday; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String execute() throws Exception { System.out.println("name:" + name + ",age:" + age + ",birthday:" + birthday); return super.execute(); } }
3.2 对象驱动获得参数
<form action="${pageContext.request.contextPath }/Demo9Action" method="post"> name:<input type="text" name="user.name"><br> age:<input type="text" name="user.age"><br> birthday:<input type="text" name="user.birthday"><br> <input type="submit" value="提交" > </form>
Demo9Action.java
/** * 使用对象驱动获得参数 * @author vanguard * */ public class Demo9Action extends ActionSupport { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String execute() throws Exception { System.out.println(user); return SUCCESS; } }
3.3 模型驱动获得参数
<form action="${pageContext.request.contextPath }/Demo10Action" method="post"> name:<input type="text" name="name"><br> age:<input type="text" name="age"><br> birthday:<input type="text" name="birthday"><br> <input type="submit" value="提交" > </form>
Demo10Action.java
/** * 使用模型驱动获得参数 * @author vanguard * */ public class Demo10Action extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public String execute() throws Exception { System.out.println(user); return SUCCESS; } @Override public User getModel() { return user; } }
3.4 集合类型的封装
<form action="${pageContext.request.contextPath }/Demo11Action" method="post"> list<input type="text" name="list"><br> list<input type="text" name="list[3]"><br> map<input type="text" name="map['key']"><br> map<input type="text" name="map['key']"><br> <input type="submit" value="提交" > </form>
Demo11Action.java
/** * 集合类型封装参数 * @author vanguard * */ public class Demo11Action extends ActionSupport { private List<String> list; private Map<String, String> map; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Map<String, String> getMap() { return map; } public void setMap(Map<String, String> map) { this.map = map; } @Override public String execute() throws Exception { System.out.println(map); System.out.println(list); return SUCCESS; } }
2. 自定义拦截器
2.1 自定义拦截器的创建
/** * 自定义Interceptor (推荐) * 功能:定制拦截器拦截的方法 * 哪些方法不需要拦截 excloud * 哪些方法需要拦截 incloud * * 当doInterceptor()不放行返回字符串时,不执行后续的拦截器以及Action, * 直接交给Result处理结果。进行页面跳转 * @author vanguard * */ public class MyInterceptor3 extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation invocation) throws Exception { //前处理 System.out.println("MyInterceptor的前处理"); //放行 String result = invocation.invoke(); //后处理 System.out.println("MyInterceptor的后处理"); return result; } }
2.3 拦截器的配置
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> 3 <struts> 4 <constant name="struts.devMode" value="true"></constant> 5 6 <package name="interceptor1" namespace="/" extends="struts-default"> 7 <!-- 1. 注册拦截器 --> 8 <interceptors> 9 <interceptor name="myInterceptor" class="com.java.interceptor.MyInterceptor3"></interceptor> 10 <!-- 2. 注册拦截器栈 --> 11 <interceptor-stack name="myStack"> 12 <!-- 引入自定义的拦截器(建议放在20个拦截器栈之前) --> 13 <interceptor-ref name="myInterceptor"> 14 <!-- 指定哪些方法不拦截 --> 15 <!-- <param name="excludeMethods">add,select</param> --> 16 <!-- 指定哪些方法拦截 --> 17 <param name="includeMethods">add,update</param> 18 </interceptor-ref> 19 <!-- 引入20个默认的拦截器栈 --> 20 <interceptor-ref name="defaultStack"></interceptor-ref> 21 </interceptor-stack> 22 </interceptors> 23 <!-- 3. 指定包中的默认拦截器栈 --> 24 <default-interceptor-ref name="myStack"></default-interceptor-ref> 25 <action name="Demo1Action_*" class="com.java.interceptor.Demo1Action" method="{1}"> 26 <!-- 为Action单独指定拦截器(栈) --> 27 <!-- <interceptor-ref name="myStack"></interceptor-ref> --> 28 <result name="success">/index.jsp</result> 29 </action> 30 </package> 31 </struts>