mirror of
https://github.com/apache/struts.git
synced 2026-08-06 23:27:07 +00:00
WW-4636 - File upload error message always in default language
This commit is contained in:
committed by
Lukasz Lenart
parent
8fe2bb8317
commit
33ac7ac49a
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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.dispatcher;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class LocalizedMessage {
|
||||
private final Class clazz;
|
||||
private final String textKey;
|
||||
private final String defaultMessage;
|
||||
private final Object[] args;
|
||||
|
||||
public LocalizedMessage(Class clazz, String textKey, String defaultMessage, Object[] args) {
|
||||
this.clazz = clazz;
|
||||
this.textKey = textKey;
|
||||
this.defaultMessage = defaultMessage;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public Class getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public String getTextKey() {
|
||||
return textKey;
|
||||
}
|
||||
|
||||
public String getDefaultMessage() {
|
||||
return defaultMessage;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
|
||||
result = prime * result + ((defaultMessage == null) ? 0 : defaultMessage.hashCode());
|
||||
result = prime * result + ((textKey == null) ? 0 : textKey.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LocalizedMessage other = (LocalizedMessage) obj;
|
||||
if (!Arrays.equals(args, other.args)) {
|
||||
return false;
|
||||
}
|
||||
if (clazz == null) {
|
||||
if (other.clazz != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!clazz.equals(other.clazz)) {
|
||||
return false;
|
||||
}
|
||||
if (defaultMessage == null) {
|
||||
if (other.defaultMessage != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!defaultMessage.equals(other.defaultMessage)) {
|
||||
return false;
|
||||
}
|
||||
if (textKey == null) {
|
||||
if (other.textKey != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!textKey.equals(other.textKey)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -34,6 +34,7 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
@@ -56,7 +57,7 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
protected Map<String, List<String>> params = new HashMap<>();
|
||||
|
||||
// any errors while processing this request
|
||||
protected List<String> errors = new ArrayList<>();
|
||||
protected List<LocalizedMessage> errors = new ArrayList<>();
|
||||
|
||||
protected long maxSize;
|
||||
private Locale defaultLocale = Locale.ENGLISH;
|
||||
@@ -85,7 +86,7 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
processUpload(request, saveDir);
|
||||
} catch (FileUploadException e) {
|
||||
LOG.warn("Request exceeded size limit!", e);
|
||||
String errorMessage = null;
|
||||
LocalizedMessage errorMessage = null;
|
||||
|
||||
if(e instanceof FileUploadBase.SizeLimitExceededException) {
|
||||
FileUploadBase.SizeLimitExceededException ex = (FileUploadBase.SizeLimitExceededException) e;
|
||||
@@ -99,7 +100,7 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Unable to parse request", e);
|
||||
String errorMessage = buildErrorMessage(e, new Object[]{});
|
||||
LocalizedMessage errorMessage = buildErrorMessage(e, new Object[]{});
|
||||
if (!errors.contains(errorMessage)) {
|
||||
errors.add(errorMessage);
|
||||
}
|
||||
@@ -112,10 +113,10 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
}
|
||||
}
|
||||
|
||||
protected String buildErrorMessage(Throwable e, Object[] args) {
|
||||
protected LocalizedMessage buildErrorMessage(Throwable e, Object[] args) {
|
||||
String errorKey = "struts.messages.upload.error." + e.getClass().getSimpleName();
|
||||
LOG.debug("Preparing error message for key: [{}]", errorKey);
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
return new LocalizedMessage(this.getClass(), errorKey, e.getMessage(), args);
|
||||
}
|
||||
|
||||
protected void processUpload(HttpServletRequest request, String saveDir) throws FileUploadException, UnsupportedEncodingException {
|
||||
@@ -315,7 +316,7 @@ public class JakartaMultiPartRequest implements MultiPartRequest {
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors()
|
||||
*/
|
||||
public List<String> getErrors() {
|
||||
public List<LocalizedMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -12,6 +12,7 @@ import org.apache.commons.fileupload.util.Streams;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
@@ -48,7 +49,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
/**
|
||||
* Internal list of raised errors to be passed to the the Struts2 framework.
|
||||
*/
|
||||
private List<String> errors = new ArrayList<>();
|
||||
private List<LocalizedMessage> errors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Internal list of non-critical messages to be passed to the Struts2 framework.
|
||||
@@ -130,7 +131,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors()
|
||||
*/
|
||||
public List<String> getErrors() {
|
||||
public List<LocalizedMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -239,7 +240,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
processUpload(request, saveDir);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Error occurred during parsing of multi part request", e);
|
||||
String errorMessage = buildErrorMessage(e, new Object[]{});
|
||||
LocalizedMessage errorMessage = buildErrorMessage(e, new Object[]{});
|
||||
if (!errors.contains(errorMessage)) {
|
||||
errors.add(errorMessage);
|
||||
}
|
||||
@@ -349,7 +350,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
private void addFileSkippedError(String fileName, HttpServletRequest request) {
|
||||
String exceptionMessage = "Skipped file " + fileName + "; request size limit exceeded.";
|
||||
FileSizeLimitExceededException exception = new FileUploadBase.FileSizeLimitExceededException(exceptionMessage, getRequestSize(request), maxSize);
|
||||
String message = buildErrorMessage(exception, new Object[]{fileName, getRequestSize(request), maxSize});
|
||||
LocalizedMessage message = buildErrorMessage(exception, new Object[]{fileName, getRequestSize(request), maxSize});
|
||||
if (!errors.contains(message)) {
|
||||
errors.add(message);
|
||||
}
|
||||
@@ -507,10 +508,10 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
|
||||
* @param args arguments
|
||||
* @return error message
|
||||
*/
|
||||
private String buildErrorMessage(Throwable e, Object[] args) {
|
||||
private LocalizedMessage buildErrorMessage(Throwable e, Object[] args) {
|
||||
String errorKey = "struts.message.upload.error." + e.getClass().getSimpleName();
|
||||
LOG.debug("Preparing error message for key: [{}]", errorKey);
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
return new LocalizedMessage(this.getClass(), errorKey, e.getMessage(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
package org.apache.struts2.dispatcher.multipart;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
@@ -112,7 +115,7 @@ public interface MultiPartRequest {
|
||||
*
|
||||
* @return a list of Strings that represent various errors during parsing
|
||||
*/
|
||||
public List<String> getErrors();
|
||||
public List<LocalizedMessage> getErrors();
|
||||
|
||||
/**
|
||||
* Cleans up all uploaded file, should be called at the end of request
|
||||
|
||||
+7
-6
@@ -25,6 +25,7 @@ import com.opensymphony.xwork2.LocaleProvider;
|
||||
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
import org.apache.struts2.dispatcher.StrutsRequestWrapper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -60,7 +61,7 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
|
||||
protected static final Logger LOG = LogManager.getLogger(MultiPartRequestWrapper.class);
|
||||
|
||||
private Collection<String> errors;
|
||||
private Collection<LocalizedMessage> errors;
|
||||
private MultiPartRequest multi;
|
||||
private Locale defaultLocale = Locale.ENGLISH;
|
||||
|
||||
@@ -83,7 +84,7 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
setLocale(request);
|
||||
try {
|
||||
multi.parse(request, saveDir);
|
||||
for (String error : multi.getErrors()) {
|
||||
for (LocalizedMessage error : multi.getErrors()) {
|
||||
addError(error);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@@ -102,10 +103,10 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
protected String buildErrorMessage(Throwable e, Object[] args) {
|
||||
protected LocalizedMessage buildErrorMessage(Throwable e, Object[] args) {
|
||||
String errorKey = "struts.messages.upload.error." + e.getClass().getSimpleName();
|
||||
LOG.debug("Preparing error message for key: [{}]", errorKey);
|
||||
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
|
||||
return new LocalizedMessage(this.getClass(), errorKey, e.getMessage(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,7 +235,7 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
*
|
||||
* @return the error Collection.
|
||||
*/
|
||||
public Collection<String> getErrors() {
|
||||
public Collection<LocalizedMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
|
||||
*
|
||||
* @param anErrorMessage the error message to report.
|
||||
*/
|
||||
protected void addError(String anErrorMessage) {
|
||||
protected void addError(LocalizedMessage anErrorMessage) {
|
||||
if (!errors.contains(anErrorMessage)) {
|
||||
errors.add(anErrorMessage);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,12 @@ import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import com.opensymphony.xwork2.interceptor.ValidationAware;
|
||||
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
|
||||
import org.apache.struts2.util.ContentTypeMatcher;
|
||||
@@ -256,9 +258,9 @@ public class FileUploadInterceptor extends AbstractInterceptor {
|
||||
MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;
|
||||
|
||||
if (multiWrapper.hasErrors()) {
|
||||
for (String error : multiWrapper.getErrors()) {
|
||||
for (LocalizedMessage error : multiWrapper.getErrors()) {
|
||||
if (validation != null) {
|
||||
validation.addActionError(error);
|
||||
validation.addActionError(LocalizedTextUtil.findText(error.getClazz(), error.getTextKey(), ActionContext.getContext().getLocale(), error.getDefaultMessage(), error.getArgs()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -335,6 +337,44 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
assertNotNull("test1.html", fileRealFilenames[0]);
|
||||
}
|
||||
|
||||
public void testMultipartRequestLocalizedError() throws Exception {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
req.setCharacterEncoding("text/html");
|
||||
req.addHeader("Content-type", "multipart/form-data; boundary=---1234");
|
||||
|
||||
// inspired by the unit tests for jakarta commons fileupload
|
||||
String content = ("-----1234\r\n" +
|
||||
"Content-Disposition: form-data; name=\"file\"; filename=\"deleteme.txt\"\r\n" +
|
||||
"Content-Type: text/html\r\n" +
|
||||
"\r\n" +
|
||||
"Unit test of FileUploadInterceptor" +
|
||||
"\r\n" +
|
||||
"-----1234--\r\n");
|
||||
req.setContent(content.getBytes("US-ASCII"));
|
||||
|
||||
MyFileupAction action = new MyFileupAction();
|
||||
|
||||
MockActionInvocation mai = new MockActionInvocation();
|
||||
mai.setAction(action);
|
||||
mai.setResultCode("success");
|
||||
mai.setInvocationContext(ActionContext.getContext());
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
ActionContext.getContext().setParameters(HttpParameters.create(param).build());
|
||||
// set German locale
|
||||
ActionContext.getContext().setLocale(Locale.GERMAN);
|
||||
ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 10));
|
||||
|
||||
interceptor.intercept(mai);
|
||||
|
||||
assertTrue(action.hasActionErrors());
|
||||
|
||||
Collection<String> errors = action.getActionErrors();
|
||||
assertEquals(1, errors.size());
|
||||
String msg = errors.iterator().next();
|
||||
// the error message should contain at least this test
|
||||
assertTrue(msg.startsWith("Der Request übertraf die maximal erlaubte Größe"));
|
||||
}
|
||||
|
||||
private String encodeTextFile(String bondary, String endline, String name, String filename, String contentType, String content) {
|
||||
final StringBuilder sb = new StringBuilder(64);
|
||||
sb.append(endline);
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import http.utils.multipartrequest.ServletMultipartRequest;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.LocalizedMessage;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
@@ -131,7 +132,7 @@ public class PellMultiPartRequest implements MultiPartRequest {
|
||||
return values.toArray(new String[values.size()]);
|
||||
}
|
||||
|
||||
public List<String> getErrors() {
|
||||
public List<LocalizedMessage> getErrors() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user