在这里我不说struts2的验证原理以及语法,我只讲一下关于struts2验证返回input视图的解决办法。
当然如果你是使用一个方法对一个类,则不存在上面的问题,当然一个方法对应一个类,这种方式虽然可读性很高但是实际开发确实不可取,因为他会使类极具增加。如果你是使用一个类对应多个方法,你肯定碰到过这样一个问题,那就是验证时返回input视图,struts2默认验证失败返回input视图,但是我们在写程序中经常会有多个方法需要验证,打个比方如:create、update这两个操作一般情况下都会验证,但是我们把它写在一个类中,我们如果区分验证失败后,到底是create失败了还是update失败了呢?这个时候有没有怀疑过struts2,呵呵。
当然struts2其时已经给了我们解决办法,如果你是一个细心的人读过struts2源码便过发现struts2是如何解决问题的,在这里我也简单的分析一下struts2的源码,大家请看下面这个类。
至此,有问题可以留言。
转载地址,onlyeffort.QQ:501276913 http://www.blogjava.net/grasszring/archive/2010/06/08/323092.html
当然如果你是使用一个方法对一个类,则不存在上面的问题,当然一个方法对应一个类,这种方式虽然可读性很高但是实际开发确实不可取,因为他会使类极具增加。如果你是使用一个类对应多个方法,你肯定碰到过这样一个问题,那就是验证时返回input视图,struts2默认验证失败返回input视图,但是我们在写程序中经常会有多个方法需要验证,打个比方如:create、update这两个操作一般情况下都会验证,但是我们把它写在一个类中,我们如果区分验证失败后,到底是create失败了还是update失败了呢?这个时候有没有怀疑过struts2,呵呵。
当然struts2其时已经给了我们解决办法,如果你是一个细心的人读过struts2源码便过发现struts2是如何解决问题的,在这里我也简单的分析一下struts2的源码,大家请看下面这个类。
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import java.lang.reflect.Method;
public class DefaultWorkflowInterceptor extends MethodFilterInterceptor {
private static final long serialVersionUID = 7563014655616490865L ;
private static final Logger LOG = LoggerFactory.getLogger(DefaultWorkflowInterceptor. class );
private static final Class[] EMPTY_CLASS_ARRAY = new Class[ 0 ];
// 默认返回input视图,是在这里定义的
private String inputResultName = Action.INPUT;
// 可以在这里更改,一般没有人会这么做
public void setInputResultName(String inputResultName) {
this .inputResultName = inputResultName;
}
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware validationAwareAction = (ValidationAware) action;
if (validationAwareAction.hasErrors()) {
if (LOG.isDebugEnabled()) {
LOG.debug( " Errors on action " + validationAwareAction + " , returning result name 'input' " );
}
// one
String resultName = inputResultName;
/*
在这里大家读一下源码即可明白,当前处理的Action如果是一个ValidationWorkflowAware类型的,
则调用他的getInputResultName作用返回值
为了方便我直接把ValidationWorkflowAware放在下面的注释中,大家看他是一个接口,
也就是说如果我们的Action实现了ValidationWorkflowAware接口
他则会调用getInputResultName方法返回的值,而非input,而默认的ActionSupport没有实现这个接口,我们需要手动实现
*/
// package com.opensymphony.xwork2.interceptor;
// public interface ValidationWorkflowAware {
// String getInputResultName();
// }
if (action instanceof ValidationWorkflowAware) {
resultName = ((ValidationWorkflowAware) action).getInputResultName();
}
// 这里不做讲述
InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig. class );
if (annotation != null ) {
if ( ! annotation.methodName().equals( "" )) {
Method method = action.getClass().getMethod(annotation.methodName());
resultName = (String) method.invoke(action);
} else {
resultName = annotation.resultName();
}
}
return resultName;
}
}
return invocation.invoke();
}
}
大家看到上面是不是已经恍然大悟了,呵呵,是的我们实现了ValidationWorkflowAware接口之后,只需要定义一个inputResultName属性生成了对应的get、set方法是不是就对应有了getInputResultName,而这个属性的值我们可以动态传入一个值进来,呵呵,大家看下面这个实例。
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import java.lang.reflect.Method;
public class DefaultWorkflowInterceptor extends MethodFilterInterceptor {
private static final long serialVersionUID = 7563014655616490865L ;
private static final Logger LOG = LoggerFactory.getLogger(DefaultWorkflowInterceptor. class );
private static final Class[] EMPTY_CLASS_ARRAY = new Class[ 0 ];
// 默认返回input视图,是在这里定义的
private String inputResultName = Action.INPUT;
// 可以在这里更改,一般没有人会这么做
public void setInputResultName(String inputResultName) {
this .inputResultName = inputResultName;
}
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware validationAwareAction = (ValidationAware) action;
if (validationAwareAction.hasErrors()) {
if (LOG.isDebugEnabled()) {
LOG.debug( " Errors on action " + validationAwareAction + " , returning result name 'input' " );
}
// one
String resultName = inputResultName;
/*
在这里大家读一下源码即可明白,当前处理的Action如果是一个ValidationWorkflowAware类型的,
则调用他的getInputResultName作用返回值
为了方便我直接把ValidationWorkflowAware放在下面的注释中,大家看他是一个接口,
也就是说如果我们的Action实现了ValidationWorkflowAware接口
他则会调用getInputResultName方法返回的值,而非input,而默认的ActionSupport没有实现这个接口,我们需要手动实现
*/
// package com.opensymphony.xwork2.interceptor;
// public interface ValidationWorkflowAware {
// String getInputResultName();
// }
if (action instanceof ValidationWorkflowAware) {
resultName = ((ValidationWorkflowAware) action).getInputResultName();
}
// 这里不做讲述
InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), EMPTY_CLASS_ARRAY).getAnnotation(InputConfig. class );
if (annotation != null ) {
if ( ! annotation.methodName().equals( "" )) {
Method method = action.getClass().getMethod(annotation.methodName());
resultName = (String) method.invoke(action);
} else {
resultName = annotation.resultName();
}
}
return resultName;
}
}
return invocation.invoke();
}
}
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
public abstract class ActionSupport extends
com.opensymphony.xwork2.ActionSupport implements Result,
ValidationWorkflowAware {
private static final long serialVersionUID = 799075559195465128L ;
public static final int ERROR_MSG = - 1 ;
public static final int WARN_MSG = 0 ;
public static final int SUCCESS_MSG = 1 ;
public static long getSerialversionuid() {
return serialVersionUID;
}
private ActionContext actionContext;
private Object id;
private Pagination pagn = new Pagination();
private QueryResult <?> results;
private String inputResultName;
/**
* 初始化ActionContext对象
*/
public ActionSupport() {
actionContext = ActionContext.getContext();
}
/**
*
* @return ActionContext对象
*/
public ActionContext getActionContext() {
return actionContext;
}
/**
*
* @return Struts封装后的ServletContext对象。
*/
public Map < String, Object > getApplication() {
return actionContext.getApplication();
}
/**
*
* @return 取得标识。
*/
public Object getId() {
return id;
}
/**
* 取得指定类型的标识。
*
* @param <E>
* @param c
* @return
*/
@SuppressWarnings( " unchecked " )
public < E > E getId(Class < E > c) {
return (E) id;
}
/**
*
* @return 输出对象。
* @throws IOException
*/
public PrintWriter getOut() throws IOException {
return getResponse().getWriter();
}
/**
*
* @return 分页参数对象。
*/
public Pagination getPagn() {
return pagn;
}
/**
*
* @return HttpServletRequest对象。
*/
public HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
/**
*
* @return HttpServletResponse对象。
*/
public HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
/**
*
* @return 查询结果集。
*/
public QueryResult <?> getResults() {
return results;
}
/**
*
* @return ServletContext对象。
*/
public ServletContext getServletContext() {
return (ServletContext) this .actionContext
.get(StrutsStatics.SERVLET_CONTEXT);
}
/**
*
* @return Struts封装后的HttpSession对象。
*/
public Map < String, Object > getSession() {
return actionContext.getSession();
}
/**
*
* @return Struts的ValueStack对象。
*/
public ValueStack getValueStack() {
return ServletActionContext.getValueStack(getRequest());
}
/**
* 向ActionContext中添加一个信息,此信息会保存到HttpServletRequest中。
*
* @param key
* 键。
* @param value
* 值。
*/
public void put(String key, Object value) {
actionContext.put(key, value);
}
public void setActionContext(ActionContext actionContext) {
this .actionContext = actionContext;
}
/**
*
* @param id
* 设置标识。
*/
public void setId(Object id) {
this .id = id;
}
/**
*
* @param pagn
* 设置分页参数对象。
*/
public void setPagn(Pagination pagn) {
this .pagn = pagn;
}
/**
*
* @param results
* 设置返回的结果集。
*/
protected void setResults(QueryResult <?> results) {
this .results = results;
}
public String getInputResultName() {
return inputResultName;
}
public void setInputResultName(String inputResultName) {
this .inputResultName = inputResultName;
}
public abstract String show() throws Exception;
public abstract String edit() throws EditFailureException;
public abstract String destroy() throws DestroyFailureException;
public abstract String create() throws CreateFailureException;
public abstract String deleteConfirm() throws DeleteFailureException;
public abstract String index() throws Exception;
public abstract String update() throws UpdateFailureException;
public abstract String editNew() throws EditFailureException;
}
上面是我自定义一个ActionSupport类,该类实现了ValidationWorkflowAware,并重写了getInputResultName方法。然后我再定义一个Action继承了该类。
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
public abstract class ActionSupport extends
com.opensymphony.xwork2.ActionSupport implements Result,
ValidationWorkflowAware {
private static final long serialVersionUID = 799075559195465128L ;
public static final int ERROR_MSG = - 1 ;
public static final int WARN_MSG = 0 ;
public static final int SUCCESS_MSG = 1 ;
public static long getSerialversionuid() {
return serialVersionUID;
}
private ActionContext actionContext;
private Object id;
private Pagination pagn = new Pagination();
private QueryResult <?> results;
private String inputResultName;
/**
* 初始化ActionContext对象
*/
public ActionSupport() {
actionContext = ActionContext.getContext();
}
/**
*
* @return ActionContext对象
*/
public ActionContext getActionContext() {
return actionContext;
}
/**
*
* @return Struts封装后的ServletContext对象。
*/
public Map < String, Object > getApplication() {
return actionContext.getApplication();
}
/**
*
* @return 取得标识。
*/
public Object getId() {
return id;
}
/**
* 取得指定类型的标识。
*
* @param <E>
* @param c
* @return
*/
@SuppressWarnings( " unchecked " )
public < E > E getId(Class < E > c) {
return (E) id;
}
/**
*
* @return 输出对象。
* @throws IOException
*/
public PrintWriter getOut() throws IOException {
return getResponse().getWriter();
}
/**
*
* @return 分页参数对象。
*/
public Pagination getPagn() {
return pagn;
}
/**
*
* @return HttpServletRequest对象。
*/
public HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
/**
*
* @return HttpServletResponse对象。
*/
public HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
/**
*
* @return 查询结果集。
*/
public QueryResult <?> getResults() {
return results;
}
/**
*
* @return ServletContext对象。
*/
public ServletContext getServletContext() {
return (ServletContext) this .actionContext
.get(StrutsStatics.SERVLET_CONTEXT);
}
/**
*
* @return Struts封装后的HttpSession对象。
*/
public Map < String, Object > getSession() {
return actionContext.getSession();
}
/**
*
* @return Struts的ValueStack对象。
*/
public ValueStack getValueStack() {
return ServletActionContext.getValueStack(getRequest());
}
/**
* 向ActionContext中添加一个信息,此信息会保存到HttpServletRequest中。
*
* @param key
* 键。
* @param value
* 值。
*/
public void put(String key, Object value) {
actionContext.put(key, value);
}
public void setActionContext(ActionContext actionContext) {
this .actionContext = actionContext;
}
/**
*
* @param id
* 设置标识。
*/
public void setId(Object id) {
this .id = id;
}
/**
*
* @param pagn
* 设置分页参数对象。
*/
public void setPagn(Pagination pagn) {
this .pagn = pagn;
}
/**
*
* @param results
* 设置返回的结果集。
*/
protected void setResults(QueryResult <?> results) {
this .results = results;
}
public String getInputResultName() {
return inputResultName;
}
public void setInputResultName(String inputResultName) {
this .inputResultName = inputResultName;
}
public abstract String show() throws Exception;
public abstract String edit() throws EditFailureException;
public abstract String destroy() throws DestroyFailureException;
public abstract String create() throws CreateFailureException;
public abstract String deleteConfirm() throws DeleteFailureException;
public abstract String index() throws Exception;
public abstract String update() throws UpdateFailureException;
public abstract String editNew() throws EditFailureException;
}
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> @Namespace(value = " /test " )
@Action(params = { " actionName " , " demo " })
@Results( {
@Result(name = " xx " , type = " redirect " , location = " http://www.google.com " ),
@Result(name = " hello " , type = " redirect " , location = " http://www.baidu.com " ) })
@SuppressWarnings( " serial " )
public class DownloadController extends ActionSupport {
public String index() {
System.out.println( " -------index----------- " );
return " xx " ;
}
public void validateIndex() {
addFieldError( " hell " , " .my hello. " );
System.out.println( " ok " );
}
// ..省略了其它无关方法
}
在上面我就只是做了一个简单了模拟验证然后跳转到指定的页面。这里你可以这样请求,测试一个最终struts2是否调用了getInputResultName方法并使用其返回值,作为返回视图的名称:http://地址:端口/project/test/demo!index.action?inputResultName=hello,大家测试如果跳转到了baidu就说明成功了。
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> @Namespace(value = " /test " )
@Action(params = { " actionName " , " demo " })
@Results( {
@Result(name = " xx " , type = " redirect " , location = " http://www.google.com " ),
@Result(name = " hello " , type = " redirect " , location = " http://www.baidu.com " ) })
@SuppressWarnings( " serial " )
public class DownloadController extends ActionSupport {
public String index() {
System.out.println( " -------index----------- " );
return " xx " ;
}
public void validateIndex() {
addFieldError( " hell " , " .my hello. " );
System.out.println( " ok " );
}
// ..省略了其它无关方法
}
至此,有问题可以留言。
转载地址,onlyeffort.QQ:501276913 http://www.blogjava.net/grasszring/archive/2010/06/08/323092.html
本文详细解析struts2验证原理及解决验证返回input视图的方法,包括通过实现ValidationWorkflowAware接口动态设置返回视图名称,提供实例演示。
651

被折叠的 条评论
为什么被折叠?



