Struts2中一些零碎的知识点:struts.xml详解、模型驱动、Preparable接口、防止表单重复提交、ActionContext、动态方法调用、异常
1、struts.xml详解
a. struts.properties
在struts.xml中可以定义constant覆盖struts-core.jar/org/apache/struts2/default.properties中的设置。
例:
也可以直接新建struts.properties(与struts.xml在同一目录),在struts.properties中配置。推荐在struts.properties中进行配置。
例:struts.custom.i18n.resources = message
b. abstract package
struts-core.jar/struts-default.xml,中有如下定义。
......
其中abstract="true"中,表示在此package中不能定义Action(与Java abstract类相似),仅供继承。
c. namespace
strut.xml中:
......
默认命名空间为namespace="",命名空间要以"/"开头。
JSP访问:
不能写成
d. 模块化配置
......
<include file="struts1.xml" />
......
include中struts1.xml的编写与struts.xml是类似的。
2、属性驱动与模型驱动
属性驱动:直接在Action中写表单属性。
/StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousAction.java:
package wintys.struts2.miscellaneous;
import com.opensymphony.xwork2.ActionSupport;
/**
*
* @author Winty ([email protected])
* @version 2009-8-24
* @see http://wintys.blogjava.net
*/
@SuppressWarnings("serial")
public class MiscellaneousAction extends ActionSupport {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
模型驱动:将属性放到JavaBean中,Action需要实现com.opensymphony.xwork2.ModelDriven接口。ModelDrivenInterceptor 必须在之前StaticParametersInterceptor and ParametersInterceptor。这个顺序已在defaultStack Interceptor中定义。
/StrutsHelloWorld/src/wintys/struts2/miscellaneous/User.java:
package wintys.struts2.miscellaneous;
/**
* 模型驱动Action中的模型
* @author Winty ([email protected])
* @version 2009-8-25
* @see http://wintys.blogjava.net
*/
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
/StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousModelDrivenAction.java:
package wintys.struts2.miscellaneous;
import com.opensymphony.xwork2.ModelDriven;
@SuppressWarnings("serial")
public class MiscellaneousModelDrivenAction extends ActionSupport implements
ModelDriven{
private User user = new User();
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
3、Preparable接口
Action还可以实现com.opensymphony.xwork2.Preparable接口,用于准备Action自己。Preparable中的prepare方法在Action执行其它方法前执行。
4、使用simple 主题时,如何单独格式化Struts错误提示信息
单独显示name字段的fielderror:
name
5、Struts防止表单重复提交
JSP页面中加入token和actionerror:
token产生的actionerror的i18n key为:struts.message.invalid.token。
在struts.xml中的Action配置中加入token interceptor,和invalid.token result:
/miscellaneous/output.jsp
/miscellaneous/input.jsp
/miscellaneous/input.jsp
生成的JSP页面如下:
struts.token.name指
6、通过Struts获取Servlet API
一般Java Web程序不能离开容器进行测试。容器内测试常用框架:Cactus(jakarta.apache.org/cactus/index.html) 、Mock。
通过Struts获取Servlet API,使程序可脱离容器测试。Struts中可通过如下方法获取Servlet API:ActionContext 、ServletActionContext、ServletXXXAware。首选ActionContext,其次选择ServletActionContext,再次ServletXXXAware。
a. ActionContext
com.opensymphony.xwork2.ActionContext.getActionContext()获取ActionContext实例。
ActionContext的get()和put()方法与HttpServletRequest的对应关系:
ActionContext.get() <=> HttpServletRequest.getAttribute()
ActionContext.put() <=> HttpServletRequest.setAttribute()
例:
ActionContext context = ActionContext.getContext();
context.put("info", "this is ActionContext value");
但是ActionContext无法获取Servlet HttpResponse对象。
b. ServletActionContext
org.apache.struts2.ServletActionContext是com.opensymphony.xwork2.ActionContext的子类。
使用静态方法直接获取Servlet对象:
Request: ServletActionContext.getRequest();
Response: ServletActionContext.getResponse();
Session: ServletActionContext.getRequest().getSession();
例:
Cookie cookie = new Cookie("mycookie" , "10000");
HttpServletResponse response = ServletActionContext.getResponse();
response.addCookie(cookie);
c. ServletXXXAware接口
org.apache.struts2.util.ServletContextAware接口
org.apache.struts2.interceptor.ServletRequestAware接口
org.apache.struts2.interceptor.ServletResponseAware接口
org.apache.struts2.interceptor.SessionAware接口
实现ServletXXXAware接口的Action会被Struts自动注入相应的Servlet对象。
例:
package wintys.struts2.miscellaneous;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class MiscellaneousModelDrivenAction extends ActionSupport implements
ServletRequestAware {
private HttpServletRequest request;
......
@Override
public String execute() throws Exception {
//实现ServletRequestAware接口,Struts自动注入的request
Cookie[] cookies = this.request.getCookies();
for(Cookie ck : cookies){
System.out.print("cookie:" + ck.getName());
System.out.println(" = " + ck.getValue());
}
return SUCCESS;
}
......
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
7、动态方法调用
a. Action配置中,由method指定动态调用方法的名称。
......
b.在JSP页面中,调用Action时加感叹号指定动态调用方法的名称。
c.通配符
则请求中helloaction对应到action中的hello()方法,以此类推。
8、异常
发生异常时,可转到指定的result。由exception-mapping配置
/miscellaneous/output.jsp
/miscellaneous/input.jsp
/miscellaneous/nameInvalidException.jsp
也可以配置全局exception mapping
nameInvalidException.jsp:
NameInvalidException.java:
package wintys.struts2.miscellaneous;
@SuppressWarnings("serial")
public class NameInvalidException extends Exception {
public NameInvalidException(String message) {
super(message);
}
}
9、详细代码
/StrutsHelloWorld/WebRoot/miscellaneous/input.jsp:
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
Input
用户名:
name
密码:
password
动态方法调用方法二: miscellaneous!myexecute
/StrutsHelloWorld/WebRoot/miscellaneous/output.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
Output
提交结果:
用户名:
密码:
${request.info}
${cookie.mycookie.value }
/StrutsHelloWorld/src/wintys/struts2/miscellaneous/MiscellaneousModelDrivenAction.java:
package wintys.struts2.miscellaneous;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
* Struts2深入探索
* @author Winty ([email protected])
* @version 2009-8-26
* @see http://wintys.blogjava.net
*/
@SuppressWarnings("serial")
public class MiscellaneousModelDrivenAction extends ActionSupport implements
ModelDriven , ServletRequestAware {
private User user = new User();
private HttpServletRequest request;
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
System.out.println("this is model driven action");
if(user.getName().equals("admin")){
throw new NameInvalidException("name 'admin' is invalid");
}
//ActionContext.put相当于HttpServletRequest.setAttribute()
ActionContext context = ActionContext.getContext();
context.put("info", "this is ActionContext value");
//ServletActionContext.getResponse得到Response对象
Cookie cookie = new Cookie("mycookie" , "10000");
HttpServletResponse response = ServletActionContext.getResponse();
response.addCookie(cookie);
//实现ServletRequestAware接口,Struts自动注入的request
Cookie[] cookies = this.request.getCookies();
for(Cookie ck : cookies){
System.out.print("cookie:" + ck.getName());
System.out.println(" = " + ck.getValue());
}
return SUCCESS;
}
public String myexecute()throws Exception{
System.out.println("myexecute()");
return SUCCESS;
}
@Override
public void validate() {
if(user.getName() == null || user.getName().equals("")){
this.addFieldError("name", "invalid name");
}
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
/src/struts.xml:
/miscellaneous/output.jsp
/miscellaneous/input.jsp
/miscellaneous/nameInvalidException.jsp
/miscellaneous/input.jsp
[参考资料]:
[1]《浪曦视频之Struts2应用开发系列》
[2] No configuration found for the specified action : http://javasunnyboy.javaeye.com/blog/254753
该篇BOLG 摘自 http://www.blogjava.net/wintys/archive/2009/08/29/struts_helloworld_miscellaneous.html
感谢博主的分享. 觉得很实用就全文摘抄下来了..呵呵~~