Java学习之struts2使用
Java学习之struts2使用
0x00 前言
持续记录学习内容
0x01 struts2 使用
- 导入ja包
<dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.13</version> </dependency> </dependencies>
- web.xml配置
<!--Struts2核心过滤器--> <filter> <filter-name>Struts2</filter-name> <filter- class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExe cuteFilter</filter-class> </filter> <filter-mapping> <filter-name>Struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- Action类
package action; import com.opensymphony.xwork2.Action; public class HelloWorldAction implements Action{ //请求中传递的参数和返回给页面的值都定义成属性 private String username private String password //getter/setter方法 @Override public String execute()throws Exception{ //查看请求中传递的参数 System.out.print1n(username); //改变这个message,会自动传递给页面 message="hello:"+username; //SUCCESS是Action中的常量,值是success return SUCCESS; }}
- 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> <.--所有的action都放在package中,必须继承struts-default--> <!--struts-default中有默认的拦截器配置,能处理参数等信息--> <package name="default"extends="struts-default"> <!--name对应的是请求的地址,class是处理请求的类--> <action name="hel1o"class="action.HelloWorldAction"> <!--success是Action类中返回的字符串,根据不同字符串返回不同的页面--> <result name="success">index.jsp</result> </action></package> </struts>
- 编写index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE HTML> <html> <head> <title>Title</title> <meta charset="UTF-8"> </head> <body> <h1>struts2</h1> <form action="hello" method="post"> id:<input name="user.id"> username:<input name="user.username"> <input type="submit" value="提交"> </form> ${requestScope.message} </body> </html>
访问到http://127.0.0.1/hello.action时,则就映射到
HelloWorldAction.execute方法里面,而这里的方法返回
SUCCESS,struts2这样进行了配置
<action name="hel1o"class="action.HelloWorldAction"> <!--success是Action类中返回的字符串,根据不同字符串返回不同的页面--> <result name="success">index.jsp</result> </action>
<result name="success">index.jsp</result>
则代表如果这个
HelloWorldAction.execute方法返回的是
success的话则映射到
index.jsp文件中。
struts默认支持的请求后缀是.action,如果需要配置其它的后缀,需要在struts.xml中配置:
设置允许请求后缀为do和html
<constant name="struts.action.extension" value="do, html"/>
0x02 struts.xml详解
constant 标签
<!--设置请求后缀--> <constant name="struts.action.extension"value="do,html"/> <!--设置编码,解决中文乱码--> <constant name="struts.i18n.encoding"value="utf-8"/> <!--设置struts标签主题--> <constant name="struts.ui.theme"value="simple"/>
constant用来配置常量。name属性是常量名,value属性是常量值。 constant常量可以改变Struts2的一些行为,比如U山标签的样式、编码格式等。 因为struts2默认的编码格式就是UTF-8,所以不用特意指定编码,中文也不会乱码。
package标签
<package name="default" namespace="/" extends="struts-default">
package是包。Struts2的package与java中的package类似,可以把同一个业务模块的action和result集中到一个包中,方便管理。不同的是Struts2的包可以继承。比如商品有增删改查操作,订单也有增删该查操作,我们可以将商品和订单的action分别放两个package中方便管理。
name属性是包的名字,一个struts.xml中可以有很多个package,通过name属性进行区分。
namespace是命名空间,/代表的是根目录。namespace的作用类似于SpringMVC中在Controller类上加@RequestMapping注解。相当于此包中所有的action前都加一个父路径。如:
<package name="user"namespace="/user"extends="struts- default"> <action name="login"class="action.LoginAction">
上面这个name=login的action,在访问的时候路径就是
/user/login.action extends属性是继承,通常都会继承struts-default。在struts-default中定义了大量的struts特性,如拦截器和参数处理的功能,如果不继承struts-default,会遇到参数无法绑定或找不到action类。
action标签
<action name="1ogin"class="action.LoginAction"> <--success是Action类中返回的字符串,根据不同字符串返回不同的页面--> <result name="success">index.jsp</result> <result name="error">error.jsp</result><result name="input">1ogin.jsp</result> </action>
action标签用来处理请求和响应结果。 name属性是请求的名字,此处不需要加.action。同一个package下的action不能重名。 class属性指定处理该请求的类,是类的全路径。默认的处理请求时会去类中找名为execute的方法。如果不指定class,将默认ActionSupport为处理请求的类。 result标签用来处理请求结果,name属性是Action类中返回的字符串。标签的值是要跳转的页面地址。name如果不写的话,默认是success。
0x03 Action配置
Struts2的主要核心是Action类。
import com.opensymphony.xwork2.Action;public class HelloWorldAction implements Action{ //请求中传递的参数和返回给页面的值都定义成属性 private String username; private String message; //getter/setter方法 @0verride public String execute()throws Exception{ //查看请求中传递的参数 System.out.println(username); //改变这个message,会自动传递给页面 message="hello:"+username; //SUCCESS是Action中的常量,值是success return SUCCESS;
一个Action业务里可以实现Action接口,也可以继承ActionSupport类。在ActionSupport中提供了一些实现好的业务方法。在以后的编程中,建议全部继承ActionSupport类。 Action中的方法必须返回一个String类型的字符串,这个字符串与struts.xml中result标签的name属性相对应,struts.xml会根据返回的字符串查找对应的页面。 在Action接口中提供了5个常用的结果常量:
package com.opensymphony.xwork2; public interface Action { String SUCCESS = "success"; String NONE = "none"; String ERROR = "error"; String INPUT = "input"; String LOGIN = "login"; String execute() throws Exception; }
自定义业务
在前面的学习中,Action类中只有一个execute方法。 假如用户有注册和登录两个功能,我们可以把这两个功能写进同一个Action类:
package action;import com.opensymphony.xwork2.ActionSupport; /∥继承ActionSupport类 public class UserAction extends ActionSupport{ //处理登录 public String 1ogin(){ //参数和业务略 System.out.println("我是登录"); return SUCCESS; //处理注册 public String regist(){ //参数和业务略 System.out.println("我是注册"); return SUCCESS; }
注意所有处理请求的业务方法必须是public的,而且要返回一个String。struts.xml中配置:
<package name="user"namespace="/user"extends="struts- default"> <!-一通过method指定调用类中的哪个方法--> <action name="login"class="action.UserAction" method=“1ogin"> <result name="success">index.jsp</result><!--登录成功去首页--> <result name="error">1ogin.jsp</result><!--登录失败回登录页--> </action> <action name="reg"class="action.UserAction" method="regist"> <result name=“success">index.jsp</result><!--注册成功去首页--> <result name="error">regist.jsp</result><!--注册失败回登录页--> </action> </package>
method="login"表示要调用类中的login方法处理请求。如果找不到login0方法,Struts2会在类中查找doLogin)方法。如果都找不到,将会报错。
动态方法调用
如果一个类中有多个业务方法,又不想给每个业务方法都配置一个action标签,可以使用动态党法调用,语法是:请求名!方法名.action当请求的格式是user!login.action时,代表调用UserAction中的login)方法处理当前请求。当请求的格式是user.regist.action时,代表调用UserAction中的regist)方法处理当前请求。
<!--允许调用动态方法--> <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
action配置
<!--允许动态调用的方法,新版里新增的设置--> <g1obal-a1lowed-methods>1ogin,regist</g1obal-a1lowed-methods> <action name="user"class="action.UserAction"> <result name="success">/index.jsp</result><!--成功去首页--> <result name="error">/error.jsp</result><!--失败去错误--> </action>
通配符使用
<g1obal-allowed-methods>login,regist</global-allowed-methods> <action name="*User"class="action.UserAction"method="{1}"> <result name="success">/index.jsp</result> <result name="error">{1}.jsp</result><!--失败了就返回原来的页面--> </action>
User匹配所有以User结尾的请求,method={1}中的{1}匹配的就是 User中的。如果请求的地址是loginUser.action,那么{1}匹配的就是login,就会去类中调用login方法,并返回相应的结果。
默认Action
如果在struts.xml中找不到匹配的action,将会报错。可以设置一个默认的action。当所有请求都不匹配时,将匹配默认action。
<default-action-ref name="default"/> <action name="default"> <result>error.jsp</result> </action>
对当前的package有效。 action标签的clas省略将调用ActionSupport类。result的name省略将默认为success。 注意default-action-re必须在所有的action标签上面。
Result 配置
常用结果有三种类型:dispatcher、redirect、redirectAction、chain
dispatcher
result的默认类型就是dispatcher。以下两个标签是等价的: dispatcher的结果等同于Servlet中的请求转发,即:
request.getRequestDispatcher("success.jsp").forward(request,response);请求转发的意思是当前请求中的参数、属性在下一个页面或请求中仍然可 以使用。
<result name="success"type="dispatcher">index.jsp</result> <result name="success">index.jsp</result>
redirect
redirect是重定向,重定向之后,当前请求中的参数和属性在下一个页面或请求中将不能使用。
<result name="success"type="redirect">index.jsp</result>
相当于Servlet中的:response.sendRedirect("success.jsp");
redirectAction
redirectAction与redirect类似,不过redirectAction是重定向到某一个action
<action name="reg"class="action.UserAction"method="regist"> <result name="success" type="redirectAction">1ogin.action</result> <result name="error">regist.jsp</result> </action>
如果要调用不同package下的action,需要在result中传参数:
<action name="login"class="action.UserAction"method="login"> <result name="success"type="redirectAction"> <!--调用不同package下的action--> <param name="namespace">/</param> <param name="actionName">hel1o.action</param> <!--传递其它参数--> <param name="username">123</param> </result> <result name="error">login.jsp</result> </action>
chain
redirectAction不能共享request中的数据,如果想共享数据,可以将type设置为chain。
<action name="reg"class="action.UserAction"method="regist"> <!--注意chain的action后面没有后缀--> <result name="success"type="chain">login</result> <result name="error">regist.jsp</result> </action>
动态获取结果
private String username;private String page; //getter/setter方法略 public String 1ogin(){ //参数和业务略 System.out.print1n(“我是登录");if("admin".equals(username)){//管理员去管理页page="admin-page"; }else{//其他人去用户页page="user-page";return SUCCESS; }
result配置
<action name="login"class="action.UserAction"method="1ogin"> <!--读取action中的属性值,返回不同页面--> <result name="success">${page}.jsp</result> <result name="error">login.jsp</result> </action>
访问Servlet
Struts2访问Servlet API有解耦和耦合两种方式
解耦方式
Struts2将部分Servlet APl中的对象封装成Map,可以通过ActionContext获取。获取到的Servlet API对象全部是Map
public String regist(){ ActionContext ac=ActionContext.getContext(); Map request=(Map)ac.get("request"); //获取request Map session=ac.getSession(); //获取session Map application=ac.getApplication(); //获取application session.put("session_user",“123"); //向session中存值 return SUCCESS;
需要注意的是Session和Application都有对应的get方法,而request没有,需要使用get("request")获取。 页面上可以使用
${sessionScope.session_id}取值
解耦方式
该方式需要导入jar包
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency>
HttpServletRequest request= ServletActionContext. getRequest(); HttpSession session=request.getSession(); HttpServletResponse response= ServletActionContext.getResponse();
0x03 struts 标签
<s:form action="/user/login.action"method="POST"> <s:textfield name="username"1abel=“用户名"/> <s:password name="password"1abe1="密码“/> <s:submit value=“登录"/> </s:form>
如果想使用原始的样式可以配置struts.xml
<constant name="struts.ui.theme"value="simple"/>
通用标签
<s:if test=""></s:if> <s:elseif test=""></s:elseif> <s:else></s:else>
si标签用于条件判断,相当于jstl中的
<c:if test=""></c:if>
s:elseif和s:else标签必须与s:if结合使用。
<s:iterator value=""var=""status=""></s:iterator>
s:iterator用于集合的遍历,相当于jstl中的
0x04 数据校验
通用校验
Action类继承ActionSupport,ActionSupport中有一个validate方法进行数据校验,只需要重写该方法即可实现数据校验功能。
package action; import com.opensymphony.xwork2.ActionSupport; public class ValidateAction extends ActionSupport { private String username;//用户名不能为空,并且长度要大于6 @Override public void validate() { System.out.println("validate()"); if (username == null || username.trim().length() < 6) { addFieldError("username", "必须输入用户名,长度大于6"); } } public void validateLogin() { System.out.println("validateLogin() "); if (username == null || username.trim().length() < 6) { addFieldError("username", "xxx"); } } public String login() { System.out.println("登陆"); return SUCCESS; } public String regist() { System.out.println("注册"); return SUCCESS; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
addFieldError要求必须给result配置一个input类型的结果。所以在调用logout方法时,会报找不到result input。
<action name="valLogin" class="action.ValidateAction" method="login"> <result name="success">main.jsp</result> <result name="input">val.jsp</result> </action>
方法校验
validate方法会验证当前Action类中所有的方法,如果只想验证其中的一个方法,可以使用validatexxx方法,其中xxx是被验证的方法名,首字母大写。
//只验证1ogin方法,不验证其它方法 public void validatelogin(){ if(username==nul1 ll username.1ength()==0){ //向页面中添加错误信息 addFieldError("username",“用户名不能为空”);
校验框架
验证框架是把验证信息都写在xm文件中,对某一个Action类进行验证,需要在Action类的同一个包下创建xml文件,文件命名为Action类的类名validation.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <field name="username"> <field-validator type="requiredstring"> <message>必须输入用户名</message> </field-validator> <field-validator type="stringlength"> <param name="minLength">6</param> <message>长度必须大于${minLength}</message> </field-validator> </field> </validators>
validators标签:在校验框架中,所有的验证都写在validators标签中field标签:每一个需要验证的属性都是一个field标签,name指定要验证那个属性。 field-validator标签:代表一种验证规则,通过type指定规则。
0x05 拦截器
拦截器可以在请求进入action之前做预处理,比如判断用户是否登录。也可以在action执行之后进行处理。和filter比较像,但是filter是基于函数回调,而拦截器是基于反射去实现。
创建一个类需要实现Interceptor接口
import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; public class TimeInterceptor implements Interceptor { @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation actionInvocation) throws Exception { long start = System.currentTimeMillis(); String result = actionInvocation.invoke();//将请求放行,进入action long end = System.currentTimeMillis(); System.out.println("运行时间:" + (end - start)); return result; }
在struts.xml中配置拦截器
<package name="test" namespace="/" extends="struts-default,json-default"> <interceptors> <interceptor name="time" class="interceptor.TimeInterceptor"/> <interceptor name="login" class="interceptor.LoginInterceptor"/> <interceptor-stack name="time-stack"> <interceptor-ref name="time"/> <interceptor-ref name="login"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <global-results> <result name="login">/login.jsp</result> </global-results>
注意配置位置
在需要拦截的Action中添加拦截器的引用
<action name="hello"class="action.HelloWorldAction"> <interceptor-ref name="time"/> <result name="success">index.jsp</result> </action>
这时候去访问hell.action就可以进入到拦截器了。
使用自定义拦截器会造成参数无法读取,这时候可以引入struts自带的拦截器。
<default-interceptor-ref name="time"/>
拦截器栈
<interceptors> <interceptor name="time" class="interceptor.TimeInterceptor"/> <interceptor name="1ogin" class="interceptor.LoginInterceptor"/> <!--拦截器栈,多个拦截器捆绑在一起执行--> <interceptor-stack name="time-1ogin"> <interceptor-ref name="time"/> <interceptor-ref name="1ogin"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors>
将多个拦截器绑定到一起,只需要引用拦截器栈即可。
登录拦截
import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import java.util.Map; public class LoginInterceptor implements Interceptor { @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation actionInvocation) throws Exception { ActionContext actionContext = ActionContext.getContext(); Map session = actionContext.getSession(); if(session.get("SEEION_USER")==null){//没有登陆 return "login"; } return actionInvocation.invoke(); } }
0x06 JSON
导入依赖
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>2.5.13</version> </dependency>
Action类:
public class JsonAction extends ActionSupport { private Map<String, Object> resultMap; @Override public String execute() throws Exception { resultMap = new HashMap<>(); resultMap.put("key1", "abc"); resultMap.put("key2", 123); return "success"; } public Map<String, Object> getResultMap() { return resultMap; } public void setResultMap(Map<String, Object> resultMap) { this.resultMap = resultMap; } }
<package name="default"namespace="/"extends="struts- default, json-default"> <action name="json"class="action. JsonAction" method="getJson"> <result type="json"> <param name="root">resultMap</param> </result>
这个包必须继承json-default
0x07 文件上传
public class FileAction extends ActionSupport { private File upload; private String uploadFileName; public String upload() { System.out.println(uploadFileName); try { String ext=uploadFileName.substring(uploadFileName.lastIndexOf(".")); byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(upload); FileOutputStream fos = new FileOutputStream("d:/upload/" + System.currentTimeMillis()+ext); int len = fis.read(buffer); while (len != -1) { fos.write(buffer); len = fis.read(buffer); } fos.close(); fis.close(); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; }
Action代码中的upload与页面表单中的upload相对应。使用xxFileName封装文件名,其中的xx指代File变量的名字。
Struts.xml配置
<action name="upload" class="action.FileAction" method="upload"> <result name="success">/upload.jsp</result> </action>
上传页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE HTML> <html> <head> <title>Title</title> <meta charset="UTF-8"> </head> <body> <form action="upload.do" method="post" enctype="multipart/form-data"> <input type="file" name="upload"/><input type="submit" value="上传"> </form> <a href="down.do?fileName=1559974348355.png">下载</a> </body> </html>
0x08 结尾
冲冲冲!!!
- java struts2入门学习实例--使用struts2快速实现上传
- Java学习笔记 Struts2的Validate()方法的使用
- 【JavaWeb_struts2学习杂记】struts2的使用配置
- java struts2入门学习实例--使用struts进行验证
- java struts2入门学习实例--使用struts进行验证
- java struts2入门学习实例--使用struts2快速实现多个文件上传
- 【JAVA学习】struts2的action中使用session的方法
- 【JAVA学习】struts2的action中使用session的方法
- JAVA_WEB Struts2学习:使用验证框架进行校验JSP页面元素 反编译工具的配置 Strtuts2 国际化学习
- java痛苦学习之路[四]---关于struts2-convention-plugin使用
- 学习JAVA-三步半使用开始LOG4J。
- Struts2 学习 第一章 struts2中Action类的使用
- 计算Java日期--学习怎样创建和使用日期
- java-使用keytool来创建管理密钥及证书等-java学习笔记(3)
- eclipse的几个使用技巧(我的java学习笔记)
- 使用 AppFuse 的七个理由--学习 Java 开放源码工具 —— 并使用这些工具提高生产效率
- java:log4j学习(2)-转帖:Common-logging 与 Log4j的结合使用
- [Java学习]对话框的使用1
- 传智播客java web 学习,自定义标签的开发和使用
- 学习笔记: Struts2中使用validate框架对Action的不同方法进行验证