mirror of
https://github.com/apache/struts.git
synced 2026-08-08 08:07:17 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0f4e9ece7 | |||
| 45580718ab | |||
| 87f113ebb2 | |||
| 0023d9664b | |||
| ee27b6604a | |||
| 7f80ef1bb5 | |||
| 253799c6c5 | |||
| 20c54df03a | |||
| ff8d731594 | |||
| 880c4c2d33 | |||
| d12bb7cddb | |||
| f48c9620fc | |||
| fc6ffba9cf | |||
| 08e181a4fe | |||
| a7f4e255b0 | |||
| 2b12f06b01 | |||
| b9c05a7181 | |||
| 14d56fbb93 | |||
| 97419283ea | |||
| 55fed53764 | |||
| 98979423a1 | |||
| 3144b6c995 | |||
| 3ce21403ee | |||
| e38a71365a | |||
| f78d90ee22 | |||
| 7e4d1b45ea | |||
| 4727265e59 | |||
| 4281e31864 | |||
| baffa9a68b | |||
| 484ce1d191 |
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
|
||||
+2
-8
@@ -24,23 +24,17 @@ package org.apache.struts2.showcase.chat;
|
||||
import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.struts2.dispatcher.SessionMap;
|
||||
|
||||
public class ChatAuthenticationInterceptor implements Interceptor {
|
||||
public class ChatAuthenticationInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LogManager.getLogger(ChatAuthenticationInterceptor.class);
|
||||
public static final String USER_SESSION_KEY = "chatUserSessionKey";
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
|
||||
LOG.debug("Authenticating chat user");
|
||||
|
||||
@@ -23,7 +23,7 @@ package org.apache.struts2.showcase.chat;
|
||||
import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
@@ -32,7 +32,7 @@ import javax.servlet.http.HttpSession;
|
||||
/**
|
||||
* Authenticate showcase chat example, make sure everyone have a username.
|
||||
*/
|
||||
public class ChatInterceptor implements Interceptor {
|
||||
public class ChatInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ChatInterceptor.class);
|
||||
|
||||
@@ -40,12 +40,6 @@ public class ChatInterceptor implements Interceptor {
|
||||
|
||||
public static final String CHAT_USER_SESSION_KEY = "ChatUserSessionKey";
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
HttpSession session = (HttpSession) ActionContext.getContext().get(ActionContext.SESSION);
|
||||
User chatUser = (User) session.getAttribute(CHAT_USER_SESSION_KEY);
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -25,7 +25,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>2.5.7</struts-version.version>
|
||||
<struts-version.version>2.5.10</struts-version.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -172,6 +172,6 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<tag>STRUTS_2_5_7</tag>
|
||||
<tag>STRUTS_2_5_10</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -19,21 +19,16 @@ import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.ValidationAware;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Provides a default implementation for the most common actions.
|
||||
* See the documentation for all the interfaces this class implements for more detailed information.
|
||||
*/
|
||||
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
|
||||
|
||||
protected static Logger LOG = LogManager.getLogger(ActionSupport.class);
|
||||
|
||||
private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
|
||||
|
||||
private transient TextProvider textProvider;
|
||||
|
||||
@@ -21,7 +21,9 @@ import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.PreResultListener;
|
||||
import com.opensymphony.xwork2.interceptor.WithLazyParams;
|
||||
import com.opensymphony.xwork2.ognl.OgnlUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
@@ -67,6 +69,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
protected Container container;
|
||||
protected UnknownHandlerManager unknownHandlerManager;
|
||||
protected OgnlUtil ognlUtil;
|
||||
protected WithLazyParams.LazyParamInjector lazyParamInjector;
|
||||
|
||||
public DefaultActionInvocation(final Map<String, Object> extraContext, final boolean pushAction) {
|
||||
this.extraContext = extraContext;
|
||||
@@ -233,11 +236,15 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
}
|
||||
|
||||
if (interceptors.hasNext()) {
|
||||
final InterceptorMapping interceptor = interceptors.next();
|
||||
String interceptorMsg = "interceptor: " + interceptor.getName();
|
||||
final InterceptorMapping interceptorMapping = interceptors.next();
|
||||
String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
|
||||
UtilTimerStack.push(interceptorMsg);
|
||||
try {
|
||||
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
|
||||
Interceptor interceptor = interceptorMapping.getInterceptor();
|
||||
if (interceptor instanceof WithLazyParams) {
|
||||
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
|
||||
}
|
||||
resultCode = interceptor.intercept(DefaultActionInvocation.this);
|
||||
} finally {
|
||||
UtilTimerStack.pop(interceptorMsg);
|
||||
}
|
||||
@@ -400,6 +407,13 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
invocationContext.setName(proxy.getActionName());
|
||||
|
||||
createInterceptors(proxy);
|
||||
|
||||
prepareLazyParamInjector(invocationContext.getValueStack());
|
||||
}
|
||||
|
||||
protected void prepareLazyParamInjector(ValueStack valueStack) {
|
||||
lazyParamInjector = new WithLazyParams.LazyParamInjector(valueStack);
|
||||
container.inject(lazyParamInjector);
|
||||
}
|
||||
|
||||
protected void createInterceptors(ActionProxy proxy) {
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.opensymphony.xwork2.config.entities;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <code>InterceptorMapping</code>
|
||||
@@ -30,10 +32,16 @@ public class InterceptorMapping implements Serializable {
|
||||
|
||||
private String name;
|
||||
private Interceptor interceptor;
|
||||
private final Map<String, String> params;
|
||||
|
||||
public InterceptorMapping(String name, Interceptor interceptor) {
|
||||
this(name, interceptor, new HashMap<String, String>());
|
||||
}
|
||||
|
||||
public InterceptorMapping(String name, Interceptor interceptor, Map<String, String> params) {
|
||||
this.name = name;
|
||||
this.interceptor = interceptor;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -44,6 +52,10 @@ public class InterceptorMapping implements Serializable {
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
public Map<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -65,7 +77,7 @@ public class InterceptorMapping implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InterceptorMapping: [" + name + "] => [" + interceptor.getClass().getName() + ']';
|
||||
return "InterceptorMapping: [" + name + "] => [" + interceptor.getClass().getName() + "] with params [" + params + "]" ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.util.location.Location;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.message.ParameterizedMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -43,7 +44,6 @@ public class InterceptorBuilder {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(InterceptorBuilder.class);
|
||||
|
||||
|
||||
/**
|
||||
* Builds a list of interceptors referenced by the refName in the supplied PackageConfig (InterceptorMapping object).
|
||||
*
|
||||
@@ -67,13 +67,11 @@ public class InterceptorBuilder {
|
||||
InterceptorConfig config = (InterceptorConfig) referencedConfig;
|
||||
Interceptor inter;
|
||||
try {
|
||||
|
||||
inter = objectFactory.buildInterceptor(config, refParams);
|
||||
result.add(new InterceptorMapping(refName, inter));
|
||||
result.add(new InterceptorMapping(refName, inter, refParams));
|
||||
} catch (ConfigurationException ex) {
|
||||
LOG.warn("Unable to load config class {} at {} probably due to a missing jar, which might be fine if you never plan to use the {} interceptor",
|
||||
config.getClassName(), ex.getLocation(), config.getName());
|
||||
LOG.error("Unable to load config class {}", config.getClassName(), ex);
|
||||
LOG.warn(new ParameterizedMessage("Unable to load config class {} at {} probably due to a missing jar, which might be fine if you never plan to use the {} interceptor",
|
||||
config.getClassName(), ex.getLocation(), config.getName()), ex);
|
||||
}
|
||||
|
||||
} else if (referencedConfig instanceof InterceptorStackConfig) {
|
||||
|
||||
+2
-2
@@ -757,7 +757,7 @@ public class XmlConfigurationProvider implements ConfigurationProvider {
|
||||
{
|
||||
// if <result ...>something</result> then we add a parameter of 'something' as this is the most used result param
|
||||
if (resultElement.getChildNodes().getLength() >= 1) {
|
||||
resultParams = new LinkedHashMap<String, String>();
|
||||
resultParams = new LinkedHashMap<>();
|
||||
|
||||
String paramName = config.getDefaultResultParam();
|
||||
if (paramName != null) {
|
||||
@@ -775,7 +775,7 @@ public class XmlConfigurationProvider implements ConfigurationProvider {
|
||||
resultParams.put(paramName, val);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("No default parameter defined for result [{}] of type [{}] ", config.getName(), config.getClassName());
|
||||
LOG.debug("No default parameter defined for result [{}] of type [{}] ", config.getName(), config.getClassName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorConfig;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.WithLazyParams;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -15,6 +18,8 @@ import java.util.Map;
|
||||
*/
|
||||
public class DefaultInterceptorFactory implements InterceptorFactory {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(DefaultInterceptorFactory.class);
|
||||
|
||||
private ObjectFactory objectFactory;
|
||||
private ReflectionProvider reflectionProvider;
|
||||
|
||||
@@ -40,7 +45,12 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
|
||||
try {
|
||||
// interceptor instances are long-lived and used across user sessions, so don't try to pass in any extra context
|
||||
Object o = objectFactory.buildBean(interceptorClassName, null);
|
||||
reflectionProvider.setProperties(params, o);
|
||||
if (o instanceof WithLazyParams) {
|
||||
LOG.debug("Interceptor {} is marked with interface {} and params will be set during action invocation",
|
||||
interceptorClassName, WithLazyParams.class.getName());
|
||||
} else {
|
||||
reflectionProvider.setProperties(params, o);
|
||||
}
|
||||
|
||||
if (o instanceof Interceptor) {
|
||||
Interceptor interceptor = (Interceptor) o;
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class ExceptionMappingInterceptor extends AbstractInterceptor {
|
||||
|
||||
protected static final Logger LOG = LogManager.getLogger(ExceptionMappingInterceptor.class);
|
||||
private static final Logger LOG = LogManager.getLogger(ExceptionMappingInterceptor.class);
|
||||
|
||||
protected Logger categoryLogger;
|
||||
protected boolean logEnabled = false;
|
||||
|
||||
@@ -70,7 +70,8 @@ import java.util.Set;
|
||||
* @see com.opensymphony.xwork2.validator.ValidationInterceptor
|
||||
*/
|
||||
public abstract class MethodFilterInterceptor extends AbstractInterceptor {
|
||||
protected transient Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(MethodFilterInterceptor.class);
|
||||
|
||||
protected Set<String> excludeMethods = Collections.emptySet();
|
||||
protected Set<String> includeMethods = Collections.emptySet();
|
||||
@@ -104,7 +105,7 @@ public abstract class MethodFilterInterceptor extends AbstractInterceptor {
|
||||
// ValidationInterceptor
|
||||
boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, method);
|
||||
if (!applyMethod) {
|
||||
log.debug("Skipping Interceptor... Method [{}] found in exclude list.", method);
|
||||
LOG.debug("Skipping Interceptor... Method [{}] found in exclude list.", method);
|
||||
}
|
||||
return applyMethod;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,8 @@ import org.apache.logging.log4j.Logger;
|
||||
* @author Claus Ibsen
|
||||
*/
|
||||
public class TimerInterceptor extends AbstractInterceptor {
|
||||
protected static final Logger LOG = LogManager.getLogger(TimerInterceptor.class);
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(TimerInterceptor.class);
|
||||
|
||||
protected Logger categoryLogger;
|
||||
protected String logCategory;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.opensymphony.xwork2.interceptor;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.ognl.OgnlUtil;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.TextParser;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interceptors marked with this interface won't be fully initialised during initialisation.
|
||||
* Appropriated params will be injected just before usage of the interceptor.
|
||||
*
|
||||
* Please be aware that in such case {@link Interceptor#init()} method must be prepared for this.
|
||||
*
|
||||
* @since 2.5.9
|
||||
*/
|
||||
public interface WithLazyParams {
|
||||
|
||||
class LazyParamInjector {
|
||||
|
||||
protected OgnlUtil ognlUtil;
|
||||
protected TextParser textParser;
|
||||
protected ReflectionProvider reflectionProvider;
|
||||
|
||||
private final TextParseUtil.ParsedValueEvaluator valueEvaluator;
|
||||
|
||||
public LazyParamInjector(final ValueStack valueStack) {
|
||||
valueEvaluator = new TextParseUtil.ParsedValueEvaluator() {
|
||||
public Object evaluate(String parsedValue) {
|
||||
return valueStack.findValue(parsedValue); // no asType !!!
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setTextParser(TextParser textParser) {
|
||||
this.textParser = textParser;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setReflectionProvider(ReflectionProvider reflectionProvider) {
|
||||
this.reflectionProvider = reflectionProvider;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setOgnlUtil(OgnlUtil ognlUtil) {
|
||||
this.ognlUtil = ognlUtil;
|
||||
}
|
||||
|
||||
public Interceptor injectParams(Interceptor interceptor, Map<String, String> params, ActionContext invocationContext) {
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
Object paramValue = textParser.evaluate(new char[]{ '$' }, entry.getValue(), valueEvaluator, TextParser.DEFAULT_LOOP_COUNT);
|
||||
ognlUtil.setProperty(entry.getKey(), paramValue, interceptor, invocationContext.getContextMap());
|
||||
}
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,15 @@
|
||||
package com.opensymphony.xwork2.mock;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.junit.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Mock for an {@link com.opensymphony.xwork2.interceptor.Interceptor}.
|
||||
*
|
||||
* @author Jason Carreira
|
||||
*/
|
||||
public class MockInterceptor implements Interceptor {
|
||||
public class MockInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final long serialVersionUID = 2692551676567227756L;
|
||||
|
||||
@@ -57,12 +56,6 @@ public class MockInterceptor implements Interceptor {
|
||||
return foo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to let an interceptor clean up any resources it has allocated.
|
||||
*/
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -101,13 +94,6 @@ public class MockInterceptor implements Interceptor {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after an Interceptor is created, but before any requests are processed using the intercept() methodName. This
|
||||
* gives the Interceptor a chance to initialize any needed resources.
|
||||
*/
|
||||
public void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
|
||||
* request by the DefaultActionInvocation or to short-circuit the processing and just return a String return code.
|
||||
|
||||
@@ -52,19 +52,20 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
|
||||
public static final String THROW_EXCEPTION_ON_FAILURE = OgnlValueStack.class.getName() + ".throwExceptionOnFailure";
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(OgnlValueStack.class);
|
||||
|
||||
private static final long serialVersionUID = 370737852934925530L;
|
||||
|
||||
private static final String MAP_IDENTIFIER_KEY = "com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY";
|
||||
private static final Logger LOG = LogManager.getLogger(OgnlValueStack.class);
|
||||
|
||||
CompoundRoot root;
|
||||
transient Map<String, Object> context;
|
||||
Class defaultType;
|
||||
Map<Object, Object> overrides;
|
||||
transient OgnlUtil ognlUtil;
|
||||
transient SecurityMemberAccess securityMemberAccess;
|
||||
protected CompoundRoot root;
|
||||
protected transient Map<String, Object> context;
|
||||
protected Class defaultType;
|
||||
protected Map<Object, Object> overrides;
|
||||
protected transient OgnlUtil ognlUtil;
|
||||
protected transient SecurityMemberAccess securityMemberAccess;
|
||||
|
||||
private transient XWorkConverter converter;
|
||||
|
||||
private boolean devMode;
|
||||
private boolean logMissingProperties;
|
||||
|
||||
@@ -189,7 +190,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
context.remove(REPORT_ERRORS_ON_NO_PROP);
|
||||
}
|
||||
|
||||
private void handleRuntimeException(String expr, Object value, boolean throwExceptionOnFailure, RuntimeException re) {
|
||||
protected void handleRuntimeException(String expr, Object value, boolean throwExceptionOnFailure, RuntimeException re) {
|
||||
if (throwExceptionOnFailure) {
|
||||
String message = ErrorMessageBuilder.create()
|
||||
.errorSettingExpressionWithValue(expr, value)
|
||||
@@ -200,7 +201,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOgnlException(String expr, Object value, boolean throwExceptionOnFailure, OgnlException e) {
|
||||
protected void handleOgnlException(String expr, Object value, boolean throwExceptionOnFailure, OgnlException e) {
|
||||
boolean shouldLog = shouldLogMissingPropertyWarning(e);
|
||||
String msg = null;
|
||||
if (throwExceptionOnFailure || shouldLog) {
|
||||
@@ -242,7 +243,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
}
|
||||
}
|
||||
|
||||
private void setupExceptionOnFailure(boolean throwExceptionOnFailure) {
|
||||
protected void setupExceptionOnFailure(boolean throwExceptionOnFailure) {
|
||||
if (throwExceptionOnFailure) {
|
||||
context.put(THROW_EXCEPTION_ON_FAILURE, true);
|
||||
}
|
||||
@@ -255,7 +256,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
return tryFindValue(expr);
|
||||
}
|
||||
|
||||
private Object handleOtherException(String expr, boolean throwExceptionOnFailure, Exception e) {
|
||||
protected Object handleOtherException(String expr, boolean throwExceptionOnFailure, Exception e) {
|
||||
logLookupFailure(expr, e);
|
||||
|
||||
if (throwExceptionOnFailure)
|
||||
@@ -322,7 +323,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
return tryFindValue(expr, asType);
|
||||
}
|
||||
|
||||
private Object handleOgnlException(String expr, boolean throwExceptionOnFailure, OgnlException e) {
|
||||
protected Object handleOgnlException(String expr, boolean throwExceptionOnFailure, OgnlException e) {
|
||||
Object ret = findInContext(expr);
|
||||
if (ret == null) {
|
||||
if (shouldLogMissingPropertyWarning(e)) {
|
||||
@@ -335,7 +336,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean shouldLogMissingPropertyWarning(OgnlException e) {
|
||||
protected boolean shouldLogMissingPropertyWarning(OgnlException e) {
|
||||
return (e instanceof NoSuchPropertyException || e instanceof MethodFailedException)
|
||||
&& devMode && logMissingProperties;
|
||||
}
|
||||
@@ -359,7 +360,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
|
||||
return ognlUtil.getValue(expr, context, root, asType);
|
||||
}
|
||||
|
||||
private Object findInContext(String name) {
|
||||
protected Object findInContext(String name) {
|
||||
return getContext().get(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,11 +38,11 @@ import java.util.Set;
|
||||
*/
|
||||
public class OgnlValueStackFactory implements ValueStackFactory {
|
||||
|
||||
private XWorkConverter xworkConverter;
|
||||
private CompoundRootAccessor compoundRootAccessor;
|
||||
private TextProvider textProvider;
|
||||
private Container container;
|
||||
private boolean allowStaticMethodAccess;
|
||||
protected XWorkConverter xworkConverter;
|
||||
protected CompoundRootAccessor compoundRootAccessor;
|
||||
protected TextProvider textProvider;
|
||||
protected Container container;
|
||||
protected boolean allowStaticMethodAccess;
|
||||
|
||||
@Inject
|
||||
public void setXWorkConverter(XWorkConverter converter) {
|
||||
|
||||
@@ -53,6 +53,8 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
|
||||
@Override
|
||||
public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
|
||||
LOG.debug("Checking access for [target: {}, member: {}, property: {}] is deprecated!", target, member, propertyName);
|
||||
|
||||
if (checkEnumAccess(target, member)) {
|
||||
LOG.trace("Allowing access to enum: {}", target);
|
||||
return true;
|
||||
|
||||
@@ -20,12 +20,16 @@ package com.opensymphony.xwork2.util;
|
||||
import com.opensymphony.xwork2.XWorkException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Vector;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* This class is an utility class that will search through the classpath
|
||||
@@ -88,10 +92,24 @@ public class ClassPathFinder {
|
||||
} catch (URISyntaxException e) {
|
||||
continue;
|
||||
}
|
||||
File entry = new File(entryURI) ;
|
||||
Vector<String> results = checkEntries(entry.list(), entry, "");
|
||||
if (results != null ) {
|
||||
matches.addAll(results);
|
||||
File entry = new File(entryURI);
|
||||
if (entry.isFile() && entry.toString().endsWith(".jar")) {
|
||||
try {
|
||||
ZipInputStream zip = new ZipInputStream(new FileInputStream(entry));
|
||||
for (ZipEntry zipEntry = zip.getNextEntry(); zipEntry != null; zipEntry = zip.getNextEntry()) {
|
||||
boolean doesMatch = patternMatcher.match(new HashMap<String, String>(), zipEntry.getName(), compiledPattern);
|
||||
if (doesMatch) {
|
||||
matches.add(zipEntry.getName());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Vector<String> results = checkEntries(entry.list(), entry, "");
|
||||
if (results != null) {
|
||||
matches.addAll(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
|
||||
@@ -31,8 +31,6 @@ import java.util.*;
|
||||
*/
|
||||
public class TextParseUtil {
|
||||
|
||||
private static final int MAX_RECURSION = 1;
|
||||
|
||||
/**
|
||||
* Converts all instances of ${...}, and %{...} in <code>expression</code> to the value returned
|
||||
* by a call to {@link ValueStack#findValue(java.lang.String)}. If an item cannot
|
||||
@@ -108,7 +106,7 @@ public class TextParseUtil {
|
||||
* @return Converted object from variable translation.
|
||||
*/
|
||||
public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) {
|
||||
return translateVariables(new char[]{open} , expression, stack, asType, evaluator, MAX_RECURSION);
|
||||
return translateVariables(new char[]{open} , expression, stack, asType, evaluator, TextParser.DEFAULT_LOOP_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +120,7 @@ public class TextParseUtil {
|
||||
* @return Converted object from variable translation.
|
||||
*/
|
||||
public static Object translateVariables(char[] openChars, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) {
|
||||
return translateVariables(openChars, expression, stack, asType, evaluator, MAX_RECURSION);
|
||||
return translateVariables(openChars, expression, stack, asType, evaluator, TextParser.DEFAULT_LOOP_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +176,7 @@ public class TextParseUtil {
|
||||
* @return converted objects
|
||||
*/
|
||||
public static Collection<String> translateVariablesCollection(String expression, ValueStack stack, boolean excludeEmptyElements, ParsedValueEvaluator evaluator) {
|
||||
return translateVariablesCollection(new char[]{'$', '%'}, expression, stack, excludeEmptyElements, evaluator, MAX_RECURSION);
|
||||
return translateVariablesCollection(new char[]{'$', '%'}, expression, stack, excludeEmptyElements, evaluator, TextParser.DEFAULT_LOOP_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,8 @@ package com.opensymphony.xwork2.util;
|
||||
*/
|
||||
public interface TextParser {
|
||||
|
||||
int DEFAULT_LOOP_COUNT = 1;
|
||||
|
||||
Object evaluate(char[] openChars, String expression, TextParseUtil.ParsedValueEvaluator evaluator, int maxLoopCount);
|
||||
|
||||
}
|
||||
|
||||
@@ -129,15 +129,15 @@ import org.apache.logging.log4j.Logger;
|
||||
*/
|
||||
public class ValidationInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ValidationInterceptor.class);
|
||||
|
||||
private final static String VALIDATE_PREFIX = "validate";
|
||||
private final static String ALT_VALIDATE_PREFIX = "validateDo";
|
||||
|
||||
private boolean validateAnnotatedMethodOnly;
|
||||
|
||||
private ActionValidatorManager actionValidatorManager;
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ValidationInterceptor.class);
|
||||
|
||||
private final static String VALIDATE_PREFIX = "validate";
|
||||
private final static String ALT_VALIDATE_PREFIX = "validateDo";
|
||||
|
||||
private boolean alwaysInvokeValidate = true;
|
||||
private boolean programmatic = true;
|
||||
private boolean declarative = true;
|
||||
@@ -212,8 +212,8 @@ public class ValidationInterceptor extends MethodFilterInterceptor {
|
||||
String context = this.getValidationContext(proxy);
|
||||
String method = proxy.getMethod();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Validating {}/{} with method {}.", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), method);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Validating {}/{} with method {}.", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), method);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ package com.opensymphony.xwork2.validator.validators;
|
||||
* The regular expression used to validate that the string is an email address is:
|
||||
*
|
||||
* <pre>
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,6})$\\b
|
||||
* </pre>
|
||||
*
|
||||
* You can also specify expression, caseSensitive and trim params as a OGNL expression, see the example below.
|
||||
@@ -78,9 +78,7 @@ package com.opensymphony.xwork2.validator.validators;
|
||||
*/
|
||||
public class EmailValidator extends RegexFieldValidator {
|
||||
|
||||
// see XW-371
|
||||
public static final String EMAIL_ADDRESS_PATTERN =
|
||||
"\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b";
|
||||
public static final String EMAIL_ADDRESS_PATTERN = "\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,6})$\\b";
|
||||
|
||||
public EmailValidator() {
|
||||
setRegex(EMAIL_ADDRESS_PATTERN);
|
||||
|
||||
+2
-2
@@ -33,7 +33,7 @@ public abstract class AbstractMultiPartRequest implements MultiPartRequest {
|
||||
/**
|
||||
* Specifies the maximum size of the entire request.
|
||||
*/
|
||||
protected int maxSize;
|
||||
protected long maxSize;
|
||||
protected boolean maxSizeProvided;
|
||||
|
||||
/**
|
||||
@@ -67,7 +67,7 @@ public abstract class AbstractMultiPartRequest implements MultiPartRequest {
|
||||
@Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)
|
||||
public void setMaxSize(String maxSize) {
|
||||
this.maxSizeProvided = true;
|
||||
this.maxSize = Integer.parseInt(maxSize);
|
||||
this.maxSize = Long.parseLong(maxSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.apache.struts2.interceptor;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
@@ -12,7 +12,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class DateTextFieldInterceptor implements Interceptor {
|
||||
public class DateTextFieldInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(DateTextFieldInterceptor.class);
|
||||
|
||||
@@ -56,12 +56,6 @@ public class DateTextFieldInterceptor implements Interceptor {
|
||||
return values();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public String intercept(ActionInvocation ai) throws Exception {
|
||||
HttpParameters parameters = ai.getInvocationContext().getParameters();
|
||||
|
||||
@@ -38,59 +38,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
* <p>
|
||||
* An interceptor that handles setting the locale specified in a session as the locale for the current action request.
|
||||
* In addition, this interceptor will look for a specific HTTP request parameter and set the locale to whatever value is
|
||||
* provided, it also looks for specific cookie to read locale from. This means that this interceptor can be used to allow
|
||||
* for your application to dynamically change the locale for the user's session or, alternatively, only for the current
|
||||
* request (since XWork 2.1.3).
|
||||
* This is very useful for applications that require multi-lingual support and want the user to
|
||||
* be able to set his or her language preference at any point. The locale parameter is removed during the execution of
|
||||
* this interceptor, ensuring that properties aren't set on an action (such as request_locale) that have no typical
|
||||
* corresponding setter in your action.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* For example, using the default parameter name, a request to <b>foo.action?request_locale=en_US</b>, then the
|
||||
* locale for US English is saved in the user's session and will be used for all future requests.
|
||||
* If there is no locale set (for example with the first visit), the interceptor uses the browser locale.
|
||||
* </p>
|
||||
* <!-- END SNIPPET: description -->
|
||||
*
|
||||
* <!-- START SNIPPET: parameters -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>parameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to and save
|
||||
* in the session. By default this is <b>request_locale</b></li>
|
||||
*
|
||||
* <li>requestCookieParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to
|
||||
* and save in a cookien. By default this is <b>request_cookie_locale</b></li>
|
||||
*
|
||||
* <li>requestOnlyParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to
|
||||
* for the current request only, without saving it in the session. By default this is <b>request_only_locale</b></li>
|
||||
*
|
||||
* <li>attributeName (optional) - the name of the session key to store the selected locale. By default this is
|
||||
* <b>WW_TRANS_I18N_LOCALE</b></li>
|
||||
*
|
||||
* <li>storage (optional) - the name of storage location, it can be <b>none</b>, <b>session</b> or <b>cookie</b>.
|
||||
* By default this is <b>session</b></li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <!-- END SNIPPET: parameters -->
|
||||
*
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <interceptor name="i18nCookie" class="org.apache.struts2.interceptor.I18nInterceptor"/>
|
||||
*
|
||||
* <action name="someAction" class="com.examples.SomeAction">
|
||||
* <interceptor-ref name="i18nCookie"/>
|
||||
* <interceptor-ref name="basicStack"/>
|
||||
* <result name="success">good_result.ftl</result>
|
||||
* </action>
|
||||
* <!-- END SNIPPET: example -->
|
||||
*/
|
||||
*/
|
||||
public class I18nInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(I18nInterceptor.class);
|
||||
@@ -135,7 +84,7 @@ public class I18nInterceptor extends AbstractInterceptor {
|
||||
try {
|
||||
this.storage = Storage.valueOf(storageName.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.warn(new ParameterizedMessage("Wrong storage name [{{}] was defined, falling back to {}", storageName, Storage.SESSION), e);
|
||||
LOG.warn(new ParameterizedMessage("Wrong storage name [{}] was defined, falling back to {}", storageName, Storage.SESSION), e);
|
||||
this.storage = Storage.SESSION;
|
||||
}
|
||||
}
|
||||
@@ -148,107 +97,53 @@ public class I18nInterceptor extends AbstractInterceptor {
|
||||
|
||||
@Override
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
LOG.debug("Intercept '{}/{}'",
|
||||
invocation.getProxy().getNamespace(), invocation.getProxy().getActionName());
|
||||
LOG.debug("Intercept '{}/{}'", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName());
|
||||
|
||||
LocaleHandler localeHandler = getLocaleHandler(invocation);
|
||||
Locale locale = localeHandler.find();
|
||||
|
||||
if (locale == null) {
|
||||
locale = localeHandler.read(invocation);
|
||||
}
|
||||
|
||||
if (localeHandler.shouldStore()) {
|
||||
locale = localeHandler.store(invocation, locale);
|
||||
}
|
||||
|
||||
RequestOnlyLocaleFinder localeFinder = getLocaleFinder(invocation);
|
||||
Locale locale = getLocaleFromParam(localeFinder.find());
|
||||
locale = storeLocale(invocation, locale);
|
||||
useLocale(invocation, locale);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Before action invocation Locale={}", invocation.getStack().findValue("locale"));
|
||||
}
|
||||
|
||||
final String result = invocation.invoke();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("After action invocation Locale={}", invocation.getStack().findValue("locale"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected RequestOnlyLocaleFinder getLocaleFinder(ActionInvocation invocation) {
|
||||
RequestOnlyLocaleFinder localeFinder;
|
||||
if (this.storage == Storage.COOKIE) {
|
||||
localeFinder = new CookieLocaleFinder(invocation);
|
||||
} else if (this.storage == Storage.SESSION) {
|
||||
localeFinder = new SessionLocaleFinder(invocation);
|
||||
} else {
|
||||
localeFinder = new RequestOnlyLocaleFinder(invocation);
|
||||
}
|
||||
|
||||
LOG.debug("Using LocaleFinder implementation {}", localeFinder.getClass().getName());
|
||||
return localeFinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the locale to the chosen storage, like f. e. the session
|
||||
*
|
||||
* @param invocation the action invocation
|
||||
* @param locale the locale to store
|
||||
*
|
||||
* @return the locale
|
||||
*/
|
||||
protected Locale storeLocale(ActionInvocation invocation, Locale locale) {
|
||||
if (locale == null) {
|
||||
storage = Storage.NONE;
|
||||
locale = readStoredLocale(invocation);
|
||||
}
|
||||
|
||||
if (storage == Storage.COOKIE) {
|
||||
storeLocaleInCookie(invocation, locale);
|
||||
}
|
||||
|
||||
if (Storage.SESSION == storage) {
|
||||
storeLocaleInSession(invocation, locale);
|
||||
}
|
||||
|
||||
return locale;
|
||||
}
|
||||
|
||||
protected void storeLocaleInCookie(ActionInvocation ignore, Locale locale) {
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
|
||||
Cookie cookie = new Cookie(DEFAULT_COOKIE_ATTRIBUTE, locale.toString());
|
||||
cookie.setMaxAge(1209600); // two weeks
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
protected void storeLocaleInSession(ActionInvocation invocation, Locale locale) {
|
||||
//save it in session
|
||||
Map<String, Object> session = invocation.getInvocationContext().getSession();
|
||||
|
||||
if (session != null) {
|
||||
synchronized (session) {
|
||||
session.put(attributeName, locale);
|
||||
try {
|
||||
return invocation.invoke();
|
||||
} finally {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("After action invocation Locale={}", invocation.getStack().findValue("locale"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the locale from the session, and if not found from the
|
||||
* current invocation (=browser)
|
||||
* Override this method to use your own implementation of {@link LocaleHandler}
|
||||
*
|
||||
* @param invocation the current invocation
|
||||
* @return the read locale
|
||||
* @param invocation current action invocation context
|
||||
* @return instance of {@link LocaleHandler}
|
||||
*/
|
||||
protected Locale readStoredLocale(ActionInvocation invocation) {
|
||||
Locale locale = readStoredLocalFromSession(invocation);
|
||||
if (locale != null) {
|
||||
LOG.debug("Found stored Locale {} in session, using it!", locale);
|
||||
return locale;
|
||||
protected LocaleHandler getLocaleHandler(ActionInvocation invocation) {
|
||||
LocaleHandler localeHandler;
|
||||
|
||||
if (this.storage == Storage.COOKIE) {
|
||||
localeHandler = new CookieLocaleHandler(invocation);
|
||||
} else if (this.storage == Storage.SESSION) {
|
||||
localeHandler = new SessionLocaleHandler(invocation);
|
||||
} else {
|
||||
localeHandler = new RequestOnlyLocaleHandler(invocation);
|
||||
}
|
||||
|
||||
Locale cookie = readStoredLocaleFromCookie(invocation);
|
||||
if (cookie != null) {
|
||||
LOG.debug("Found stored Locale {} in cookies, using it!", locale);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
LOG.debug("Neither locale was in session nor in cookies, searching current Invocation context");
|
||||
return readStoredLocalFromCurrentInvocation(invocation);
|
||||
LOG.debug("Using LocaleFinder implementation {}", localeHandler.getClass().getName());
|
||||
return localeHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,7 +165,7 @@ public class I18nInterceptor extends AbstractInterceptor {
|
||||
}
|
||||
}
|
||||
if (locale != null) {
|
||||
LOG.debug("Applied request locale: {}", locale);
|
||||
LOG.debug("Found locale: {}", locale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,45 +178,8 @@ public class I18nInterceptor extends AbstractInterceptor {
|
||||
return locale;
|
||||
}
|
||||
|
||||
protected Locale readStoredLocalFromSession(ActionInvocation invocation) {
|
||||
// check session for saved locale
|
||||
Map<String, Object> session = invocation.getInvocationContext().getSession();
|
||||
|
||||
if (session != null) {
|
||||
synchronized (session) {
|
||||
Object sessionLocale = session.get(attributeName);
|
||||
if (sessionLocale != null && sessionLocale instanceof Locale) {
|
||||
Locale locale = (Locale) sessionLocale;
|
||||
LOG.debug("Applied session locale: {}", locale);
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Locale readStoredLocaleFromCookie(ActionInvocation ignore) {
|
||||
Cookie[] cookies = ServletActionContext.getRequest().getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (DEFAULT_COOKIE_ATTRIBUTE.equals(cookie.getName())) {
|
||||
return getLocaleFromParam(cookie.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Locale readStoredLocalFromCurrentInvocation(ActionInvocation invocation) {
|
||||
// no overriding locale definition found, stay with current invocation (=browser) locale
|
||||
Locale locale = invocation.getInvocationContext().getLocale();
|
||||
if (locale != null) {
|
||||
LOG.debug("Applied invocation context locale: {}", locale);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
protected Parameter findLocaleParameter(HttpParameters params, String parameterName) {
|
||||
protected Parameter findLocaleParameter(ActionInvocation invocation, String parameterName) {
|
||||
HttpParameters params = invocation.getInvocationContext().getParameters();
|
||||
Parameter requestedLocale = params.get(parameterName);
|
||||
params.remove(parameterName);
|
||||
if (requestedLocale.isDefined()) {
|
||||
@@ -340,75 +198,182 @@ public class I18nInterceptor extends AbstractInterceptor {
|
||||
invocation.getInvocationContext().setLocale(locale);
|
||||
}
|
||||
|
||||
protected class RequestOnlyLocaleFinder {
|
||||
/**
|
||||
* Uses to handle reading/storing Locale from/in different locations
|
||||
*/
|
||||
protected interface LocaleHandler {
|
||||
Locale find();
|
||||
Locale read(ActionInvocation invocation);
|
||||
Locale store(ActionInvocation invocation, Locale locale);
|
||||
boolean shouldStore();
|
||||
}
|
||||
|
||||
protected class RequestOnlyLocaleHandler implements LocaleHandler {
|
||||
|
||||
protected ActionInvocation actionInvocation = null;
|
||||
protected boolean shouldStore = true;
|
||||
|
||||
protected RequestOnlyLocaleFinder(ActionInvocation invocation) {
|
||||
protected RequestOnlyLocaleHandler(ActionInvocation invocation) {
|
||||
actionInvocation = invocation;
|
||||
}
|
||||
|
||||
public String find() {
|
||||
HttpParameters params = actionInvocation.getInvocationContext().getParameters();
|
||||
public Locale find() {
|
||||
LOG.debug("Searching locale in request under parameter {}", requestOnlyParameterName);
|
||||
|
||||
Parameter requestedLocale = findLocaleParameter(params, requestOnlyParameterName);
|
||||
Parameter requestedLocale = findLocaleParameter(actionInvocation, requestOnlyParameterName);
|
||||
if (requestedLocale.isDefined()) {
|
||||
storage = Storage.NONE;
|
||||
return requestedLocale.getValue();
|
||||
return getLocaleFromParam(requestedLocale.getValue());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale store(ActionInvocation invocation, Locale locale) {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale read(ActionInvocation invocation) {
|
||||
LOG.debug("Searching current Invocation context");
|
||||
// no overriding locale definition found, stay with current invocation (=browser) locale
|
||||
Locale locale = invocation.getInvocationContext().getLocale();
|
||||
if (locale != null) {
|
||||
LOG.debug("Applied invocation context locale: {}", locale);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldStore() {
|
||||
return shouldStore;
|
||||
}
|
||||
}
|
||||
|
||||
protected class SessionLocaleFinder extends RequestOnlyLocaleFinder {
|
||||
protected class SessionLocaleHandler extends RequestOnlyLocaleHandler {
|
||||
|
||||
protected SessionLocaleFinder(ActionInvocation invocation) {
|
||||
protected SessionLocaleHandler(ActionInvocation invocation) {
|
||||
super(invocation);
|
||||
}
|
||||
|
||||
public String find() {
|
||||
String requestOnlyLocale = super.find();
|
||||
public Locale find() {
|
||||
Locale requestOnlyLocale = super.find();
|
||||
|
||||
if (requestOnlyLocale != null) {
|
||||
LOG.debug("Found locale under request only param, it won't be stored in session!");
|
||||
shouldStore = false;
|
||||
return requestOnlyLocale;
|
||||
}
|
||||
|
||||
HttpParameters params = actionInvocation.getInvocationContext().getParameters();
|
||||
|
||||
Parameter requestedLocale = findLocaleParameter(params, parameterName);
|
||||
LOG.debug("Searching locale in request under parameter {}", parameterName);
|
||||
Parameter requestedLocale = findLocaleParameter(actionInvocation, parameterName);
|
||||
if (requestedLocale.isDefined()) {
|
||||
return requestedLocale.getValue();
|
||||
return getLocaleFromParam(requestedLocale.getValue());
|
||||
}
|
||||
|
||||
return requestedLocale.getValue();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale store(ActionInvocation invocation, Locale locale) {
|
||||
//save it in session
|
||||
Map<String, Object> session = invocation.getInvocationContext().getSession();
|
||||
|
||||
if (session != null) {
|
||||
String sessionId = ServletActionContext.getRequest().getSession().getId();
|
||||
synchronized (sessionId.intern()) {
|
||||
session.put(attributeName, locale);
|
||||
}
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale read(ActionInvocation invocation) {
|
||||
Locale locale = null;
|
||||
|
||||
LOG.debug("Checks session for saved locale");
|
||||
Map<String, Object> session = invocation.getInvocationContext().getSession();
|
||||
|
||||
if (session != null) {
|
||||
String sessionId = ServletActionContext.getRequest().getSession().getId();
|
||||
synchronized (sessionId.intern()) {
|
||||
Object sessionLocale = session.get(attributeName);
|
||||
if (sessionLocale != null && sessionLocale instanceof Locale) {
|
||||
locale = (Locale) sessionLocale;
|
||||
LOG.debug("Applied session locale: {}", locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locale == null) {
|
||||
LOG.debug("No Locale defined in session, fetching from current request and it won't be stored in session!");
|
||||
shouldStore = false;
|
||||
locale = super.read(invocation);
|
||||
} else {
|
||||
LOG.debug("Found stored Locale {} in session, using it!", locale);
|
||||
}
|
||||
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
protected class CookieLocaleFinder extends RequestOnlyLocaleFinder {
|
||||
protected CookieLocaleFinder(ActionInvocation invocation) {
|
||||
protected class CookieLocaleHandler extends RequestOnlyLocaleHandler {
|
||||
protected CookieLocaleHandler(ActionInvocation invocation) {
|
||||
super(invocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String find() {
|
||||
String requestOnlySessionLocale = super.find();
|
||||
public Locale find() {
|
||||
Locale requestOnlySessionLocale = super.find();
|
||||
|
||||
if (requestOnlySessionLocale != null) {
|
||||
shouldStore = false;
|
||||
return requestOnlySessionLocale;
|
||||
}
|
||||
|
||||
HttpParameters params = actionInvocation.getInvocationContext().getParameters();
|
||||
|
||||
Parameter requestedLocale = findLocaleParameter(params, requestCookieParameterName);
|
||||
LOG.debug("Searching locale in request under parameter {}", requestCookieParameterName);
|
||||
Parameter requestedLocale = findLocaleParameter(actionInvocation, requestCookieParameterName);
|
||||
if (requestedLocale.isDefined()) {
|
||||
storage = Storage.COOKIE;
|
||||
return requestedLocale.getValue();
|
||||
return getLocaleFromParam(requestedLocale.getValue());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale store(ActionInvocation invocation, Locale locale) {
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
|
||||
Cookie cookie = new Cookie(attributeName, locale.toString());
|
||||
cookie.setMaxAge(1209600); // two weeks
|
||||
response.addCookie(cookie);
|
||||
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale read(ActionInvocation invocation) {
|
||||
Locale locale = null;
|
||||
|
||||
Cookie[] cookies = ServletActionContext.getRequest().getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (attributeName.equals(cookie.getName())) {
|
||||
locale = getLocaleFromParam(cookie.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locale == null) {
|
||||
LOG.debug("No Locale defined in cookie, fetching from current request and it won't be stored!");
|
||||
shouldStore = false;
|
||||
locale = super.read(invocation);
|
||||
} else {
|
||||
LOG.debug("Found stored Locale {} in cookie, using it!", locale);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -203,7 +203,10 @@ public class MessageStoreInterceptor extends AbstractInterceptor {
|
||||
before(invocation);
|
||||
|
||||
LOG.trace("Registering listener to store messages before result will be executed");
|
||||
invocation.addPreResultListener(new MessageStorePreResultListener(this));
|
||||
MessageStorePreResultListener preResultListener = createPreResultListener(invocation);
|
||||
preResultListener.init(this);
|
||||
|
||||
invocation.addPreResultListener(preResultListener);
|
||||
|
||||
String result = invocation.invoke();
|
||||
|
||||
@@ -212,6 +215,10 @@ public class MessageStoreInterceptor extends AbstractInterceptor {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected MessageStorePreResultListener createPreResultListener(ActionInvocation invocation) {
|
||||
return new MessageStorePreResultListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the retrieving of field errors / action messages / field errors, which is
|
||||
* done before action invocation, and the <code>operationMode</code> is 'RETRIEVE'.
|
||||
|
||||
+29
-17
@@ -26,8 +26,7 @@ import com.opensymphony.xwork2.interceptor.ValidationAware;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.result.ServletActionRedirectResult;
|
||||
import org.apache.struts2.result.ServletRedirectResult;
|
||||
import org.apache.struts2.result.Redirectable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,26 +35,25 @@ import java.util.Map;
|
||||
* just before result will be executed. It must be done that way as after result will be executed
|
||||
* HttpSession cannot be modified (response was already sent to browser).
|
||||
*/
|
||||
class MessageStorePreResultListener implements PreResultListener {
|
||||
public class MessageStorePreResultListener implements PreResultListener {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(MessageStorePreResultListener.class);
|
||||
|
||||
private MessageStoreInterceptor interceptor;
|
||||
protected MessageStoreInterceptor interceptor;
|
||||
|
||||
public MessageStorePreResultListener(MessageStoreInterceptor interceptor) {
|
||||
public void init(MessageStoreInterceptor interceptor) {
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeResult(ActionInvocation invocation, String resultCode) {
|
||||
|
||||
boolean isCommitted = ServletActionContext.getResponse().isCommitted();
|
||||
boolean isCommitted = isCommitted();
|
||||
if (isCommitted) {
|
||||
LOG.trace("Response was already committed, cannot store messages!");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isInvalidated = ServletActionContext.getRequest().getSession(false) == null;
|
||||
boolean isInvalidated = isInvalidated();
|
||||
if (isInvalidated) {
|
||||
LOG.trace("Session was invalidated or never created, cannot store messages!");
|
||||
return;
|
||||
@@ -69,15 +67,7 @@ class MessageStorePreResultListener implements PreResultListener {
|
||||
|
||||
String reqOperationMode = interceptor.getRequestOperationMode(invocation);
|
||||
|
||||
boolean isRedirect = false;
|
||||
try {
|
||||
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode);
|
||||
if (resultConfig != null) {
|
||||
isRedirect = ServletRedirectResult.class.isAssignableFrom(Class.forName(resultConfig.getClassName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot read result!", e);
|
||||
}
|
||||
boolean isRedirect = isRedirect(invocation, resultCode);
|
||||
|
||||
if (MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(reqOperationMode) ||
|
||||
MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(interceptor.getOperationModel()) ||
|
||||
@@ -97,4 +87,26 @@ class MessageStorePreResultListener implements PreResultListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isCommitted() {
|
||||
return ServletActionContext.getResponse().isCommitted();
|
||||
}
|
||||
|
||||
protected boolean isInvalidated() {
|
||||
return ServletActionContext.getRequest().getSession(false) == null;
|
||||
}
|
||||
|
||||
protected boolean isRedirect(ActionInvocation invocation, String resultCode) {
|
||||
boolean isRedirect = false;
|
||||
try {
|
||||
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode);
|
||||
if (resultConfig != null) {
|
||||
isRedirect = Redirectable.class.isAssignableFrom(Class.forName(resultConfig.getClassName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot read result!", e);
|
||||
}
|
||||
return isRedirect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.opensymphony.xwork2.TextProvider;
|
||||
import com.opensymphony.xwork2.interceptor.ValidationAware;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.util.TokenHelper;
|
||||
|
||||
@@ -116,7 +118,7 @@ import javax.servlet.http.HttpSession;
|
||||
*/
|
||||
public class TokenInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
private static final long serialVersionUID = -6680894220590585506L;
|
||||
private static final Logger LOG = LogManager.getLogger(TokenInterceptor.class);
|
||||
|
||||
public static final String INVALID_TOKEN_CODE = "invalid.token";
|
||||
|
||||
@@ -135,7 +137,7 @@ public class TokenInterceptor extends MethodFilterInterceptor {
|
||||
*/
|
||||
@Override
|
||||
protected String doIntercept(ActionInvocation invocation) throws Exception {
|
||||
log.debug("Intercepting invocation to check for valid transaction token.");
|
||||
LOG.debug("Intercepting invocation to check for valid transaction token.");
|
||||
return handleToken(invocation);
|
||||
}
|
||||
|
||||
@@ -143,7 +145,7 @@ public class TokenInterceptor extends MethodFilterInterceptor {
|
||||
//see WW-2902: we need to use the real HttpSession here, as opposed to the map
|
||||
//that wraps the session, because a new wrap is created on every request
|
||||
HttpSession session = ServletActionContext.getRequest().getSession(true);
|
||||
synchronized (session) {
|
||||
synchronized (session.getId().intern()) {
|
||||
if (!TokenHelper.validToken()) {
|
||||
return handleInvalidToken(invocation);
|
||||
}
|
||||
@@ -165,7 +167,7 @@ public class TokenInterceptor extends MethodFilterInterceptor {
|
||||
if (action instanceof ValidationAware) {
|
||||
((ValidationAware) action).addActionError(errorMessage);
|
||||
} else {
|
||||
log.warn(errorMessage);
|
||||
LOG.warn(errorMessage);
|
||||
}
|
||||
|
||||
return INVALID_TOKEN_CODE;
|
||||
|
||||
+16
-9
@@ -22,10 +22,13 @@
|
||||
package org.apache.struts2.interceptor.validation;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.AnnotationUtils;
|
||||
import com.opensymphony.xwork2.validator.ValidationInterceptor;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -38,19 +41,20 @@ import java.util.Collection;
|
||||
*/
|
||||
public class AnnotationValidationInterceptor extends ValidationInterceptor {
|
||||
|
||||
/** Auto-generated serialization id */
|
||||
private static final long serialVersionUID = 1813272797367431184L;
|
||||
private static final Logger LOG = LogManager.getLogger(AnnotationValidationInterceptor.class);
|
||||
|
||||
protected String doIntercept(ActionInvocation invocation) throws Exception {
|
||||
|
||||
Object action = invocation.getAction();
|
||||
if (action != null) {
|
||||
Method method = getActionMethod(action.getClass(), invocation.getProxy().getMethod());
|
||||
Collection<Method> annotatedMethods = AnnotationUtils.getAnnotatedMethods(action.getClass(), SkipValidation.class);
|
||||
if (annotatedMethods.contains(method))
|
||||
return invocation.invoke();
|
||||
|
||||
//check if method overwites an annotated method
|
||||
Collection<Method> annotatedMethods = AnnotationUtils.getAnnotatedMethods(action.getClass(), SkipValidation.class);
|
||||
if (annotatedMethods.contains(method)) {
|
||||
return invocation.invoke();
|
||||
}
|
||||
|
||||
LOG.debug("Check if method overrides an annotated method");
|
||||
Class clazz = action.getClass().getSuperclass();
|
||||
while (clazz != null) {
|
||||
annotatedMethods = AnnotationUtils.getAnnotatedMethods(clazz, SkipValidation.class);
|
||||
@@ -69,9 +73,12 @@ public class AnnotationValidationInterceptor extends ValidationInterceptor {
|
||||
return super.doIntercept(invocation);
|
||||
}
|
||||
|
||||
// FIXME: This is copied from DefaultActionInvocation but should be exposed through the interface
|
||||
protected Method getActionMethod(Class<?> actionClass, String methodName) throws NoSuchMethodException {
|
||||
return actionClass.getMethod(methodName);
|
||||
protected Method getActionMethod(Class<?> actionClass, String methodName) {
|
||||
try {
|
||||
return actionClass.getMethod(methodName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new ConfigurationException("Wrong method was defined as an action method: " + methodName, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.apache.struts2.result;
|
||||
|
||||
/**
|
||||
* Marking interface for results which perform browser redirection
|
||||
*/
|
||||
public interface Redirectable {
|
||||
|
||||
}
|
||||
@@ -123,7 +123,7 @@ import java.util.List;
|
||||
*
|
||||
* @see ActionMapper
|
||||
*/
|
||||
public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler {
|
||||
public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler, Redirectable {
|
||||
|
||||
private static final long serialVersionUID = -9042425229314584066L;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.views.util.UrlHelper;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
@@ -142,14 +143,17 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
// see WW-2120
|
||||
if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf("?") > 0) {
|
||||
String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
|
||||
Map<String, Object> parameters = getParameters(invocation);
|
||||
HttpParameters parameters = getParameters(invocation);
|
||||
Map<String, Object> queryParams = urlHelper.parseQueryString(queryString, true);
|
||||
if (queryParams != null && !queryParams.isEmpty())
|
||||
parameters.putAll(queryParams);
|
||||
if (queryParams != null && !queryParams.isEmpty()) {
|
||||
parameters = HttpParameters.create(queryParams).withParent(parameters).build();
|
||||
invocation.getInvocationContext().setParameters(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// if the view doesn't exist, let's do a 404
|
||||
if (dispatcher == null) {
|
||||
LOG.warn("Location {} not found!", finalLocation);
|
||||
response.sendError(404, "result '" + finalLocation + "' not found");
|
||||
return;
|
||||
}
|
||||
@@ -171,9 +175,8 @@ public class ServletDispatcherResult extends StrutsResultSupport {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getParameters(ActionInvocation invocation) {
|
||||
return (Map<String, Object>) invocation.getInvocationContext().getContextMap().get("parameters");
|
||||
protected HttpParameters getParameters(ActionInvocation invocation) {
|
||||
return invocation.getInvocationContext().getParameters();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ import static javax.servlet.http.HttpServletResponse.SC_FOUND;
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler {
|
||||
public class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler, Redirectable {
|
||||
|
||||
private static final long serialVersionUID = 6316947346435301270L;
|
||||
|
||||
|
||||
@@ -43,162 +43,8 @@ import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: description -->
|
||||
*
|
||||
* XSLTResult uses XSLT to transform an action object to XML. The recent version
|
||||
* has been specifically modified to deal with Xalan flaws. When using Xalan you
|
||||
* may notice that even though you have a very minimal stylesheet like this one
|
||||
* <pre>
|
||||
* <xsl:template match="/result">
|
||||
* <result/>
|
||||
* </xsl:template></pre>
|
||||
*
|
||||
* <p>
|
||||
* Xalan would still iterate through every property of your action and all
|
||||
* its descendants.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you had double-linked objects, Xalan would work forever analysing an
|
||||
* infinite object tree. Even if your stylesheet was not constructed to process
|
||||
* them all. It's because the current Xalan eagerly and extensively converts
|
||||
* everything to its internal DTM model before further processing.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* That's why there's a loop eliminator added that works by indexing every
|
||||
* object-property combination during processing. If it notices that some
|
||||
* object's property was already walked through, it doesn't go any deeper.
|
||||
* Say you have two objects, x and y, with the following properties set
|
||||
* (pseudocode):
|
||||
* </p>
|
||||
* <pre>
|
||||
* x.y = y;
|
||||
* and
|
||||
* y.x = x;
|
||||
* action.x=x;</pre>
|
||||
*
|
||||
* <p>
|
||||
* Due to that modification, the resulting XML document based on x would be:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* <result>
|
||||
* <x>
|
||||
* <y/>
|
||||
* </x>
|
||||
* </result></pre>
|
||||
*
|
||||
* <p>
|
||||
* Without it there would be endless x/y/x/y/x/y/... elements.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The XSLTResult code tries also to deal with the fact that DTM model is built
|
||||
* in a manner that children are processed before siblings. The result is that if
|
||||
* there is object x that is both set in action's x property, and very deeply
|
||||
* under action's a property then it would only appear under a, not under x.
|
||||
* That's not what we expect, and that's why XSLTResult allows objects to repeat
|
||||
* in various places to some extent.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Sometimes the object mesh is still very dense and you may notice that even
|
||||
* though you have a relatively simple stylesheet, execution takes a tremendous
|
||||
* amount of time. To help you to deal with that obstacle of Xalan, you may
|
||||
* attach regexp filters to elements paths (xpath).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> In your .xsl file the root match must be named <tt>result</tt>.
|
||||
* <br>This example will output the username by using <tt>getUsername</tt> on your
|
||||
* action class:
|
||||
* <pre>
|
||||
* <xsl:template match="result">
|
||||
* <html>
|
||||
* <body>
|
||||
* Hello <xsl:value-of select="username"/> how are you?
|
||||
* </body>
|
||||
* </html>
|
||||
* </xsl:template>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* In the following example the XSLT result would only walk through action's
|
||||
* properties without their childs. It would also skip every property that has
|
||||
* "hugeCollection" in their name. Element's path is first compared to
|
||||
* excludingPattern - if it matches it's no longer processed. Then it is
|
||||
* compared to matchingPattern and processed only if there's a match.
|
||||
* </p>
|
||||
*
|
||||
* <!-- END SNIPPET: description -->
|
||||
*
|
||||
* <pre><!-- START SNIPPET: description.example -->
|
||||
* <result name="success" type="xslt">
|
||||
* <param name="location">foo.xslt</param>
|
||||
* <param name="matchingPattern">^/result/[^/*]$</param>
|
||||
* <param name="excludingPattern">.*(hugeCollection).*</param>
|
||||
* </result>
|
||||
* <!-- END SNIPPET: description.example --></pre>
|
||||
*
|
||||
* <p>
|
||||
* In the following example the XSLT result would use the action's user property
|
||||
* instead of the action as it's base document and walk through it's properties.
|
||||
* The exposedValue uses an ognl expression to derive it's value.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* <result name="success" type="xslt">
|
||||
* <param name="location">foo.xslt</param>
|
||||
* <param name="exposedValue">user$</param>
|
||||
* </result>
|
||||
* </pre>
|
||||
* *
|
||||
* <b>This result type takes the following parameters:</b>
|
||||
*
|
||||
* <!-- START SNIPPET: params -->
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>location (default)</b> - the location to go to after execution.</li>
|
||||
* <li><b>encoding</b> - character encoding used in XML, default UTF-8.</li>
|
||||
*
|
||||
* <li><b>parse</b> - true by default. If set to false, the location param will
|
||||
* not be parsed for Ognl expressions.</li>
|
||||
*
|
||||
* <!--
|
||||
* <li><b>matchingPattern</b> - Pattern that matches only desired elements, by
|
||||
* default it matches everything.</li>
|
||||
*
|
||||
* <li><b>excludingPattern</b> - Pattern that eliminates unwanted elements, by
|
||||
* default it matches none.</li>
|
||||
* -->
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* <code>struts.properties</code> related configuration:
|
||||
* </p>
|
||||
* <ul>
|
||||
*
|
||||
* <li><b>struts.xslt.nocache</b> - Defaults to false. If set to true, disables
|
||||
* stylesheet caching. Good for development, bad for production.</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
* <p>
|
||||
* <b>Example:</b>
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: example -->
|
||||
* <result name="success" type="xslt">foo.xslt</result>
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
* XSLTResult uses XSLT to transform an action object to XML.
|
||||
*/
|
||||
public class XSLTResult implements Result {
|
||||
|
||||
@@ -233,7 +79,7 @@ public class XSLTResult implements Result {
|
||||
/** Indicates the property name patterns which should be excluded from the xml. */
|
||||
private String excludingPattern;
|
||||
|
||||
/** Indicates the ognl expression respresenting the bean which is to be exposed as xml. */
|
||||
/** Indicates the ognl expression representing the bean which is to be exposed as xml. */
|
||||
private String exposedValue;
|
||||
|
||||
/** Indicates the status to return in the response */
|
||||
@@ -258,8 +104,6 @@ public class XSLTResult implements Result {
|
||||
}
|
||||
|
||||
public void setStylesheetLocation(String location) {
|
||||
if (location == null)
|
||||
throw new IllegalArgumentException("Null location");
|
||||
this.stylesheetLocation = location;
|
||||
}
|
||||
|
||||
@@ -306,12 +150,15 @@ public class XSLTResult implements Result {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String location = getStylesheetLocation();
|
||||
|
||||
if (location == null) {
|
||||
throw new IllegalArgumentException("Parameter 'stylesheetLocation' cannot be null!");
|
||||
}
|
||||
|
||||
if (parse) {
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
location = TextParseUtil.translateVariables(location, stack);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
HttpServletResponse response = ServletActionContext.getResponse();
|
||||
response.setStatus(status);
|
||||
@@ -324,17 +171,20 @@ public class XSLTResult implements Result {
|
||||
if (location != null) {
|
||||
templates = getTemplates(location);
|
||||
transformer = templates.newTransformer();
|
||||
} else
|
||||
} else {
|
||||
transformer = TransformerFactory.newInstance().newTransformer();
|
||||
}
|
||||
|
||||
transformer.setURIResolver(getURIResolver());
|
||||
transformer.setErrorListener(buildErrorListener());
|
||||
|
||||
String mimeType;
|
||||
if (templates == null)
|
||||
if (templates == null) {
|
||||
mimeType = "text/xml"; // no stylesheet, raw xml
|
||||
else
|
||||
} else {
|
||||
mimeType = templates.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
|
||||
}
|
||||
|
||||
if (mimeType == null) {
|
||||
// guess (this is a servlet, so text/html might be the best guess)
|
||||
mimeType = "text/html";
|
||||
@@ -383,8 +233,9 @@ public class XSLTResult implements Result {
|
||||
}
|
||||
|
||||
protected AdapterFactory getAdapterFactory() {
|
||||
if (adapterFactory == null)
|
||||
if (adapterFactory == null) {
|
||||
adapterFactory = new AdapterFactory();
|
||||
}
|
||||
return adapterFactory;
|
||||
}
|
||||
|
||||
@@ -397,8 +248,7 @@ public class XSLTResult implements Result {
|
||||
* function. The default is an instance of ServletURIResolver, which operates relative to the servlet context.
|
||||
*/
|
||||
protected URIResolver getURIResolver() {
|
||||
return new ServletURIResolver(
|
||||
ServletActionContext.getServletContext());
|
||||
return new ServletURIResolver(ServletActionContext.getServletContext());
|
||||
}
|
||||
|
||||
protected Templates getTemplates(final String path) throws TransformerException, IOException {
|
||||
@@ -428,8 +278,7 @@ public class XSLTResult implements Result {
|
||||
return templates;
|
||||
}
|
||||
|
||||
protected Source getDOMSourceForStack(Object value)
|
||||
throws IllegalAccessException, InstantiationException {
|
||||
protected Source getDOMSourceForStack(Object value) throws IllegalAccessException, InstantiationException {
|
||||
return new DOMSource(getAdapterFactory().adaptDocument("result", value) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ struts.messages.invalid.file=Could not find a Filename for {0}. Verify that a va
|
||||
struts.messages.invalid.content.type=Could not find a Content-Type for {0}. Verify that a valid file was submitted.
|
||||
struts.messages.removing.file=Removing file {0} {1}
|
||||
struts.messages.error.uploading=Error uploading: {0}
|
||||
struts.messages.error.file.too.large=The file is to large to be uploaded: {0} "{1}" "{2}" {3}
|
||||
struts.messages.error.file.too.large=The file is too large to be uploaded: {0} "{1}" "{2}" {3}
|
||||
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
|
||||
struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<!-- constant name="struts.excludedPackageNamePatterns" value="^java\.lang\..*,^ognl.*,^(?!javax\.servlet\..+)(javax\..+)" / -->
|
||||
|
||||
<!-- this is simpler version of the above used with string comparison -->
|
||||
<constant name="struts.excludedPackageNames" value="java.lang.,ognl,javax" />
|
||||
<constant name="struts.excludedPackageNames" value="java.lang.,ognl,javax,freemarker.core,freemarker.template" />
|
||||
|
||||
<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
|
||||
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="struts" class="org.apache.struts2.factory.StrutsResultFactory" />
|
||||
|
||||
@@ -3,16 +3,20 @@ package com.opensymphony.xwork2;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
|
||||
import com.opensymphony.xwork2.mock.MockActionProxy;
|
||||
import com.opensymphony.xwork2.mock.MockContainer;
|
||||
import com.opensymphony.xwork2.mock.MockInterceptor;
|
||||
import com.opensymphony.xwork2.mock.MockLazyInterceptor;
|
||||
import com.opensymphony.xwork2.ognl.OgnlUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -298,6 +302,36 @@ public class DefaultActionInvocationTest extends XWorkTestCase {
|
||||
assertEquals("success", result);
|
||||
}
|
||||
|
||||
public void testInvokeWithLazyParams() throws Exception {
|
||||
HashMap<String, Object> params = new HashMap<>();
|
||||
params.put("blah", "this is blah");
|
||||
|
||||
HashMap<String, Object> extraContext = new HashMap<>();
|
||||
extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
|
||||
|
||||
DefaultActionInvocation defaultActionInvocation = new DefaultActionInvocation(extraContext, true);
|
||||
container.inject(defaultActionInvocation);
|
||||
|
||||
ActionProxy actionProxy = actionProxyFactory.createActionProxy( "", "LazyFoo", null, extraContext);
|
||||
defaultActionInvocation.init(actionProxy);
|
||||
defaultActionInvocation.invoke();
|
||||
|
||||
SimpleAction action = (SimpleAction) defaultActionInvocation.getAction();
|
||||
|
||||
assertEquals("this is blah", action.getBlah());
|
||||
assertEquals("this is blah", action.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// ensure we're using the default configuration, not simple config
|
||||
XmlConfigurationProvider configurationProvider = new XmlConfigurationProvider("xwork-sample.xml");
|
||||
container.inject(configurationProvider);
|
||||
loadConfigurationProviders(configurationProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DefaultActionInvocationTester extends DefaultActionInvocation {
|
||||
|
||||
+4
@@ -41,6 +41,10 @@ public class XmlConfigurationProviderWildCardIncludeTest extends ConfigurationTe
|
||||
assertNotNull(defaultTwoPackage);
|
||||
assertEquals("default-2", defaultTwoPackage.getName());
|
||||
|
||||
PackageConfig defaultPackage = configuration.getPackageConfig("default");
|
||||
assertNotNull(defaultPackage);
|
||||
assertEquals("default", defaultPackage.getName());
|
||||
|
||||
configurationManager.addContainerProvider(provider);
|
||||
configurationManager.reload();
|
||||
|
||||
|
||||
@@ -55,21 +55,18 @@ public class TimerInterceptorTest extends XWorkTestCase {
|
||||
public void testDefault() throws Exception {
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testNoNamespace() throws Exception {
|
||||
ap.setNamespace(null);
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testInputMethod() throws Exception {
|
||||
ap.setMethod("input");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!input] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testTraceLevel() throws Exception {
|
||||
@@ -89,35 +86,30 @@ public class TimerInterceptorTest extends XWorkTestCase {
|
||||
interceptor.setLogLevel("info");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testWarnLevel() throws Exception {
|
||||
interceptor.setLogLevel("warn");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testErrorLevel() throws Exception {
|
||||
interceptor.setLogLevel("error");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testFatalLevel() throws Exception {
|
||||
interceptor.setLogLevel("fatal");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testLogCategory() throws Exception {
|
||||
interceptor.setLogCategory("com.mycompany.myapp.actiontiming");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertNotSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
}
|
||||
|
||||
public void testLogCategoryLevel() throws Exception {
|
||||
@@ -125,7 +117,6 @@ public class TimerInterceptorTest extends XWorkTestCase {
|
||||
interceptor.setLogLevel("error");
|
||||
interceptor.intercept(mai);
|
||||
assertTrue(interceptor.message.startsWith("Executed action [myApp/myAction!execute] took "));
|
||||
assertNotSame(interceptor.logger, TimerInterceptor.LOG);
|
||||
assertEquals("com.mycompany.myapp.actiontiming", interceptor.getLogCategory());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2006,2009 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.opensymphony.xwork2.mock;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.SimpleAction;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.WithLazyParams;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class MockLazyInterceptor extends AbstractInterceptor implements WithLazyParams {
|
||||
|
||||
private String foo = "";
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
if (invocation.getAction() instanceof SimpleAction) {
|
||||
((SimpleAction) invocation.getAction()).setName(foo);
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ public class EmailValidatorTest extends XWorkTestCase {
|
||||
assertTrue(verifyEmailValidity("Ferda+Mravenec@yaHoo.CoM"));
|
||||
assertTrue(verifyEmailValidity("user@domainname.tech"));
|
||||
assertTrue(verifyEmailValidity("Ferda+Mravenec@yaHoo.cat"));
|
||||
assertTrue(verifyEmailValidity("user@domainname.swiss"));
|
||||
|
||||
assertFalse(verifyEmailValidity("tm_jee#marry@yahoo.co.uk"));
|
||||
assertFalse(verifyEmailValidity("tm_jee@ yahoo.co.uk"));
|
||||
|
||||
@@ -207,7 +207,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
assertEquals(1, errors.size());
|
||||
String msg = (String) errors.get(0);
|
||||
// the error message should contain at least this test
|
||||
assertTrue(msg.startsWith("The file is to large to be uploaded"));
|
||||
assertTrue(msg.startsWith("The file is too large to be uploaded"));
|
||||
assertTrue(msg.indexOf("inputName") > 0);
|
||||
assertTrue(msg.indexOf("log4j2.xml") > 0);
|
||||
}
|
||||
|
||||
+8
-4
@@ -54,7 +54,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase {
|
||||
|
||||
// when
|
||||
MessageStoreInterceptor msi = new MessageStoreInterceptor();
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener(msi);
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener();
|
||||
listener.init(msi);
|
||||
listener.beforeResult(mockActionInvocation, Action.SUCCESS);
|
||||
|
||||
// then
|
||||
@@ -86,7 +87,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase {
|
||||
|
||||
// when
|
||||
MessageStoreInterceptor msi = new MessageStoreInterceptor();
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener(msi);
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener();
|
||||
listener.init(msi);
|
||||
listener.beforeResult(mockActionInvocation, Action.SUCCESS);
|
||||
|
||||
// then
|
||||
@@ -98,7 +100,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase {
|
||||
MessageStoreInterceptor interceptor = new MessageStoreInterceptor();
|
||||
interceptor.setOperationMode(MessageStoreInterceptor.AUTOMATIC_MODE);
|
||||
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor);
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener();
|
||||
listener.init(interceptor);
|
||||
|
||||
Map sessionMap = new LinkedHashMap();
|
||||
|
||||
@@ -178,7 +181,8 @@ public class MessageStorePreResultListenerTest extends StrutsInternalTestCase {
|
||||
interceptor.setAllowRequestParameterSwitch(true);
|
||||
interceptor.setOperationMode(MessageStoreInterceptor.STORE_MODE);
|
||||
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor);
|
||||
MessageStorePreResultListener listener = new MessageStorePreResultListener();
|
||||
listener.init(interceptor);
|
||||
|
||||
Map sessionMap = new LinkedHashMap();
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import ognl.Ognl;
|
||||
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
@@ -107,4 +110,46 @@ public class ServletDispatcherResultTest extends StrutsInternalTestCase implemen
|
||||
requestMock.verify();
|
||||
dispatcherMock.verify();
|
||||
}
|
||||
|
||||
public void testWithParameter() {
|
||||
ServletDispatcherResult view = container.inject(ServletDispatcherResult.class);
|
||||
view.setLocation("foo.jsp?bar=1");
|
||||
|
||||
Mock dispatcherMock = new Mock(RequestDispatcher.class);
|
||||
dispatcherMock.expect("forward", C.ANY_ARGS);
|
||||
|
||||
Mock requestMock = new Mock(HttpServletRequest.class);
|
||||
requestMock.expectAndReturn("getAttribute", "struts.actiontag.invocation", null);
|
||||
requestMock.expectAndReturn("getAttribute", "javax.servlet.include.servlet_path", null);
|
||||
requestMock.expectAndReturn("getRequestDispatcher", C.args(C.eq("foo.jsp?bar=1")), dispatcherMock.proxy());
|
||||
requestMock.expect("setAttribute", C.ANY_ARGS); // this is a bad mock, but it works
|
||||
requestMock.expect("setAttribute", C.ANY_ARGS); // this is a bad mock, but it works
|
||||
requestMock.matchAndReturn("getRequestURI", "foo.jsp");
|
||||
|
||||
Mock responseMock = new Mock(HttpServletResponse.class);
|
||||
responseMock.expectAndReturn("isCommitted", Boolean.FALSE);
|
||||
|
||||
ActionContext ac = new ActionContext(Ognl.createDefaultContext(null));
|
||||
ac.setContainer(container);
|
||||
ActionContext.setContext(ac);
|
||||
ServletActionContext.setRequest((HttpServletRequest) requestMock.proxy());
|
||||
ServletActionContext.setResponse((HttpServletResponse) responseMock.proxy());
|
||||
|
||||
MockActionInvocation mockActionInvocation = new MockActionInvocation();
|
||||
mockActionInvocation.setInvocationContext(ac);
|
||||
mockActionInvocation.setStack(container.getInstance(ValueStackFactory.class).createValueStack());
|
||||
|
||||
try {
|
||||
view.execute(mockActionInvocation);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
assertTrue(mockActionInvocation.getInvocationContext().getParameters().contains("bar"));
|
||||
assertEquals("1", mockActionInvocation.getInvocationContext().getParameters().get("bar").getValue());
|
||||
dispatcherMock.verify();
|
||||
requestMock.verify();
|
||||
dispatcherMock.verify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -82,6 +83,22 @@ public class XSLTResultTest extends StrutsInternalTestCase {
|
||||
assertTrue(out.indexOf("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
|
||||
}
|
||||
|
||||
public void testSimpleTransform5() throws Exception {
|
||||
result.setParse(false);
|
||||
result.setStylesheetLocation("XSLTResultTest6.xsl");
|
||||
result.execute(mai);
|
||||
|
||||
String out = response.getContentAsString();
|
||||
assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
|
||||
assertTrue(out.contains("<title>WebWork in Action</title>"));
|
||||
assertTrue(out.contains("<author>Patrick and Jason</author>"));
|
||||
assertTrue(out.contains("<editions><edition value=\"I\">I</edition><edition value=\"IV\">IV</edition></editions>"));
|
||||
assertTrue(out.contains("<book><title/><author/><editions/></book>"));
|
||||
assertTrue(out.contains("<title>XWork not in Action</title>"));
|
||||
assertTrue(out.contains("<author>Superman</author>"));
|
||||
assertTrue(out.contains("<editions><edition value=\"1234\">1234</edition><edition value=\"345\">345</edition><edition value=\"6667\">6667</edition></editions>"));
|
||||
}
|
||||
|
||||
public void testSimpleTransformParse() throws Exception {
|
||||
result.setParse(true);
|
||||
result.setStylesheetLocation("${top.myLocation}");
|
||||
@@ -277,9 +294,9 @@ public class XSLTResultTest extends StrutsInternalTestCase {
|
||||
|
||||
public List getBooks() {
|
||||
List list = new ArrayList();
|
||||
list.add(new Book("WebWork in Action", "Patrick and Jason"));
|
||||
list.add(new Book("WebWork in Action", "Patrick and Jason", Arrays.asList("I", "IV")));
|
||||
list.add(null);
|
||||
list.add(new Book("XWork not in Action", "Superman"));
|
||||
list.add(new Book("XWork not in Action", "Superman", Arrays.asList("1234", "345", "6667")));
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -289,10 +306,12 @@ public class XSLTResultTest extends StrutsInternalTestCase {
|
||||
|
||||
private String title;
|
||||
private String author;
|
||||
private List<String> editions;
|
||||
|
||||
public Book(String title, String author) {
|
||||
public Book(String title, String author, List<String> editions) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.editions = editions;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
@@ -302,5 +321,9 @@ public class XSLTResultTest extends StrutsInternalTestCase {
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public List<String> getEditions() {
|
||||
return editions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:output method="xml" encoding="UTF-8" />
|
||||
<xsl:template match="result">
|
||||
<books>
|
||||
<xsl:for-each select="books/item">
|
||||
<book>
|
||||
<title><xsl:value-of select="title"/></title>
|
||||
<author><xsl:value-of select="author"/></author>
|
||||
<editions>
|
||||
<xsl:for-each select="editions/item">
|
||||
<edition><xsl:attribute name="value"><xsl:value-of select="."/></xsl:attribute><xsl:value-of select="."/></edition>
|
||||
</xsl:for-each>
|
||||
</editions>
|
||||
</book>
|
||||
</xsl:for-each>
|
||||
</books>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
+2
@@ -6,5 +6,7 @@
|
||||
<xwork>
|
||||
<include file="xwork-test-beans.xml" />
|
||||
<include file="com/opensymphony/xwork2/config/providers/xwork-test-wildcard-*.xml" />
|
||||
<!-- config file defined inside xwork-jar.jar -->
|
||||
<include file="xwork-jar.xml" />
|
||||
<package name="default-wildcard" />
|
||||
</xwork>
|
||||
@@ -9,5 +9,6 @@
|
||||
<Root level="info">
|
||||
<AppenderRef ref="STDOUT"/>
|
||||
</Root>
|
||||
<Logger name="org.apache.struts2.views.xslt" level="debug"/>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
@@ -26,6 +26,14 @@
|
||||
<interceptor-ref name="defaultStack"/>
|
||||
</action>
|
||||
|
||||
<action name="LazyFoo" class="com.opensymphony.xwork2.SimpleAction">
|
||||
<result name="error" type="void" />
|
||||
<interceptor-ref name="params"/>
|
||||
<interceptor-ref name="lazy">
|
||||
<param name="foo">${blah}</param>
|
||||
</interceptor-ref>
|
||||
</action>
|
||||
|
||||
<action name="WildCard" class="com.opensymphony.xwork2.SimpleAction">
|
||||
<param name="foo">17</param>
|
||||
<param name="bar">23</param>
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
|
||||
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
|
||||
<interceptor name="validation" class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>
|
||||
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
|
||||
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
|
||||
<interceptor name="test" class="com.opensymphony.xwork2.mock.MockInterceptor">
|
||||
<param name="foo">expectedFoo</param>
|
||||
</interceptor>
|
||||
<interceptor name="lazy" class="com.opensymphony.xwork2.mock.MockLazyInterceptor"/>
|
||||
|
||||
<interceptor-stack name="defaultStack">
|
||||
<interceptor-ref name="staticParams"/>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-cdi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
|
||||
+3
-1
@@ -27,6 +27,8 @@ import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.validator.ActionValidatorManager;
|
||||
import com.opensymphony.xwork2.validator.Validator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -37,7 +39,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ListValidatorsAction extends ActionSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LogManager.getLogger(ListValidatorsAction.class);
|
||||
|
||||
private String clazz;
|
||||
private String context;
|
||||
|
||||
+5
-2
@@ -22,6 +22,8 @@
|
||||
package org.apache.struts2.config_browser;
|
||||
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
@@ -35,6 +37,8 @@ import java.util.Properties;
|
||||
*/
|
||||
public class ShowJarsAction extends ActionNamesAction {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ShowJarsAction.class);
|
||||
|
||||
public List<Properties> getJarPoms() {
|
||||
try {
|
||||
return configHelper.getJarProperties();
|
||||
@@ -52,8 +56,7 @@ public class ShowJarsAction extends ActionNamesAction {
|
||||
try {
|
||||
return ClassLoaderUtil.getResources("struts-plugin.xml", ShowJarsAction.class, false);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
LOG.error("Cannot load struts-plugin.xml", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-dwr-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
|
||||
@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.result.Redirectable;
|
||||
import org.apache.struts2.result.ServletActionRedirectResult;
|
||||
|
||||
/**
|
||||
@@ -24,7 +25,7 @@ import org.apache.struts2.result.ServletActionRedirectResult;
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
public class JSONActionRedirectResult extends ServletActionRedirectResult {
|
||||
public class JSONActionRedirectResult extends ServletActionRedirectResult implements Redirectable {
|
||||
|
||||
private static final long serialVersionUID = 3107276294073879542L;
|
||||
|
||||
|
||||
@@ -39,36 +39,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>Serializes validation and action errors into JSON. This interceptor does not
|
||||
* Serializes validation and action errors into JSON. This interceptor does not
|
||||
* perform any validation, so it must follow the 'validation' interceptor on the stack.
|
||||
* </p>
|
||||
*
|
||||
* <p>This stack (defined in struts-default.xml) shows how to use this interceptor with the
|
||||
* 'validation' interceptor</p>
|
||||
* <pre>
|
||||
* <interceptor-stack name="jsonValidationWorkflowStack">
|
||||
* <interceptor-ref name="basicStack"/>
|
||||
* <interceptor-ref name="validation">
|
||||
* <param name="excludeMethods">input,back,cancel</param>
|
||||
* </interceptor-ref>
|
||||
* <interceptor-ref name="jsonValidation"/>
|
||||
* <interceptor-ref name="workflow"/>
|
||||
* </interceptor-stack>
|
||||
* </pre>
|
||||
* <p>If 'validationFailedStatus' is set it will be used as the Response status
|
||||
* when validation fails.</p>
|
||||
*
|
||||
* <p>If the request has a parameter 'struts.validateOnly' execution will return after
|
||||
* validation (action won't be executed).</p>
|
||||
*
|
||||
* <p>If 'struts.validateOnly' is set to false you may want to use {@link JSONActionRedirectResult}.</p>
|
||||
*
|
||||
* <p>A request parameter named 'struts.enableJSONValidation' must be set to 'true' to
|
||||
* use this interceptor</p>
|
||||
*
|
||||
* <p>If the request has a parameter 'struts.JSONValidation.set.encoding' set to true
|
||||
* the character encoding will NOT be set on the response - is needed in portlet environment
|
||||
* - for more details see issue WW-3237</p>
|
||||
*/
|
||||
public class JSONValidationInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
@@ -80,16 +52,10 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
public static final String DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
private int validationFailedStatus = -1;
|
||||
|
||||
/**
|
||||
* HTTP status that will be set in the response if validation fails
|
||||
*
|
||||
* @param validationFailedStatus validation failed status
|
||||
*/
|
||||
public void setValidationFailedStatus(int validationFailedStatus) {
|
||||
this.validationFailedStatus = validationFailedStatus;
|
||||
}
|
||||
private int validationFailedStatus = HttpServletResponse.SC_BAD_REQUEST;
|
||||
private String validateOnlyParam = VALIDATE_ONLY_PARAM;
|
||||
private String validateJsonParam = VALIDATE_JSON_PARAM;
|
||||
private String noEncodingSetParam = NO_ENCODING_SET_PARAM;
|
||||
|
||||
@Override
|
||||
protected String doIntercept(ActionInvocation invocation) throws Exception {
|
||||
@@ -121,13 +87,9 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
private void setupEncoding(HttpServletResponse response, HttpServletRequest request) {
|
||||
if (isSetEncoding(request)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Default encoding not set!");
|
||||
}
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Setting up encoding to: [" + DEFAULT_ENCODING + "]!");
|
||||
}
|
||||
LOG.debug("Setting up encoding to: [{}]!", DEFAULT_ENCODING);
|
||||
response.setCharacterEncoding(DEFAULT_ENCODING);
|
||||
}
|
||||
}
|
||||
@@ -143,16 +105,16 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
|
||||
return Action.NONE;
|
||||
}
|
||||
|
||||
private boolean isJsonEnabled(HttpServletRequest request) {
|
||||
return "true".equals(request.getParameter(VALIDATE_JSON_PARAM));
|
||||
public boolean isJsonEnabled(HttpServletRequest request) {
|
||||
return Boolean.parseBoolean(request.getParameter(validateJsonParam));
|
||||
}
|
||||
|
||||
private boolean isValidateOnly(HttpServletRequest request) {
|
||||
return "true".equals(request.getParameter(VALIDATE_ONLY_PARAM));
|
||||
public boolean isValidateOnly(HttpServletRequest request) {
|
||||
return Boolean.parseBoolean(request.getParameter(validateOnlyParam));
|
||||
}
|
||||
|
||||
private boolean isSetEncoding(HttpServletRequest request) {
|
||||
return "true".equals(request.getParameter(NO_ENCODING_SET_PARAM));
|
||||
public boolean isSetEncoding(HttpServletRequest request) {
|
||||
return Boolean.parseBoolean(request.getParameter(noEncodingSetParam));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,4 +184,40 @@ public class JSONValidationInterceptor extends MethodFilterInterceptor {
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP status that will be set in the response if validation fails
|
||||
*
|
||||
* @param validationFailedStatus validation failed status
|
||||
*/
|
||||
public void setValidationFailedStatus(int validationFailedStatus) {
|
||||
this.validationFailedStatus = validationFailedStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides 'struts.validateOnly' param name
|
||||
*
|
||||
* @param validateOnlyParam new param name
|
||||
*/
|
||||
public void setValidateOnlyParam(String validateOnlyParam) {
|
||||
this.validateOnlyParam = validateOnlyParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides 'struts.enableJSONValidation' param name
|
||||
*
|
||||
* @param validateJsonParam new param name
|
||||
*/
|
||||
public void setValidateJsonParam(String validateJsonParam) {
|
||||
this.validateJsonParam = validateJsonParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides 'struts.JSONValidation.no.encoding' param name
|
||||
*
|
||||
* @param noEncodingSetParam new param name
|
||||
*/
|
||||
public void setNoEncodingSetParam(String noEncodingSetParam) {
|
||||
this.noEncodingSetParam = noEncodingSetParam;
|
||||
}
|
||||
}
|
||||
|
||||
+48
-1
@@ -63,7 +63,6 @@ public class JSONValidationInterceptorTest extends StrutsTestCase {
|
||||
request.setParameterMap(parameters);
|
||||
|
||||
validationInterceptor.intercept(invocation);
|
||||
interceptor.setValidationFailedStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
interceptor.intercept(invocation);
|
||||
|
||||
String json = stringWriter.toString();
|
||||
@@ -131,6 +130,54 @@ public class JSONValidationInterceptorTest extends StrutsTestCase {
|
||||
assertEquals("UTF-8", response.getCharacterEncoding());
|
||||
}
|
||||
|
||||
public void testValidationSucceedsWithDifferentParamName() throws Exception {
|
||||
JSONValidationInterceptor interceptor = new JSONValidationInterceptor();
|
||||
interceptor.setValidateJsonParam("enableJSONValidation");
|
||||
|
||||
action.setText("abcd@ggg.com");
|
||||
action.setPassword("apassword");
|
||||
action.setValue(10);
|
||||
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("enableJSONValidation", "true");
|
||||
request.setParameterMap(parameters);
|
||||
|
||||
validationInterceptor.intercept(invocation);
|
||||
interceptor.intercept(invocation);
|
||||
|
||||
String json = stringWriter.toString();
|
||||
|
||||
String normalizedActual = TestUtils.normalize(json, true);
|
||||
assertEquals("", normalizedActual);
|
||||
}
|
||||
|
||||
public void testValidationSucceedsValidateOnlyWithDifferentParamName() throws Exception {
|
||||
JSONValidationInterceptor interceptor = new JSONValidationInterceptor();
|
||||
interceptor.setValidateOnlyParam("validateOnly");
|
||||
interceptor.setValidateJsonParam("enableJSONValidation");
|
||||
|
||||
action.setText("abcd@ggg.com");
|
||||
action.setPassword("apassword");
|
||||
action.setValue(10);
|
||||
|
||||
//just validate
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("validateOnly", "true");
|
||||
parameters.put("enableJSONValidation", "true");
|
||||
request.setParameterMap(parameters);
|
||||
|
||||
validationInterceptor.intercept(invocation);
|
||||
interceptor.intercept(invocation);
|
||||
|
||||
String json = stringWriter.toString();
|
||||
|
||||
String normalizedActual = TestUtils.normalize(json, true);
|
||||
assertEquals("{}", normalizedActual);
|
||||
assertFalse(action.isExecuted());
|
||||
assertEquals("application/json", response.getContentType());
|
||||
assertEquals("UTF-8", response.getCharacterEncoding());
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ActionConfig config = new ActionConfig.Builder("", "name", "").build();
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-oval-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-pell-multipart-plugin</artifactId>
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ public class PellMultiPartRequest extends AbstractMultiPartRequest {
|
||||
synchronized (this) {
|
||||
setEncoding();
|
||||
if (maxSizeProvided){
|
||||
multi = new ServletMultipartRequest(servletRequest, saveDir, maxSize);
|
||||
int intMaxSize = (maxSize >= Integer.MAX_VALUE ? Integer.MAX_VALUE : Long.valueOf(maxSize).intValue());
|
||||
multi = new ServletMultipartRequest(servletRequest, saveDir, intMaxSize);
|
||||
}else{
|
||||
multi = new ServletMultipartRequest(servletRequest, saveDir);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plexus-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-tiles-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@ package org.apache.struts2.rest;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.ModelDriven;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
|
||||
@@ -35,7 +35,7 @@ import java.io.InputStreamReader;
|
||||
/**
|
||||
* Uses the content handler to apply the request body to the action
|
||||
*/
|
||||
public class ContentTypeInterceptor implements Interceptor {
|
||||
public class ContentTypeInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
ContentTypeHandlerManager selector;
|
||||
@@ -45,10 +45,6 @@ public class ContentTypeInterceptor implements Interceptor {
|
||||
this.selector = sel;
|
||||
}
|
||||
|
||||
public void destroy() {}
|
||||
|
||||
public void init() {}
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
HttpServletRequest request = ServletActionContext.getRequest();
|
||||
ContentTypeHandler handler = selector.getHandlerForRequest(request);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-spring-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-testng-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-tiles-plugin</artifactId>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.7</version>
|
||||
<version>2.5.10</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Struts 2</name>
|
||||
<url>http://struts.apache.org/</url>
|
||||
@@ -31,7 +31,7 @@
|
||||
<connection>scm:git:git://git.apache.org/struts.git</connection>
|
||||
<developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/struts.git</developerConnection>
|
||||
<url>http://git.apache.org/struts.git</url>
|
||||
<tag>STRUTS_2_5_7</tag>
|
||||
<tag>STRUTS_2_5_10</tag>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
@@ -699,6 +699,12 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.1</version>
|
||||
</dependency>
|
||||
<!-- it's a dependency of Velocity defined here to override the transitive one -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user