當(dāng)然如果你是使用一個(gè)方法對(duì)一個(gè)類,則不存在上面的問題,當(dāng)然一個(gè)方法對(duì)應(yīng)一個(gè)類,這種方式雖然可讀性很高但是實(shí)際開發(fā)確實(shí)不可取,因?yàn)樗麜?huì)使類極具增加。如果你是使用一個(gè)類對(duì)應(yīng)多個(gè)方法,你肯定碰到過這樣一個(gè)問題,那就是驗(yàn)證時(shí)返回input視圖,struts2默認(rèn)驗(yàn)證失敗返回input視圖,但是我們?cè)趯懗绦蛑薪?jīng)常會(huì)有多個(gè)方法需要驗(yàn)證,打個(gè)比方如:create、update這兩個(gè)操作一般情況下都會(huì)驗(yàn)證,但是我們把它寫在一個(gè)類中,我們?nèi)绻麉^(qū)分驗(yàn)證失敗后,到底是create失敗了還是update失敗了呢?這個(gè)時(shí)候有沒有懷疑過struts2,呵呵。
當(dāng)然struts2其時(shí)已經(jīng)給了我們解決辦法,如果你是一個(gè)細(xì)心的人讀過struts2源碼便過發(fā)現(xiàn)struts2是如何解決問題的,在這里我也簡(jiǎn)單的分析一下struts2的源碼,大家請(qǐng)看下面這個(gè)類。
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];
//默認(rèn)返回input視圖,是在這里定義的
private String inputResultName = Action.INPUT;
//可以在這里更改,一般沒有人會(huì)這么做
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;
/*
在這里大家讀一下源碼即可明白,當(dāng)前處理的Action如果是一個(gè)ValidationWorkflowAware類型的,
則調(diào)用他的getInputResultName作用返回值
為了方便我直接把ValidationWorkflowAware放在下面的注釋中,大家看他是一個(gè)接口,
也就是說如果我們的Action實(shí)現(xiàn)了ValidationWorkflowAware接口
他則會(huì)調(diào)用getInputResultName方法返回的值,而非input,而默認(rèn)的ActionSupport沒有實(shí)現(xiàn)這個(gè)接口,我們需要手動(dòng)實(shí)現(xiàn)
*/
//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();
}
}
大家看到上面是不是已經(jīng)恍然大悟了,呵呵,是的我們實(shí)現(xiàn)了ValidationWorkflowAware接口之后,只需要定義一個(gè)inputResultName屬性生成了對(duì)應(yīng)的get、set方法是不是就對(duì)應(yīng)有了getInputResultName,而這個(gè)屬性的值我們可以動(dòng)態(tài)傳入一個(gè)值進(jìn)來,呵呵,大家看下面這個(gè)實(shí)例。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];
//默認(rèn)返回input視圖,是在這里定義的
private String inputResultName = Action.INPUT;
//可以在這里更改,一般沒有人會(huì)這么做
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;
/*
在這里大家讀一下源碼即可明白,當(dāng)前處理的Action如果是一個(gè)ValidationWorkflowAware類型的,
則調(diào)用他的getInputResultName作用返回值
為了方便我直接把ValidationWorkflowAware放在下面的注釋中,大家看他是一個(gè)接口,
也就是說如果我們的Action實(shí)現(xiàn)了ValidationWorkflowAware接口
他則會(huì)調(diào)用getInputResultName方法返回的值,而非input,而默認(rèn)的ActionSupport沒有實(shí)現(xiàn)這個(gè)接口,我們需要手動(dòng)實(shí)現(xiàn)
*/
//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();
}
}
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對(duì)象
*/
public ActionSupport() {
actionContext = ActionContext.getContext();
}
/**
*
* @return ActionContext對(duì)象
*/
public ActionContext getActionContext() {
return actionContext;
}
/**
*
* @return Struts封裝后的ServletContext對(duì)象。
*/
public Map<String, Object> getApplication() {
return actionContext.getApplication();
}
/**
*
* @return 取得標(biāo)識(shí)。
*/
public Object getId() {
return id;
}
/**
* 取得指定類型的標(biāo)識(shí)。
*
* @param <E>
* @param c
* @return
*/
@SuppressWarnings("unchecked")
public <E> E getId(Class<E> c) {
return (E) id;
}
/**
*
* @return 輸出對(duì)象。
* @throws IOException
*/
public PrintWriter getOut() throws IOException {
return getResponse().getWriter();
}
/**
*
* @return 分頁參數(shù)對(duì)象。
*/
public Pagination getPagn() {
return pagn;
}
/**
*
* @return HttpServletRequest對(duì)象。
*/
public HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
/**
*
* @return HttpServletResponse對(duì)象。
*/
public HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
/**
*
* @return 查詢結(jié)果集。
*/
public QueryResult<?> getResults() {
return results;
}
/**
*
* @return ServletContext對(duì)象。
*/
public ServletContext getServletContext() {
return (ServletContext) this.actionContext
.get(StrutsStatics.SERVLET_CONTEXT);
}
/**
*
* @return Struts封裝后的HttpSession對(duì)象。
*/
public Map<String, Object> getSession() {
return actionContext.getSession();
}
/**
*
* @return Struts的ValueStack對(duì)象。
*/
public ValueStack getValueStack() {
return ServletActionContext.getValueStack(getRequest());
}
/**
* 向ActionContext中添加一個(gè)信息,此信息會(huì)保存到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
* 設(shè)置標(biāo)識(shí)。
*/
public void setId(Object id) {
this.id = id;
}
/**
*
* @param pagn
* 設(shè)置分頁參數(shù)對(duì)象。
*/
public void setPagn(Pagination pagn) {
this.pagn = pagn;
}
/**
*
* @param results
* 設(shè)置返回的結(jié)果集。
*/
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;
}
@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");
}
//..省略了其它無關(guān)方法
}
在上面我就只是做了一個(gè)簡(jiǎn)單了模擬驗(yàn)證然后跳轉(zhuǎn)到指定的頁面。這里你可以這樣請(qǐng)求,測(cè)試一個(gè)最終struts2是否調(diào)用了getInputResultName方法并使用其返回值,作為返回視圖的名稱:http://地址:端口/project/test/demo!index.action?inputResultName=hello,大家測(cè)試如果跳轉(zhuǎn)到了baidu就說明成功了。@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");
}
//..省略了其它無關(guān)方法
}
至此,有問題可以留言。
轉(zhuǎn)載時(shí)請(qǐng)注明轉(zhuǎn)載地址,onlyeffort.QQ:501276913