在这里我不说struts2的验证原理以及语法,我只讲一下关于struts2验证返回input视图的解决办法。
当然如果你是使用一个方法对一个类,则不存在上面的问题,当然一个方法对应一个类,这种方式虽然可读性很高但是实际开发确实不可取,因为他会使类极具增加。如果你是使用一个类对应多个方法,你肯定碰到过这样一个问题,那就是验证时返回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/ --> 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/ -->@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就说明成功了。
至此,有问题可以留言。
转载地址,onlyeffort.QQ:501276913 http://www.blogjava.net/grasszring/archive/2010/06/08/323092.html