下载struts2.5.26jar包
官网下载
更新jar
新增或替换
asm-7.3.1.jar asm-analysis-7.3.1.jar asm-commons-7.3.1.jar asm-tree-7.3.1.jar commons-lang3-3.8.1.jar commons-io-2.6.jar commons-fileupload-1.4.jar javassist-3.20.0-GA.jar log4j-api-2.12.1.jar ognl-3.1.28.jar struts2-core-2.5.26.jar struts2-json-plugin-2.5.26.jar struts2-junit-plugin-2.5.26.jar struts2-spring-plugin-2.5.26.jar xpp3_min-1.1.4c.jar xstream-1.4.11.1.jar xmlpull-1.1.3.1.jar
删除
xwork-core-2.3.32.jar 2.5.X已把xwork-core整合到struts2-core,所以删除
修改web.xml
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter>
修改weblogic.xml(如果有)
新增session-descriptor
<weblogic-web-app> <session-descriptor> <cookie-name>JSESSIONID1</cookie-name> </session-descriptor> </weblogic-web-app>
修改struts.xml
2.1–》2.5
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd">
新增配置
- package标签添加strict-method-invocation=”false”和下列标签。
- global-allowed-methods:放最下面,过滤自定义action的方法,不然不能访问
- 如果已经配置struts.properties,可不加constant标签
<constant name="struts.enable.DynamicMethodInvocation" value="true"/> <constant name="struts.enable.SlashesInActionNames" value="true"/> <constant name="struts.action.extension" value="do" /> <package extends="struts-default" strict-method-invocation="false"> <global-results> </global-results> <global-allowed-methods>regex:.*</global-allowed-methods> </package>
修改struts.xml的result-types配置
- 注释部分为struts2.3.32配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="struts-default" abstract="true" strict-method-invocation="false"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <!-- <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult"/> --> <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult" default="true"/> <!-- <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> --> <result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.result.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <!-- <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" /> --> <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.result.PostbackResult" /> <!--自定义result-type--> <result-type name="json" class="org.apache.struts2.json.JSONResult"> <param name="root">jsonRoot</param> </result-type> </result-types> <interceptors> <interceptor name="i18n" class="org.apache.struts2.interceptor.I18nInterceptor"/> <!-- <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> --> </interceptors> <!-- 其他配置不变,这里略 --> <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> <global-allowed-methods>regex:.*</global-allowed-methods> </package> </struts>
如果重写了ParametersInterceptor.java类
原方法
protected Map<String, Object> retrieveParameters(ActionContext ac) {
return ac.getParameters(); }
新方法
protected Map<String, String[]> retrieveParameters(ActionContext ac) {
HttpParameters httpParameters = ac.getParameters(); return httpParameters.toMap(); }
处理上传附件问题(2021.03.30修改)
修改struts.xml的interceptors配置
- 注释部分为struts2.3.32配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="struts-default" abstract="true" strict-method-invocation="false"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <!-- <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult"/> --> <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult" default="true"/> <!-- <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> --> <result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.result.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <!-- <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" /> --> <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.result.PostbackResult" /> <!--自定义result-type--> <result-type name="json" class="org.apache.struts2.json.JSONResult"> <param name="root">jsonRoot</param> </result-type> </result-types> <interceptors> <interceptor name="i18n" class="org.apache.struts2.interceptor.I18nInterceptor"/> <!-- <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> --> <interceptor name="fileUpload" class="com.struts2.interceptor.FileUploadInterceptor"/> <!-- <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> --> </interceptors> <!-- 其他配置不变,这里略 --> <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> <global-allowed-methods>regex:.*</global-allowed-methods> </package> </struts>
FileUploadInterceptor.java
package com.struts2.interceptor; import java.io.File; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; 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.dispatcher.multipart.UploadedFile; import org.apache.struts2.util.ContentTypeMatcher; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.LocaleProvider; import com.opensymphony.xwork2.LocaleProviderFactory; import com.opensymphony.xwork2.TextProvider; import com.opensymphony.xwork2.TextProviderFactory; 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.TextParseUtil; public class FileUploadInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = -L; protected static final Logger LOG = LogManager.getLogger(FileUploadInterceptor.class); protected Long maximumSize; protected Set<String> allowedTypesSet = Collections.emptySet(); protected Set<String> allowedExtensionsSet = Collections.emptySet(); private ContentTypeMatcher matcher; private Container container; @Inject public void setMatcher(ContentTypeMatcher matcher) {
this.matcher = matcher; } @Inject public void setContainer(Container container) {
this.container = container; } / * Sets the allowed extensions * * @param allowedExtensions A comma-delimited list of extensions */ public void setAllowedExtensions(String allowedExtensions) {
allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions); } / * Sets the allowed mimetypes * * @param allowedTypes A comma-delimited list of types */ public void setAllowedTypes(String allowedTypes) {
allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes); } / * Sets the maximum size of an uploaded file * * @param maximumSize The maximum size in bytes */ public void setMaximumSize(Long maximumSize) {
this.maximumSize = maximumSize; } /* (non-Javadoc) * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation) */ public String intercept(ActionInvocation invocation) throws Exception {
ActionContext ac = invocation.getInvocationContext(); HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); if (!(request instanceof MultiPartRequestWrapper)) {
if (LOG.isDebugEnabled()) {
ActionProxy proxy = invocation.getProxy(); LOG.debug(getTextMessage("struts.messages.bypass.request", new String[]{
proxy.getNamespace(), proxy.getActionName()})); } return invocation.invoke(); } ValidationAware validation = null; Object action = invocation.getAction(); if (action instanceof ValidationAware) {
validation = (ValidationAware) action; } MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; if (multiWrapper.hasErrors() && validation != null) {
TextProvider textProvider = getTextProvider(action); for (LocalizedMessage error : multiWrapper.getErrors()) {
String errorMessage; if (textProvider.hasKey(error.getTextKey())) {
errorMessage = textProvider.getText(error.getTextKey(), Arrays.asList(error.getArgs())); } else {
errorMessage = textProvider.getText("struts.messages.error.uploading", error.getDefaultMessage()); } validation.addActionError(errorMessage); } } // bind allowed Files Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
// get the value of this input tag String inputName = (String) fileParameterNames.nextElement(); // get the content type String[] contentType = multiWrapper.getContentTypes(inputName); if (isNonEmpty(contentType)) {
// get the name of the file from the input tag String[] fileName = multiWrapper.getFileNames(inputName); if (isNonEmpty(fileName)) {
// get a File object for the uploaded File UploadedFile[] files = multiWrapper.getFiles(inputName); if (files != null && files.length > 0) {
List<File> acceptedFiles = new ArrayList<>(files.length); List<String> acceptedContentTypes = new ArrayList<>(files.length); List<String> acceptedFileNames = new ArrayList<>(files.length); String contentTypeName = inputName + "ContentType"; String fileNameName = inputName + "FileName"; for (int index = 0; index < files.length; index++) {
if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation)) {
acceptedFiles.add((File)files[index].getContent()); acceptedContentTypes.add(contentType[index]); acceptedFileNames.add(fileName[index]); } } if (!acceptedFiles.isEmpty()) {
Map<String, Parameter> newParams = new HashMap<>(); newParams.put(inputName, new Parameter.File(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]))); newParams.put(contentTypeName, new Parameter.File(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]))); newParams.put(fileNameName, new Parameter.File(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]))); ac.getParameters().appendAll(newParams); } } } else {
if (LOG.isWarnEnabled()) {
LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new String[]{
inputName})); } } } else {
if (LOG.isWarnEnabled()) {
LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new String[]{
inputName})); } } } // invoke action return invocation.invoke(); } / * Override for added functionality. Checks if the proposed file is acceptable based on contentType and size. * * @param action - uploading action for message retrieval. * @param file - proposed upload file. * @param filename - name of the file. * @param contentType - contentType of the file. * @param inputName - inputName of the file. * @param validation - Non-null ValidationAware if the action implements ValidationAware, allowing for better * logging. * @return true if the proposed file is acceptable by contentType and size. */ protected boolean acceptFile(Object action, UploadedFile file, String filename, String contentType, String inputName, ValidationAware validation) {
boolean fileIsAcceptable = false; // If it's null the upload failed if (file == null) {
String errMsg = getTextMessage(action, "struts.messages.error.uploading", new String[]{
inputName}); if (validation != null) {
validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) {
LOG.warn(errMsg); } } else if (file.getContent() == null) {
String errMsg = getTextMessage(action, "struts.messages.error.uploading", new String[]{
filename}); if (validation != null) {
validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) {
LOG.warn(errMsg); } } else if (maximumSize != null && maximumSize < file.length()) {
String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new String[]{
inputName, filename, file.getName(), "" + file.length(), getMaximumSizeStr(action)}); if (validation != null) {
validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) {
LOG.warn(errMsg); } } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) {
String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new String[]{
inputName, filename, file.getName(), contentType}); if (validation != null) {
validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) {
LOG.warn(errMsg); } } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) {
String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new String[]{
inputName, filename, file.getName(), contentType}); if (validation != null) {
validation.addFieldError(inputName, errMsg); } if (LOG.isWarnEnabled()) {
LOG.warn(errMsg); } } else {
fileIsAcceptable = true; } return fileIsAcceptable; } private String getMaximumSizeStr(Object action) {
return NumberFormat.getNumberInstance(getLocaleProvider(action).getLocale()).format(maximumSize); } / * @param extensionCollection - Collection of extensions (all lowercase). * @param filename - filename to check. * @return true if the filename has an allowed extension, false otherwise. */ private boolean hasAllowedExtension(Collection<String> extensionCollection, String filename) {
if (filename == null) {
return false; } String lowercaseFilename = filename.toLowerCase(); for (String extension : extensionCollection) {
if (lowercaseFilename.endsWith(extension)) {
return true; } } return false; } / * @param itemCollection - Collection of string items (all lowercase). * @param item - Item to search for. * @return true if itemCollection contains the item, false otherwise. */ private boolean containsItem(Collection<String> itemCollection, String item) {
for (String pattern : itemCollection) if (matchesWildcard(pattern, item)) return true; return false; } private boolean matchesWildcard(String pattern, String text) {
Object o = matcher.compilePattern(pattern); return matcher.match(new HashMap<String, String>(), text, o); } private boolean isNonEmpty(Object[] objArray) {
boolean result = false; for (int index = 0; index < objArray.length && !result; index++) {
if (objArray[index] != null) {
result = true; } } return result; } protected String getTextMessage(String messageKey, String[] args) {
return getTextMessage(this, messageKey, args); } protected String getTextMessage(Object action, String messageKey, String[] args) {
if (action instanceof TextProvider) {
return ((TextProvider) action).getText(messageKey, args); } return getTextProvider(action).getText(messageKey, args); } private TextProvider getTextProvider(Object action) {
TextProviderFactory tpf = container.getInstance(TextProviderFactory.class); return tpf.createInstance(action.getClass()); } private LocaleProvider getLocaleProvider(Object action) {
LocaleProvider localeProvider; if (action instanceof LocaleProvider) {
localeProvider = (LocaleProvider) action; } else {
LocaleProviderFactory localeProviderFactory = container.getInstance(LocaleProviderFactory.class); localeProvider = localeProviderFactory.createLocaleProvider(); } return localeProvider; } }
修改xwork-conversion.properties配置
java.io.File=com.struts2.UploadedFileConverter
UploadedFileConverter.java
package com.struts2; import java.io.File; import java.lang.reflect.Array; import java.lang.reflect.Member; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.multipart.StrutsUploadedFile; import org.apache.struts2.dispatcher.multipart.UploadedFile; import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter; public class UploadedFileConverter extends DefaultTypeConverter {
private static final Logger LOG = LogManager.getLogger(UploadedFileConverter.class); @Override public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) {
if (File.class.equals(toType)) {
LOG.debug("Converting {} into {}, consider switching to {} and do not access {} directly!", File.class.getName(), UploadedFile.class.getName(), UploadedFile.class.getName(), File.class.getName()); Object obj; if (value.getClass().isArray() && Array.getLength(value) == 1) {
obj = Array.get(value, 0); } else {
obj = value; } if (obj instanceof UploadedFile) {
UploadedFile file = (UploadedFile) obj; if (file.getContent() instanceof File) {
return file.getContent(); } return new File(file.getAbsolutePath()); }else {
return new File(obj.toString()); } } return super.convertValue(context, target, member, propertyName, value, toType); } }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231598.html原文链接:https://javaforall.net
