Struts2 chain类型不能 跳转DMI型式路径

其实就是复制了 com.opensymphony.xwork2.ActionChainResult再在execute里进行了些判断,达到了我项目的需求

可以正确跳转actionName!method这种DMI型式的路径
可以带参数跳转


package com.common.base.struts2.interceptor;


import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.XWorkException;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;

/**
*
* 重写了默认的chain拦截器com.opensymphony.xwork2.ActionChainResult
* 可以正确跳转actionName!method这种DMI型式的路径
* 可以带参数跳转
* 使用:
* <struts>
<package ...
<result-types>
<result-type name="chain" class="com.common.base.struts2.interceptor.ActionChainResult"></result-type>
</result-types>
<result type="chain">...</result>
</package>
* </struts>
* @author Administrator
*
*/
public class ActionChainResult implements Result {

private static final Logger LOG = LoggerFactory.getLogger(ActionChainResult.class);

/**
* The result parameter name to set the name of the action to chain to.
*/
public static final String DEFAULT_PARAM = "actionName";

/**
* The action context key to save the chain history.
*/
private static final String CHAIN_HISTORY = "CHAIN_HISTORY";

/**
* The result parameter name to set the name of the action to chain to.
*/
public static final String SKIP_ACTIONS_PARAM = "skipActions";


private ActionProxy proxy;
private String actionName;

private String namespace;

private String methodName;

/**
* The list of actions to skip.
*/
private String skipActions;

private ActionProxyFactory actionProxyFactory;

public ActionChainResult() {
super();
}

public ActionChainResult(String namespace, String actionName, String methodName) {
this.namespace = namespace;
this.actionName = actionName;
this.methodName = methodName;
}

public ActionChainResult(String namespace, String actionName, String methodName, String skipActions) {
this.namespace = namespace;
this.actionName = actionName;
this.methodName = methodName;
this.skipActions = skipActions;
}


/**
* @param actionProxyFactory the actionProxyFactory to set
*/
@Inject
public void setActionProxyFactory(ActionProxyFactory actionProxyFactory) {
this.actionProxyFactory = actionProxyFactory;
}

/**
* Set the action name.
*
* @param actionName The action name.
*/
public void setActionName(String actionName) {
this.actionName = actionName;
}

/**
* sets the namespace of the Action that we're chaining to. if namespace
* is null, this defaults to the current namespace.
*
* @param namespace the name of the namespace we're chaining to
*/
public void setNamespace(String namespace) {
this.namespace = namespace;
}

/**
* Set the list of actions to skip.
* To test if an action should not throe an infinite recursion,
* only the action name is used, not the namespace.
*
* @param actions The list of action name separated by a white space.
*/
public void setSkipActions(String actions) {
this.skipActions = actions;
}


public void setMethod(String method) {
this.methodName = method;
}

public ActionProxy getProxy() {
return proxy;
}

/**
* Get the XWork chain history.
* The stack is a list of <code>namespace/action!method</code> keys.
*/
public static LinkedList getChainHistory() {
LinkedList chainHistory = (LinkedList) ActionContext.getContext().get(CHAIN_HISTORY);
// Add if not exists
if (chainHistory == null) {
chainHistory = new LinkedList();
ActionContext.getContext().put(CHAIN_HISTORY, chainHistory);
}

return chainHistory;
}

/**
* @param invocation the DefaultActionInvocation calling the action call stack
*/
public void execute(ActionInvocation invocation) throws Exception {
// if the finalNamespace wasn't explicitly defined, assume the current one
if (this.namespace == null) {
this.namespace = invocation.getProxy().getNamespace();
}

ValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(namespace, stack);
String finalActionName = TextParseUtil.translateVariables(actionName, stack);
String finalMethodName=null;
int index=-1;
//项目中用到的跳转前缀
if(!finalActionName.startsWith("dispatcher.")&&!finalActionName.startsWith("redirect.")){
index=finalActionName.indexOf('!');
}

if(index!=-1){
finalMethodName=finalActionName.substring(index+1);
finalActionName=finalActionName.substring(0,index);
}else{
finalMethodName = this.methodName != null
? TextParseUtil.translateVariables(this.methodName, stack)
: null;
}
index=finalMethodName!=null?finalMethodName.indexOf('?'):-1;
String paramStr=null;
if(index!=-1){
paramStr=finalMethodName.substring(index+1);
finalMethodName=finalMethodName.substring(0,index);
}

Map paramMap=ActionContext.getContext().getParameters();
if(paramStr!=null){
String [] params=paramStr.split("&");
for(String temp:params){
index=temp.indexOf('=');
paramMap.put(temp.substring(0,index), temp.substring(index+1));
}
}

if (isInChainHistory(finalNamespace, finalActionName, finalMethodName)) {
addToHistory(finalNamespace, finalActionName, finalMethodName);
throw new XWorkException("Infinite recursion detected: "
+ ActionChainResult.getChainHistory().toString());
}

if (ActionChainResult.getChainHistory().isEmpty() && invocation != null && invocation.getProxy() != null) {
addToHistory(finalNamespace, invocation.getProxy().getActionName(), invocation.getProxy().getMethod());
}
addToHistory(finalNamespace, finalActionName, finalMethodName);


HashMap extraContext = new HashMap();
extraContext.put(ActionContext.VALUE_STACK, ActionContext.getContext().getValueStack());
extraContext.put(ActionContext.PARAMETERS,paramMap);
extraContext.put(CHAIN_HISTORY, ActionChainResult.getChainHistory());

if (LOG.isDebugEnabled()) {
LOG.debug("Chaining to action " + finalActionName);
}

proxy = actionProxyFactory.createActionProxy(finalNamespace, finalActionName, finalMethodName, extraContext);
proxy.execute();
}

public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

final ActionChainResult that = (ActionChainResult) o;

if (actionName != null ? !actionName.equals(that.actionName) : that.actionName != null) return false;
if (methodName != null ? !methodName.equals(that.methodName) : that.methodName != null) return false;
if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) return false;

return true;
}

public int hashCode() {
int result;
result = (actionName != null ? actionName.hashCode() : 0);
result = 31 * result + (namespace != null ? namespace.hashCode() : 0);
result = 31 * result + (methodName != null ? methodName.hashCode() : 0);
return result;
}

private boolean isInChainHistory(String namespace, String actionName, String methodName) {
LinkedList chainHistory = ActionChainResult.getChainHistory();

if (chainHistory == null) {
return false;
} else {
// Actions to skip
Set skipActionsList = new HashSet();
if (skipActions != null && skipActions.length() > 0) {
ValueStack stack = ActionContext.getContext().getValueStack();
String finalSkipActions = TextParseUtil.translateVariables(this.skipActions, stack);
skipActionsList.addAll(TextParseUtil.commaDelimitedStringToSet(finalSkipActions));
}
if (!skipActionsList.contains(actionName)) {
// Get if key is in the chain history
return chainHistory.contains(makeKey(namespace, actionName, methodName));
}

return false;
}
}

private void addToHistory(String namespace, String actionName, String methodName) {
LinkedList chainHistory = ActionChainResult.getChainHistory();
chainHistory.add(makeKey(namespace, actionName, methodName));
}

private String makeKey(String namespace, String actionName, String methodName) {
if (null == methodName) {
return namespace + "/" + actionName;
}

return namespace + "/" + actionName + "!" + methodName;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值