mirror of
https://github.com/apache/struts.git
synced 2026-08-08 16:16:58 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0b3a1d213 | |||
| 2306f5f7fa | |||
| ed7f9dd4cb | |||
| cf53b59647 | |||
| 6dd6e5cfb7 | |||
| b9a0c497d3 | |||
| 2f95b9a130 | |||
| 103e3b174e | |||
| 2776b34b44 | |||
| 287e3bc8cb | |||
| 677ccebe83 | |||
| f11ac901d3 | |||
| 3fddfb6eb5 | |||
| 744c1f409d | |||
| 54a4dce7bf | |||
| 16eb7fa768 | |||
| 631ce98d17 | |||
| 086b637355 | |||
| ae56301979 | |||
| 73da12e723 | |||
| 583da3d5df | |||
| 9e8627ca66 | |||
| c349dfa5ab | |||
| 4d888a5ab6 | |||
| 1ed29d508f | |||
| 3523064939 | |||
| 54dff362f5 | |||
| b12864dd38 | |||
| de90290354 | |||
| ba0563183b | |||
| b348fc552c | |||
| 81371e09c5 | |||
| 431e50e922 | |||
| 156db8e5df | |||
| 6f5ddca471 | |||
| cc0d52f216 | |||
| 23e0181328 | |||
| 030ffa3354 | |||
| 8e67b9144a | |||
| 77017cd677 | |||
| 7d8c3598ef | |||
| 83bb64f4c2 | |||
| ae2840f183 | |||
| e8b48f8bb4 | |||
| 3243448084 | |||
| 5c61c9a575 | |||
| e40dcaa3f4 | |||
| ab6acd2382 | |||
| bf0a01d390 | |||
| 00c47b7ce6 | |||
| c84810ff82 | |||
| 2ea59b31b4 | |||
| fae1e0e799 | |||
| e4ce3ce839 | |||
| 730441b7a7 |
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-blank</artifactId>
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.apache.struts2.interceptor.validation.SkipValidation;
|
||||
|
||||
public class Login extends ExampleSupport {
|
||||
|
||||
@Override
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jboss-blank</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-mailreader</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet</artifactId>
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ public class SaveGangsterAction extends Action {
|
||||
// Some code to save the gangster to the db as necessary
|
||||
GangsterForm gform = (GangsterForm) form;
|
||||
ActionMessages messages = new ActionMessages();
|
||||
messages.add("msg", new ActionMessage("Gangster " + gform.getName() + " added successfully"));
|
||||
System.out.println(gform.getName());
|
||||
messages.add("msg", new ActionMessage("struts1.gangsterAdded", gform.getName()));
|
||||
addMessages(request, messages);
|
||||
|
||||
return mapping.findForward("success");
|
||||
|
||||
@@ -7,3 +7,5 @@ item.create=Create {0}
|
||||
item.list={0} List
|
||||
|
||||
token.transfer.time=The bank transfer was executed at {0,date,HH:mm:ss MM-dd-yyyy}
|
||||
|
||||
struts1.gangsterAdded=Gangster {0} added successfully
|
||||
@@ -5,3 +5,5 @@ item.create={0} neu anlegen
|
||||
item.list={0}-Liste
|
||||
|
||||
token.transfer.time=Die \u00dcberweisung wurde am {0,date,HH:mm:ss MM-dd-yyyy} durchgef\u00fchrt
|
||||
|
||||
struts1.gangsterAdded=Gangster {0} wurde erfolgreich hinzugefugt
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
struts1.gangsterAdded=Gangster {0} anadido con exito
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -25,7 +25,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>2.3.29</struts-version.version>
|
||||
<struts-version.version>2.3.34</struts-version.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -197,6 +197,6 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<tag>STRUTS_2_3_29</tag>
|
||||
<tag>STRUTS_2_3_34</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -272,6 +272,13 @@ public final class StrutsConstants {
|
||||
|
||||
/** actions names' whitelist **/
|
||||
public static final String STRUTS_ALLOWED_ACTION_NAMES = "struts.allowed.action.names";
|
||||
/** default action name to use when action didn't match the whitelist **/
|
||||
public static final String STRUTS_DEFAULT_ACTION_NAME = "struts.default.action.name";
|
||||
|
||||
/** methods names' whitelist **/
|
||||
public static final String STRUTS_ALLOWED_METHOD_NAMES = "struts.allowed.method.names";
|
||||
/** default method name to use when method didn't match the whitelist **/
|
||||
public static final String STRUTS_DEFAULT_METHOD_NAME = "struts.default.method.name";
|
||||
|
||||
/** enables action: prefix **/
|
||||
public static final String STRUTS_MAPPER_ACTION_PREFIX_ENABLED = "struts.mapper.action.prefix.enabled";
|
||||
|
||||
@@ -22,14 +22,12 @@
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.LocaleProvider;
|
||||
import com.opensymphony.xwork2.TextProviderFactory;
|
||||
import com.opensymphony.xwork2.TextProvider;
|
||||
@@ -95,6 +93,8 @@ public class I18n extends Component {
|
||||
protected String name;
|
||||
protected Container container;
|
||||
private TextProvider textProvider;
|
||||
private TextProvider defaultTextProvider;
|
||||
private LocaleProvider localeProvider;
|
||||
|
||||
public I18n(ValueStack stack) {
|
||||
super(stack);
|
||||
@@ -105,26 +105,31 @@ public class I18n extends Component {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setTextProvider(TextProvider textProvider) {
|
||||
this.defaultTextProvider = textProvider;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setLocaleProvider(LocaleProvider localeProvider) {
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
public boolean start(Writer writer) {
|
||||
boolean result = super.start(writer);
|
||||
|
||||
try {
|
||||
String name = this.findString(this.name, "name", "Resource bundle name is required. Example: foo or foo_en");
|
||||
ResourceBundle bundle = (ResourceBundle) findValue("getTexts('" + name + "')");
|
||||
ResourceBundle bundle = defaultTextProvider.getTexts(name);
|
||||
|
||||
if (bundle == null) {
|
||||
bundle = LocalizedTextUtil.findResourceBundle(name, (Locale) getStack().getContext().get(ActionContext.LOCALE));
|
||||
bundle = LocalizedTextUtil.findResourceBundle(name, localeProvider.getLocale());
|
||||
}
|
||||
|
||||
if (bundle != null) {
|
||||
final Locale locale = (Locale) getStack().getContext().get(ActionContext.LOCALE);
|
||||
TextProviderFactory tpf = new TextProviderFactory();
|
||||
container.inject(tpf);
|
||||
textProvider = tpf.createInstance(bundle, new LocaleProvider() {
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
});
|
||||
textProvider = tpf.createInstance(bundle, localeProvider);
|
||||
getStack().push(textProvider);
|
||||
pushed = true;
|
||||
}
|
||||
|
||||
@@ -649,6 +649,7 @@ public abstract class UIBean extends Component {
|
||||
addParameter("themeExpansionToken", uiThemeExpansionToken);
|
||||
addParameter("expandTheme", uiThemeExpansionToken + theme);
|
||||
|
||||
String name = null;
|
||||
String providedLabel = null;
|
||||
|
||||
if (this.key != null) {
|
||||
@@ -665,7 +666,8 @@ public abstract class UIBean extends Component {
|
||||
}
|
||||
|
||||
if (this.name != null) {
|
||||
addParameter("name", findString(this.name));
|
||||
name = findString(this.name);
|
||||
addParameter("name", name);
|
||||
}
|
||||
|
||||
if (label != null) {
|
||||
|
||||
@@ -22,6 +22,8 @@ package org.apache.struts2.dispatcher;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
@@ -39,6 +41,7 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
@@ -93,6 +96,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
|
||||
*/
|
||||
protected String encoding;
|
||||
|
||||
protected boolean devMode;
|
||||
|
||||
/**
|
||||
* Modify state of StrutsConstants.STRUTS_SERVE_STATIC_CONTENT setting.
|
||||
@@ -101,29 +105,34 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
|
||||
* New setting
|
||||
*/
|
||||
@Inject(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT)
|
||||
public void setServeStaticContent(String val) {
|
||||
serveStatic = "true".equals(val);
|
||||
public void setServeStaticContent(String serveStaticContent) {
|
||||
this.serveStatic = BooleanUtils.toBoolean(serveStaticContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify state of StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE
|
||||
* setting.
|
||||
*
|
||||
* @param val
|
||||
* @param serveStaticBrowserCache
|
||||
* New setting
|
||||
*/
|
||||
@Inject(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE)
|
||||
public void setServeStaticBrowserCache(String val) {
|
||||
serveStaticBrowserCache = "true".equals(val);
|
||||
public void setServeStaticBrowserCache(String serveStaticBrowserCache) {
|
||||
this.serveStaticBrowserCache = BooleanUtils.toBoolean(serveStaticBrowserCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
|
||||
* @param val New setting
|
||||
* @param encoding New setting
|
||||
*/
|
||||
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
|
||||
public void setEncoding(String val) {
|
||||
encoding = val;
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_DEVMODE)
|
||||
public void setDevMode(String devMode) {
|
||||
this.devMode = Boolean.parseBoolean(devMode);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -141,7 +150,16 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
|
||||
}
|
||||
|
||||
protected String getAdditionalPackages() {
|
||||
return "org.apache.struts2.static template org.apache.struts2.interceptor.debugging static";
|
||||
List<String> packages = new LinkedList<String>();
|
||||
packages.add("org.apache.struts2.static");
|
||||
packages.add("template");
|
||||
packages.add("static");
|
||||
|
||||
if (devMode) {
|
||||
packages.add("org.apache.struts2.interceptor.debugging");
|
||||
}
|
||||
|
||||
return StringUtils.join(packages.iterator(), ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,7 +291,7 @@ public class DefaultStaticContentLoader implements StaticContentLoader {
|
||||
* @param name resource name
|
||||
* @param packagePrefix The package prefix to use to locate the resource
|
||||
* @return full path
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws UnsupportedEncodingException If there is a encoding problem
|
||||
*/
|
||||
protected String buildPath(String name, String packagePrefix) throws UnsupportedEncodingException {
|
||||
String resourcePath;
|
||||
|
||||
@@ -211,7 +211,11 @@ public class Dispatcher {
|
||||
*/
|
||||
@Inject(StrutsConstants.STRUTS_DEVMODE)
|
||||
public void setDevMode(String mode) {
|
||||
devMode = "true".equals(mode);
|
||||
devMode = Boolean.parseBoolean(mode);
|
||||
}
|
||||
|
||||
public boolean isDevMode() {
|
||||
return devMode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,6 +269,10 @@ public class Dispatcher {
|
||||
this.handleException = Boolean.parseBoolean(handleException);
|
||||
}
|
||||
|
||||
public boolean isHandleException() {
|
||||
return handleException;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setDispatcherErrorHandler(DispatcherErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
|
||||
@@ -121,6 +121,11 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
protected boolean alwaysSelectFullNamespace = false;
|
||||
protected PrefixTrie prefixTrie = null;
|
||||
protected Pattern allowedActionNames = Pattern.compile("[a-zA-Z0-9._!/\\-]*");
|
||||
protected String defaultActionName = "index";
|
||||
|
||||
protected Pattern allowedMethodNames = Pattern.compile("[a-zA-Z_]*[0-9]*");
|
||||
protected String defaultMethodName = "execute";
|
||||
|
||||
private boolean allowActionPrefix = false;
|
||||
private boolean allowActionCrossNamespaceAccess = false;
|
||||
|
||||
@@ -137,7 +142,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
put(METHOD_PREFIX, new ParameterAction() {
|
||||
public void execute(String key, ActionMapping mapping) {
|
||||
if (allowDynamicMethodCalls) {
|
||||
mapping.setMethod(cleanupActionName(key.substring(METHOD_PREFIX.length())));
|
||||
mapping.setMethod(cleanupMethodName(key.substring(METHOD_PREFIX.length())));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -149,7 +154,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
if (allowDynamicMethodCalls) {
|
||||
int bang = name.indexOf('!');
|
||||
if (bang != -1) {
|
||||
String method = cleanupActionName(name.substring(bang + 1));
|
||||
String method = cleanupMethodName(name.substring(bang + 1));
|
||||
mapping.setMethod(method);
|
||||
name = name.substring(0, bang);
|
||||
}
|
||||
@@ -205,6 +210,21 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
this.allowedActionNames = Pattern.compile(allowedActionNames);
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_DEFAULT_ACTION_NAME, required = false)
|
||||
public void setDefaultActionName(String defaultActionName) {
|
||||
this.defaultActionName = defaultActionName;
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_ALLOWED_METHOD_NAMES, required = false)
|
||||
public void setAllowedMethodNames(String allowedMethodNames) {
|
||||
this.allowedMethodNames = Pattern.compile(allowedMethodNames);
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_DEFAULT_METHOD_NAME, required = false)
|
||||
public void setDefaultMethodName(String defaultMethodName) {
|
||||
this.defaultMethodName = defaultMethodName;
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_MAPPER_ACTION_PREFIX_ENABLED)
|
||||
public void setAllowActionPrefix(String allowActionPrefix) {
|
||||
this.allowActionPrefix = "true".equalsIgnoreCase(allowActionPrefix);
|
||||
@@ -376,7 +396,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up action name from suspicious characters
|
||||
* Checks action name against allowed pattern if not matched returns default action name
|
||||
*
|
||||
* @param rawActionName action name extracted from URI
|
||||
* @return safe action name
|
||||
@@ -385,7 +405,23 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
if (allowedActionNames.matcher(rawActionName).matches()) {
|
||||
return rawActionName;
|
||||
} else {
|
||||
throw new StrutsException("Action [" + rawActionName + "] does not match allowed action names pattern [" + allowedActionNames + "]!");
|
||||
LOG.warn("{} did not match allowed action names {} - default action {} will be used!", rawActionName, allowedActionNames, defaultActionName);
|
||||
return defaultActionName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks method name (when DMI is enabled) against allowed pattern if not matched returns default action name
|
||||
*
|
||||
* @param rawMethodName method name extracted from URI
|
||||
* @return safe method name
|
||||
*/
|
||||
protected String cleanupMethodName(final String rawMethodName) {
|
||||
if (allowedMethodNames.matcher(rawMethodName).matches()) {
|
||||
return rawMethodName;
|
||||
} else {
|
||||
LOG.warn("{} did not match allowed method names {} - default method {} will be used!", rawMethodName, allowedMethodNames, defaultMethodName);
|
||||
return defaultMethodName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -120,7 +120,11 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
}
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processUpload(HttpServletRequest request, String saveDir) throws FileUploadException, UnsupportedEncodingException {
|
||||
|
||||
+5
-1
@@ -539,7 +539,11 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
String errorKey = "struts.message.upload.error." + e.getClass().getSimpleName();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-1
@@ -108,7 +108,11 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Preparing error message for key: [#0]", errorKey);
|
||||
}
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
if (LocalizedTextUtil.findText(this.getClass(), errorKey, getLocale(), null, new Object[0]) == null) {
|
||||
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
|
||||
} else {
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -168,7 +168,9 @@ public class PrepareOperations {
|
||||
request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
dispatcher.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
|
||||
if (dispatcher.isHandleException() || dispatcher.isDevMode()) {
|
||||
dispatcher.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,11 +44,11 @@ public class ComponentUtils {
|
||||
* @return true if it is an expression
|
||||
*/
|
||||
public static boolean isExpression(String expr) {
|
||||
return expr.startsWith("%{") && expr.endsWith("}");
|
||||
return expr != null && expr.startsWith("%{") && expr.endsWith("}");
|
||||
}
|
||||
|
||||
public static boolean containsExpression(String expr) {
|
||||
return expr.contains("%{") && expr.contains("}");
|
||||
return expr != null && expr.contains("%{") && expr.contains("}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,4 +19,16 @@ public class URLDecoderUtil {
|
||||
return UDecoder.URLDecode(sequence, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a <code>x-www-form-urlencoded</code> string.
|
||||
* @param sequence the String to decode
|
||||
* @param charset The name of a supported character encoding.
|
||||
* @param isQueryString whether input is a query string. If <code>true</code> other decoding rules apply.
|
||||
* @return the newly decoded <code>String</code>
|
||||
* @exception IllegalArgumentException If the encoding is not valid
|
||||
*/
|
||||
public static String decode(String sequence, String charset, boolean isQueryString) {
|
||||
return UDecoder.URLDecode(sequence, charset, isQueryString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import freemarker.cache.FileTemplateLoader;
|
||||
import freemarker.cache.MultiTemplateLoader;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.cache.WebappTemplateLoader;
|
||||
import freemarker.core.TemplateClassResolver;
|
||||
import freemarker.ext.jsp.TaglibFactory;
|
||||
import freemarker.ext.servlet.HttpRequestHashModel;
|
||||
import freemarker.ext.servlet.HttpRequestParametersHashModel;
|
||||
@@ -344,6 +345,9 @@ public class FreemarkerManager {
|
||||
configuration.setLocalizedLookup(false);
|
||||
configuration.setWhitespaceStripping(true);
|
||||
|
||||
LOG.debug("Sets NewBuiltinClassResolver to TemplateClassResolver.SAFER_RESOLVER");
|
||||
configuration.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,18 @@ package org.apache.struts2.views.util;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
@@ -179,9 +191,9 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
|
||||
//if the action was not explicitly set grab the params from the request
|
||||
if (escapeAmp) {
|
||||
buildParametersString(params, link, AMP);
|
||||
buildParametersString(params, link, AMP, true);
|
||||
} else {
|
||||
buildParametersString(params, link, "&");
|
||||
buildParametersString(params, link, "&", true);
|
||||
}
|
||||
|
||||
String result = link.toString();
|
||||
@@ -202,6 +214,10 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
}
|
||||
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator) {
|
||||
buildParametersString(params, link, paramSeparator, true);
|
||||
}
|
||||
|
||||
public void buildParametersString(Map<String, Object> params, StringBuilder link, String paramSeparator, boolean encode) {
|
||||
if ((params != null) && (params.size() > 0)) {
|
||||
if (!link.toString().contains("?")) {
|
||||
link.append("?");
|
||||
@@ -219,7 +235,7 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
if (value instanceof Iterable) {
|
||||
for (Iterator iterator = ((Iterable) value).iterator(); iterator.hasNext();) {
|
||||
Object paramValue = iterator.next();
|
||||
link.append(buildParameterSubstring(name, paramValue != null ? paramValue.toString() : StringUtils.EMPTY));
|
||||
link.append(buildParameterSubstring(name, paramValue != null ? paramValue.toString() : StringUtils.EMPTY, encode));
|
||||
|
||||
if (iterator.hasNext()) {
|
||||
link.append(paramSeparator);
|
||||
@@ -229,14 +245,14 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
Object[] array = (Object[]) value;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
Object paramValue = array[i];
|
||||
link.append(buildParameterSubstring(name, paramValue != null ? paramValue.toString() : StringUtils.EMPTY));
|
||||
link.append(buildParameterSubstring(name, paramValue != null ? paramValue.toString() : StringUtils.EMPTY, encode));
|
||||
|
||||
if (i < array.length - 1) {
|
||||
link.append(paramSeparator);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
link.append(buildParameterSubstring(name, value != null ? value.toString() : StringUtils.EMPTY));
|
||||
link.append(buildParameterSubstring(name, value != null ? value.toString() : StringUtils.EMPTY, encode));
|
||||
}
|
||||
|
||||
if (iter.hasNext()) {
|
||||
@@ -250,11 +266,11 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
return HTTP_PROTOCOL.equals(scheme) || HTTPS_PROTOCOL.equals(scheme);
|
||||
}
|
||||
|
||||
private String buildParameterSubstring(String name, String value) {
|
||||
private String buildParameterSubstring(String name, String value, boolean encode) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(encode(name));
|
||||
builder.append(encode ? encode(name) : name);
|
||||
builder.append('=');
|
||||
builder.append(encode(value));
|
||||
builder.append(encode ? encode(value) : value);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -283,7 +299,7 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
*/
|
||||
public String decode( String input ) {
|
||||
try {
|
||||
return URLDecoderUtil.decode(input, encoding);
|
||||
return URLDecoderUtil.decode(input, encoding, false);
|
||||
} catch (Exception e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not decode URL parameter '#0', returning value un-decoded", input);
|
||||
@@ -292,6 +308,22 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the URL using {@link URLDecoderUtil#decode(String, String, boolean)} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input the input to decode
|
||||
* @param isQueryString whether input is a query string. If <code>true</code> other decoding rules apply.
|
||||
* @return the encoded string
|
||||
*/
|
||||
public String decode( String input, boolean isQueryString ) {
|
||||
try {
|
||||
return URLDecoderUtil.decode(input, encoding, isQueryString);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not decode URL parameter '{}', returning value un-decoded", input);
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> parseQueryString(String queryString, boolean forceValueArray) {
|
||||
Map<String, Object> queryParams = new LinkedHashMap<String, Object>();
|
||||
if (queryString != null) {
|
||||
@@ -308,8 +340,8 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
paramName = decode(paramName);
|
||||
String translatedParamValue = decode(paramValue);
|
||||
paramName = decode(paramName, true);
|
||||
String translatedParamValue = decode(paramValue, true);
|
||||
|
||||
if (queryParams.containsKey(paramName) || forceValueArray) {
|
||||
// WW-1619 append new param value to existing value(s)
|
||||
|
||||
@@ -164,21 +164,4 @@ public class UIBeanTest extends StrutsInternalTestCase {
|
||||
assertEquals("12", txtFld.getTheme());
|
||||
}
|
||||
|
||||
// I couldn't figure out how to make this test work. Bailing for now.
|
||||
// public void testEscapeLabel() throws Exception {
|
||||
// ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
// MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
// MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
// stack.push(this);
|
||||
//
|
||||
// TextField txtFld = new TextField(stack, req, res);
|
||||
// txtFld.setKey("test['foo']");
|
||||
// txtFld.evaluateParams();
|
||||
// assertEquals("test_label", txtFld.getParameters().get("label"));
|
||||
// }
|
||||
//
|
||||
// public String getText(String key) {
|
||||
// assertEquals("test[\\'foo\\']", key);
|
||||
// return "test_label";
|
||||
// }
|
||||
}
|
||||
|
||||
+18
-26
@@ -845,37 +845,14 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
|
||||
String actionName = "action";
|
||||
assertEquals(actionName, mapper.cleanupActionName(actionName));
|
||||
|
||||
Throwable expected = null;
|
||||
|
||||
actionName = "${action}";
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${action}] does not match allowed action names pattern [" + mapper.allowedActionNames.pattern() + "]!", expected.getMessage());
|
||||
assertEquals(mapper.defaultActionName, mapper.cleanupActionName(actionName));
|
||||
|
||||
actionName = "${${%{action}}}";
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${${%{action}}}] does not match allowed action names pattern [" + mapper.allowedActionNames.pattern() + "]!", expected.getMessage());
|
||||
assertEquals(mapper.defaultActionName, mapper.cleanupActionName(actionName));
|
||||
|
||||
actionName = "${#foo='action',#foo}";
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${#foo='action',#foo}] does not match allowed action names pattern [" + mapper.allowedActionNames.pattern() + "]!", expected.getMessage());
|
||||
assertEquals(mapper.defaultActionName, mapper.cleanupActionName(actionName));
|
||||
|
||||
actionName = "test-action";
|
||||
assertEquals("test-action", mapper.cleanupActionName(actionName));
|
||||
@@ -887,4 +864,19 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
|
||||
assertEquals("test!bar.action", mapper.cleanupActionName(actionName));
|
||||
}
|
||||
|
||||
public void testAllowedMethodNames() throws Exception {
|
||||
DefaultActionMapper mapper = new DefaultActionMapper();
|
||||
|
||||
assertEquals("", mapper.cleanupMethodName(""));
|
||||
assertEquals("test", mapper.cleanupMethodName("test"));
|
||||
assertEquals("test_method", mapper.cleanupMethodName("test_method"));
|
||||
assertEquals("_test", mapper.cleanupMethodName("_test"));
|
||||
assertEquals("test1", mapper.cleanupMethodName("test1"));
|
||||
|
||||
assertEquals(mapper.defaultMethodName, mapper.cleanupMethodName("2test"));
|
||||
assertEquals(mapper.defaultMethodName, mapper.cleanupMethodName("%{exp}"));
|
||||
assertEquals(mapper.defaultMethodName, mapper.cleanupMethodName("${%{foo}}"));
|
||||
assertEquals(mapper.defaultMethodName, mapper.cleanupMethodName("${#foo='method',#foo}"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -93,6 +93,10 @@ public class ComponentUtilsTest extends StrutsInternalTestCase {
|
||||
assertFalse(actual);
|
||||
}
|
||||
|
||||
public void testIsExpressionIsFalseWhenNull() throws Exception {
|
||||
assertFalse(ComponentUtils.isExpression(null));
|
||||
}
|
||||
|
||||
public void testContainsExpressionIsTrue() throws Exception {
|
||||
// given
|
||||
String anExpression = "%{foo}";
|
||||
@@ -125,6 +129,10 @@ public class ComponentUtilsTest extends StrutsInternalTestCase {
|
||||
// then
|
||||
assertFalse(actual);
|
||||
}
|
||||
|
||||
public void testContainsExpressionIsFalseWhenNull() throws Exception {
|
||||
assertFalse(ComponentUtils.containsExpression(null));
|
||||
}
|
||||
}
|
||||
|
||||
class MockConfigurationProvider implements ConfigurationProvider {
|
||||
|
||||
@@ -68,4 +68,11 @@ public class URLDecoderUtilTest {
|
||||
assertEquals("xxxx\u00ea", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testURLDecodePlusCharAsSpace() {
|
||||
|
||||
String result = URLDecoderUtil.decode("a+b", "UTF-8", true);
|
||||
assertEquals("a b", result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -281,4 +281,20 @@ public class TextfieldTest extends AbstractUITagTest {
|
||||
verify(TextFieldTag.class.getResource("Textfield-11.txt"));
|
||||
}
|
||||
|
||||
public void testNameEvaluation() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setArray(new String[]{"test", "bar"});
|
||||
testAction.setFooInt(1);
|
||||
|
||||
TextFieldTag tag = new TextFieldTag();
|
||||
tag.setPageContext(pageContext);
|
||||
tag.setName("array[%{fooInt}]");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
verify(TextFieldTag.class.getResource("Textfield-12.txt"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,21 +21,23 @@
|
||||
|
||||
package org.apache.struts2.views.util;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Scope.Strategy;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Scope.Strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Test case for DefaultUrlHelper.
|
||||
@@ -393,7 +395,15 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase {
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
}
|
||||
|
||||
|
||||
public void testDecodeSpacesInQueryString() throws Exception {
|
||||
Map<String, Object> queryParameters = urlHelper.parseQueryString("name=value+with+space", false);
|
||||
|
||||
assertTrue(queryParameters.containsKey("name"));
|
||||
assertEquals("value with space", queryParameters.get("name"));
|
||||
}
|
||||
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
stubContainer = new StubContainer(container);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<tr>
|
||||
<td class="tdLabel"></td>
|
||||
<td><input type="text" name="array[1]" value="bar" id="array_1_"/></td>
|
||||
</tr>
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-cdi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-codebehind-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ public class ShowBeansAction extends ActionNamesAction {
|
||||
|
||||
@Inject
|
||||
public void setContainer(Container container) {
|
||||
super.setContainer(container);
|
||||
bindings = new TreeMap<String, Set<Binding>>();
|
||||
bindings.put(ObjectFactory.class.getName(), addBindings(container, ObjectFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY));
|
||||
bindings.put(XWorkConverter.class.getName(), addBindings(container, XWorkConverter.class, StrutsConstants.STRUTS_XWORKCONVERTER));
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ public class ShowConstantsAction extends ActionNamesAction {
|
||||
|
||||
@Inject
|
||||
public void setContainer(Container container) {
|
||||
super.setContainer(container);
|
||||
constants = new HashMap<String, String>();
|
||||
for (String key : container.getInstanceNames(String.class)) {
|
||||
constants.put(key, container.getInstance(String.class, key));
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
-->
|
||||
<#include "tigris-macros.ftl">
|
||||
<@startPage pageTitle="Actions in namespace"/>
|
||||
<h3>Actions in <#if namespace == ""> default namespace <#else> ${namespace} </#if></h3>
|
||||
<h3>Actions in <#if namespace == ""> default namespace <#else> ${namespace?html} </#if></h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<tr><td>Action name:</td><td>${actionName}</td></tr>
|
||||
<tr><td>Namespace:</td><td> ${namespace}</td></tr>
|
||||
<tr><td>Action class:</td><td> ${config.className}</td></tr>
|
||||
<tr><td>Action method:</td><td> <#if config.methodName?exists>${config.methodName}</#if></td></tr>
|
||||
<tr><td>Action method:</td><td> <#if config.methodName??>${config.methodName}</#if></td></tr>
|
||||
<tr><td>Parameters:</td><td> <#list config.params?keys as p>
|
||||
${p}
|
||||
</#list></td></tr>
|
||||
@@ -41,9 +41,9 @@
|
||||
</table>
|
||||
|
||||
<!-- URLTag is faulty -->
|
||||
<@s.url id="url" action="showConfig" includeParams="none">
|
||||
<@s.param name="namespace">${namespace}</@s.param>
|
||||
<@s.param name="actionName">${actionName}</@s.param>
|
||||
<@s.url var="url" action="showConfig" includeParams="none">
|
||||
<@s.param name="namespace">${namespace?html}</@s.param>
|
||||
<@s.param name="actionName">${actionName?html}</@s.param>
|
||||
</@s.url>
|
||||
<#assign url = url + "&detailView=">
|
||||
<!-- Set all to false -->
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<#call startPage pageTitle="Validator Details"/>
|
||||
<table>
|
||||
<tr><td>Validated Class:</td><td>${action.stripPackage(clazz)}</td></tr>
|
||||
<tr><td>Context:</td><td>${context}</td></tr>
|
||||
<tr><td>Context:</td><td>${context?html}</td></tr>
|
||||
<tr><td>Validator Number:</td><td>${selected}</td></tr>
|
||||
<tr><td>Validator Type:</td><td>${action.stripPackage(selectedValidator.class)}</td></tr>
|
||||
</table>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
|
||||
+18
-10
@@ -43,6 +43,7 @@ import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -332,27 +333,34 @@ public class ConventionUnknownHandler implements UnknownHandler {
|
||||
Map<String, ResultTypeConfig> resultsByExtension) {
|
||||
try {
|
||||
boolean traceEnabled = LOG.isTraceEnabled();
|
||||
if (traceEnabled)
|
||||
if (traceEnabled) {
|
||||
LOG.trace("Checking ServletContext for [#0]", path);
|
||||
}
|
||||
|
||||
if (servletContext.getResource(path) != null) {
|
||||
if (traceEnabled)
|
||||
LOG.trace("Found");
|
||||
URL resource = servletContext.getResource(path);
|
||||
if (resource != null && resource.getPath().endsWith(path)) {
|
||||
if (traceEnabled) {
|
||||
LOG.trace("Found resource #0", resource);
|
||||
}
|
||||
return buildResult(path, resultCode, resultsByExtension.get(ext), actionContext);
|
||||
}
|
||||
|
||||
if (traceEnabled)
|
||||
LOG.trace("Checking ClasLoader for #0", path);
|
||||
if (traceEnabled) {
|
||||
LOG.trace("Checking ClassLoader for #0", path);
|
||||
}
|
||||
|
||||
String classLoaderPath = path.startsWith("/") ? path.substring(1, path.length()) : path;
|
||||
if (ClassLoaderUtil.getResource(classLoaderPath, getClass()) != null) {
|
||||
if (traceEnabled)
|
||||
LOG.trace("Found");
|
||||
resource = ClassLoaderUtil.getResource(classLoaderPath, getClass());
|
||||
if (resource != null && resource.getPath().endsWith(classLoaderPath)) {
|
||||
if (traceEnabled) {
|
||||
LOG.trace("Found resource #0", resource);
|
||||
}
|
||||
return buildResult(path, resultCode, resultsByExtension.get(ext), actionContext);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
if (LOG.isErrorEnabled())
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Unable to parse template path: [#0] skipping...", path);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+19
-7
@@ -107,14 +107,26 @@ public class ConventionsServiceImpl implements ConventionsService {
|
||||
public Map<String, ResultTypeConfig> getResultTypesByExtension(PackageConfig packageConfig) {
|
||||
Map<String, ResultTypeConfig> results = packageConfig.getAllResultTypeConfigs();
|
||||
|
||||
ResultTypeConfig dispatcher = disableParse(results.get("dispatcher"));
|
||||
ResultTypeConfig velocity = disableParse(results.get("velocity"));
|
||||
ResultTypeConfig freemarker = disableParse(results.get("freemarker"));
|
||||
|
||||
Map<String, ResultTypeConfig> resultsByExtension = new HashMap<String, ResultTypeConfig>();
|
||||
resultsByExtension.put("jsp", results.get("dispatcher"));
|
||||
resultsByExtension.put("jspf", results.get("dispatcher"));
|
||||
resultsByExtension.put("jspx", results.get("dispatcher"));
|
||||
resultsByExtension.put("vm", results.get("velocity"));
|
||||
resultsByExtension.put("ftl", results.get("freemarker"));
|
||||
resultsByExtension.put("html", results.get("dispatcher"));
|
||||
resultsByExtension.put("htm", results.get("dispatcher"));
|
||||
resultsByExtension.put("jsp", dispatcher);
|
||||
resultsByExtension.put("jspf", dispatcher);
|
||||
resultsByExtension.put("jspx", dispatcher);
|
||||
resultsByExtension.put("vm", velocity);
|
||||
resultsByExtension.put("ftl", freemarker);
|
||||
resultsByExtension.put("html", dispatcher);
|
||||
resultsByExtension.put("htm", dispatcher);
|
||||
return resultsByExtension;
|
||||
}
|
||||
|
||||
private ResultTypeConfig disableParse(ResultTypeConfig resultConfig) {
|
||||
if (resultConfig != null) {
|
||||
return new ResultTypeConfig.Builder(resultConfig).addParam("parse", "false").build();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -33,7 +33,7 @@ dojo.global=function(){
|
||||
return dj_currentContext;
|
||||
};
|
||||
dojo.locale=djConfig.locale;
|
||||
dojo.version={major:0,minor:4,patch:3,flag:"",revision:Number("$Rev$".match(/[0-9]+/)[0]),toString:function(){
|
||||
dojo.version={major:0,minor:4,patch:3,flag:"",revision:Number("$Rev: 670371 $".match(/[0-9]+/)[0]),toString:function(){
|
||||
with(dojo.version){
|
||||
return major+"."+minor+"."+patch+flag+" ("+revision+")";
|
||||
}
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ dojo.locale = djConfig.locale;
|
||||
dojo.version = {
|
||||
// summary: version number of this instance of dojo.
|
||||
major: 0, minor: 4, patch: 3, flag: "",
|
||||
revision: Number("$Rev$".match(/[0-9]+/)[0]),
|
||||
revision: Number("$Rev: 670371 $".match(/[0-9]+/)[0]),
|
||||
toString: function(){
|
||||
with(dojo.version){
|
||||
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ dojo.locale = djConfig.locale;
|
||||
dojo.version = {
|
||||
// summary: version number of this instance of dojo.
|
||||
major: 0, minor: 4, patch: 3, flag: "",
|
||||
revision: Number("$Rev$".match(/[0-9]+/)[0]),
|
||||
revision: Number("$Rev: 670371 $".match(/[0-9]+/)[0]),
|
||||
toString: function(){
|
||||
with(dojo.version){
|
||||
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-dwr-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-java8-support-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jsf-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-oval-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-pell-multipart-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</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.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-tiles-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.3.29</version>
|
||||
<version>2.3.34</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -58,10 +59,16 @@ public interface ContentTypeHandlerManager {
|
||||
* @param target The object to return, usually the action object
|
||||
* @return The new result code to process
|
||||
* @throws IOException If unable to write to the response
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
String handleResult(ActionConfig actionConfig, Object methodResult, Object target)
|
||||
throws IOException;
|
||||
|
||||
String handleResult(ActionInvocation actionInvocation, Object methodResult, Object target)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Finds the extension in the url
|
||||
*
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ContentTypeInterceptor implements Interceptor {
|
||||
if (request.getContentLength() > 0) {
|
||||
InputStream is = request.getInputStream();
|
||||
InputStreamReader reader = new InputStreamReader(is);
|
||||
handler.toObject(reader, target);
|
||||
handler.toObject(invocation, reader, target);
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
|
||||
+16
-4
@@ -21,9 +21,12 @@
|
||||
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
|
||||
@@ -41,6 +44,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManager {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultContentTypeHandlerManager.class);
|
||||
|
||||
/** ContentTypeHandlers keyed by the extension */
|
||||
Map<String, ContentTypeHandler> handlersByExtension = new HashMap<String, ContentTypeHandler>();
|
||||
/** ContentTypeHandlers keyed by the content-type */
|
||||
@@ -115,7 +120,7 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
|
||||
/**
|
||||
* Gets the handler for the response by looking at the extension of the request
|
||||
* @param req The request
|
||||
* @param request The request
|
||||
* @return The appropriate handler
|
||||
*
|
||||
* WW-4588: modified to get a handler for the response side and auto generate the response type
|
||||
@@ -153,20 +158,27 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
return handler;
|
||||
}
|
||||
|
||||
public String handleResult(ActionConfig actionConfig, Object methodResult, Object target) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
return readResultCode(methodResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the result using handlers to generate content type-specific content
|
||||
*
|
||||
* @param actionConfig The action config for the current request
|
||||
* @param invocation The action invocation for the current request
|
||||
* @param methodResult The object returned from the action method
|
||||
* @param target The object to return, usually the action object
|
||||
* @return The new result code to process
|
||||
* @throws IOException If unable to write to the response
|
||||
*/
|
||||
public String handleResult(ActionConfig actionConfig, Object methodResult, Object target) throws IOException {
|
||||
public String handleResult(ActionInvocation invocation, Object methodResult, Object target) throws IOException {
|
||||
String resultCode = readResultCode(methodResult);
|
||||
Integer statusCode = readStatusCode(methodResult);
|
||||
HttpServletRequest req = ServletActionContext.getRequest();
|
||||
HttpServletResponse res = ServletActionContext.getResponse();
|
||||
ActionConfig actionConfig = invocation.getProxy().getConfig();
|
||||
|
||||
if(statusCode != null) {
|
||||
res.setStatus(statusCode);
|
||||
}
|
||||
@@ -178,7 +190,7 @@ public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManag
|
||||
resultCode = extCode;
|
||||
} else {
|
||||
StringWriter writer = new StringWriter();
|
||||
resultCode = handler.fromObject(target, resultCode, writer);
|
||||
resultCode = handler.fromObject(invocation, target, resultCode, writer);
|
||||
String text = writer.toString();
|
||||
if (text.length() > 0) {
|
||||
byte[] data = text.getBytes("UTF-8");
|
||||
|
||||
@@ -229,9 +229,7 @@ public class RestActionInvocation extends DefaultActionInvocation {
|
||||
if (handler != null && !(handler instanceof HtmlHandler)) {
|
||||
|
||||
// Specific representation (json, xml...)
|
||||
resultCode = handlerSelector.handleResult(
|
||||
this.getProxy().getConfig(), httpHeaders, target);
|
||||
|
||||
resultCode = handlerSelector.handleResult(this, httpHeaders, target);
|
||||
} else {
|
||||
|
||||
// Normal struts execution (html o other struts result)
|
||||
|
||||
@@ -112,6 +112,7 @@ public class RestActionMapper extends DefaultActionMapper {
|
||||
private boolean allowDynamicMethodCalls = false;
|
||||
|
||||
public RestActionMapper() {
|
||||
this.defaultMethodName = indexMethodName;
|
||||
}
|
||||
|
||||
public String getIdParameterName() {
|
||||
@@ -290,7 +291,7 @@ public class RestActionMapper extends DefaultActionMapper {
|
||||
fullName = fullName.substring(0, lastSlashPos);
|
||||
}
|
||||
|
||||
mapping.setName(fullName);
|
||||
mapping.setName(cleanupActionName(fullName));
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
@@ -311,7 +312,7 @@ public class RestActionMapper extends DefaultActionMapper {
|
||||
|
||||
mapping.setName(actionName);
|
||||
if (allowDynamicMethodCalls) {
|
||||
mapping.setMethod(cleanupActionName(actionMethod));
|
||||
mapping.setMethod(cleanupMethodName(actionMethod));
|
||||
} else {
|
||||
mapping.setMethod(null);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ public class RestWorkflowInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
errors.put("actionErrors", validationAwareAction.getActionErrors());
|
||||
errors.put("fieldErrors", validationAwareAction.getFieldErrors());
|
||||
return manager.handleResult(invocation.getProxy().getConfig(), info, errors);
|
||||
return manager.handleResult(invocation, info, errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
abstract public class AbstractContentTypeHandler implements ContentTypeHandler {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractContentTypeHandler.class);
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
LOG.warn("This method is deprecated!");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AllowedClassNames {
|
||||
Set<String> allowedClassNames();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AllowedClasses {
|
||||
Set<Class<?>> allowedClasses();
|
||||
}
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
@@ -34,9 +36,15 @@ public interface ContentTypeHandler {
|
||||
* Populates an object using data from the input stream
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
* @throws IOException If unable to write to the output stream
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
void toObject(Reader in, Object target) throws IOException;
|
||||
|
||||
|
||||
void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes content to the stream
|
||||
*
|
||||
@@ -45,9 +53,14 @@ public interface ContentTypeHandler {
|
||||
* @param stream The output stream, usually the response
|
||||
* @return The new result code
|
||||
* @throws IOException If unable to write to the output stream
|
||||
*
|
||||
* @deprecated use version which requires {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
String fromObject(Object obj, String resultCode, Writer stream) throws IOException;
|
||||
|
||||
|
||||
String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the content type for this handler
|
||||
*
|
||||
|
||||
+12
-6
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -34,21 +36,25 @@ import java.io.Reader;
|
||||
* {@link http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4}
|
||||
*
|
||||
*/
|
||||
public class FormUrlEncodedHandler implements ContentTypeHandler {
|
||||
public class FormUrlEncodedHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
throw new IOException("Conversion from Object to '"+getContentType()+"' is not supported");
|
||||
}
|
||||
|
||||
/** No transformation is required as the framework handles this data */
|
||||
public void toObject(Reader in, Object target) {
|
||||
/**
|
||||
* No transformation is required as the framework handles this data
|
||||
*
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
*/
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension is not used by this handler
|
||||
* @return
|
||||
* @return The extension is not used by this handler
|
||||
*/
|
||||
public String getExtension() {
|
||||
return null;
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
@@ -28,13 +30,13 @@ import java.io.Writer;
|
||||
/**
|
||||
* Handles HTML content, usually just a simple passthrough to the framework
|
||||
*/
|
||||
public class HtmlHandler implements ContentTypeHandler {
|
||||
public class HtmlHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
public void toObject(Reader in, Object target) {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
|
||||
@@ -21,11 +21,12 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.ObjectReader;
|
||||
import org.codehaus.jackson.map.SerializationConfig.Feature;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -34,20 +35,19 @@ import java.io.Writer;
|
||||
/**
|
||||
* Handles JSON content using jackson-lib
|
||||
*/
|
||||
public class JacksonLibHandler implements ContentTypeHandler {
|
||||
public class JacksonLibHandler extends AbstractContentTypeHandler {
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
private String defaultEncoding = "ISO-8859-1";
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
mapper.configure(Feature.WRITE_NULL_MAP_VALUES, false);
|
||||
ObjectReader or = mapper.readerForUpdating(target);
|
||||
or.readValue(in); //, new TypeReference<clazz>);
|
||||
or.readValue(in);
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
mapper.configure(Feature.WRITE_NULL_MAP_VALUES, false);
|
||||
mapper.writeValue(stream, obj);
|
||||
return null;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import net.sf.json.JSONArray;
|
||||
import net.sf.json.JSONObject;
|
||||
import net.sf.json.JsonConfig;
|
||||
@@ -37,12 +38,12 @@ import com.opensymphony.xwork2.inject.Inject;
|
||||
/**
|
||||
* Handles JSON content using json-lib
|
||||
*/
|
||||
public class JsonLibHandler implements ContentTypeHandler {
|
||||
public class JsonLibHandler extends AbstractContentTypeHandler {
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
private String defaultEncoding = "ISO-8859-1";
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char[] buffer = new char[1024];
|
||||
int len = 0;
|
||||
@@ -63,7 +64,7 @@ public class JsonLibHandler implements ContentTypeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
if (obj != null) {
|
||||
if (isArray(obj)) {
|
||||
JSONArray jsonArray = JSONArray.fromObject(obj);
|
||||
|
||||
+12
-6
@@ -20,6 +20,8 @@
|
||||
*/
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -35,21 +37,25 @@ import java.io.Reader;
|
||||
* {@link http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4}
|
||||
*
|
||||
*/
|
||||
public class MultipartFormDataHandler implements ContentTypeHandler {
|
||||
public class MultipartFormDataHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public static final String CONTENT_TYPE = "multipart/form-data";
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
throw new IOException("Conversion from Object to '"+getContentType()+"' is not supported");
|
||||
}
|
||||
|
||||
/** No transformation is required as the framework handles this data */
|
||||
public void toObject(Reader in, Object target) {
|
||||
/**
|
||||
* No transformation is required as the framework handles this data
|
||||
*
|
||||
* @param in The input stream, usually the body of the request
|
||||
* @param target The target, usually the action class
|
||||
*/
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension is not used by this handler
|
||||
* @return
|
||||
* @return The extension is not used by this handler
|
||||
*/
|
||||
public String getExtension() {
|
||||
return null;
|
||||
|
||||
@@ -21,34 +21,98 @@
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.ModelDriven;
|
||||
import com.opensymphony.xwork2.util.logging.Logger;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.security.ArrayTypePermission;
|
||||
import com.thoughtworks.xstream.security.ExplicitTypePermission;
|
||||
import com.thoughtworks.xstream.security.NoTypePermission;
|
||||
import com.thoughtworks.xstream.security.NullPermission;
|
||||
import com.thoughtworks.xstream.security.PrimitiveTypePermission;
|
||||
import com.thoughtworks.xstream.security.TypePermission;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Handles XML content
|
||||
*/
|
||||
public class XStreamHandler implements ContentTypeHandler {
|
||||
public class XStreamHandler extends AbstractContentTypeHandler {
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer out) throws IOException {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(XStreamHandler.class);
|
||||
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer out) throws IOException {
|
||||
if (obj != null) {
|
||||
XStream xstream = createXStream();
|
||||
XStream xstream = createXStream(invocation);
|
||||
xstream.toXML(obj, out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void toObject(Reader in, Object target) {
|
||||
XStream xstream = createXStream();
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {
|
||||
XStream xstream = createXStream(invocation);
|
||||
xstream.fromXML(in, target);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated use version with {@link ActionInvocation}
|
||||
*/
|
||||
@Deprecated
|
||||
protected XStream createXStream() {
|
||||
LOG.warn("You are using a deprecated API!");
|
||||
return new XStream();
|
||||
}
|
||||
|
||||
protected XStream createXStream(ActionInvocation invocation) {
|
||||
XStream stream = new XStream();
|
||||
LOG.debug("Clears existing permissions");
|
||||
stream.addPermission(NoTypePermission.NONE);
|
||||
|
||||
LOG.debug("Adds per action permissions");
|
||||
addPerActionPermission(invocation, stream);
|
||||
|
||||
LOG.debug("Adds default permissions");
|
||||
addDefaultPermissions(invocation, stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
private void addPerActionPermission(ActionInvocation invocation, XStream stream) {
|
||||
Object action = invocation.getAction();
|
||||
if (action instanceof AllowedClasses) {
|
||||
Set<Class<?>> allowedClasses = ((AllowedClasses) action).allowedClasses();
|
||||
stream.addPermission(new ExplicitTypePermission(allowedClasses.toArray(new Class[allowedClasses.size()])));
|
||||
}
|
||||
if (action instanceof AllowedClassNames) {
|
||||
Set<String> allowedClassNames = ((AllowedClassNames) action).allowedClassNames();
|
||||
stream.addPermission(new ExplicitTypePermission(allowedClassNames.toArray(new String[allowedClassNames.size()])));
|
||||
}
|
||||
if (action instanceof XStreamPermissionProvider) {
|
||||
Collection<TypePermission> permissions = ((XStreamPermissionProvider) action).getTypePermissions();
|
||||
for (TypePermission permission : permissions) {
|
||||
stream.addPermission(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addDefaultPermissions(ActionInvocation invocation, XStream stream) {
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{invocation.getAction().getClass()}));
|
||||
if (invocation.getAction() instanceof ModelDriven) {
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{((ModelDriven) invocation.getAction()).getModel().getClass()}));
|
||||
}
|
||||
stream.addPermission(NullPermission.NULL);
|
||||
stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
|
||||
stream.addPermission(ArrayTypePermission.ARRAYS);
|
||||
stream.addPermission(CollectionTypePermission.COLLECTIONS);
|
||||
stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return "application/xml";
|
||||
}
|
||||
@@ -56,4 +120,15 @@ public class XStreamHandler implements ContentTypeHandler {
|
||||
public String getExtension() {
|
||||
return "xml";
|
||||
}
|
||||
|
||||
private static class CollectionTypePermission implements TypePermission {
|
||||
|
||||
private static final TypePermission COLLECTIONS = new CollectionTypePermission();
|
||||
|
||||
public boolean allows(Class type) {
|
||||
return type != null && type.isInterface() &&
|
||||
(Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.apache.struts2.rest.handler;
|
||||
|
||||
import com.thoughtworks.xstream.security.TypePermission;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface XStreamPermissionProvider {
|
||||
Collection<TypePermission> getTypePermissions();
|
||||
}
|
||||
+17
-5
@@ -24,10 +24,14 @@ package org.apache.struts2.rest;
|
||||
import com.mockobjects.dynamic.C;
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.mock.MockActionInvocation;
|
||||
import com.opensymphony.xwork2.mock.MockActionProxy;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.rest.handler.AbstractContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.FormUrlEncodedHandler;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
@@ -49,6 +53,7 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
private DefaultContentTypeHandlerManager mgr;
|
||||
private MockHttpServletResponse mockResponse;
|
||||
private MockHttpServletRequest mockRequest;
|
||||
private MockActionInvocation invocation;
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
@@ -59,6 +64,9 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
ActionContext.setContext(new ActionContext(new HashMap()));
|
||||
ServletActionContext.setRequest(mockRequest);
|
||||
ServletActionContext.setResponse(mockResponse);
|
||||
|
||||
invocation = new MockActionInvocation();
|
||||
invocation.setProxy(new MockActionProxy());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,9 +79,9 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
public void testHandleResultOK() throws IOException {
|
||||
|
||||
String obj = "mystring";
|
||||
ContentTypeHandler handler = new ContentTypeHandler() {
|
||||
public void toObject(Reader in, Object target) {}
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
ContentTypeHandler handler = new AbstractContentTypeHandler() {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) {}
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
stream.write(obj.toString());
|
||||
return resultCode;
|
||||
}
|
||||
@@ -82,7 +90,11 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
};
|
||||
mgr.handlersByExtension.put("xml", handler);
|
||||
mgr.setDefaultExtension("xml");
|
||||
mgr.handleResult(new ActionConfig.Builder("", "", "").build(), new DefaultHttpHeaders().withStatus(SC_OK), obj);
|
||||
ActionConfig actionConfig = new ActionConfig.Builder("", "", "").build();
|
||||
MockActionProxy proxy = new MockActionProxy();
|
||||
proxy.setConfig(actionConfig);
|
||||
invocation.setProxy(proxy);
|
||||
mgr.handleResult(invocation, new DefaultHttpHeaders().withStatus(SC_OK), obj);
|
||||
|
||||
assertEquals(obj.getBytes().length, mockResponse.getContentLength());
|
||||
}
|
||||
@@ -92,7 +104,7 @@ public class ContentTypeHandlerManagerTest extends TestCase {
|
||||
Mock mockHandlerXml = new Mock(ContentTypeHandler.class);
|
||||
mockHandlerXml.matchAndReturn("getExtension", "xml");
|
||||
mgr.handlersByExtension.put("xml", (ContentTypeHandler) mockHandlerXml.proxy());
|
||||
mgr.handleResult(null, new DefaultHttpHeaders().withStatus(SC_NOT_MODIFIED), new Object());
|
||||
mgr.handleResult(invocation, new DefaultHttpHeaders().withStatus(SC_NOT_MODIFIED), new Object());
|
||||
|
||||
assertEquals(0, mockResponse.getContentLength());
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,8 +1,10 @@
|
||||
package org.apache.struts2.rest;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.XWorkTestCase;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Scope;
|
||||
import org.apache.struts2.rest.handler.AbstractContentTypeHandler;
|
||||
import org.apache.struts2.rest.handler.ContentTypeHandler;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
@@ -113,13 +115,13 @@ class DummyContainer implements Container {
|
||||
private ContentTypeHandler handler;
|
||||
|
||||
DummyContainer(final String contentType, final String extension) {
|
||||
handler = new ContentTypeHandler() {
|
||||
handler = new AbstractContentTypeHandler() {
|
||||
|
||||
public void toObject(Reader in, Object target) throws IOException {
|
||||
public void toObject(ActionInvocation invocation, Reader in, Object target) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public String fromObject(Object obj, String resultCode, Writer stream) throws IOException {
|
||||
public String fromObject(ActionInvocation invocation, Object obj, String resultCode, Writer stream) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ public class RestWorkflowInterceptorTest extends TestCase {
|
||||
Mock mockActionInvocation = new Mock(ActionInvocation.class);
|
||||
Mock mockActionProxy = new Mock(ActionProxy.class);
|
||||
mockActionProxy.expectAndReturn("getConfig", null);
|
||||
mockActionInvocation.expectAndReturn("getProxy", mockActionProxy.proxy());
|
||||
mockActionInvocation.expectAndReturn("getAction", action);
|
||||
Mock mockContentTypeHandlerManager = new Mock(ContentTypeHandlerManager.class);
|
||||
mockContentTypeHandlerManager.expectAndReturn("handleResult", new AnyConstraintMatcher() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user