当前位置: 首页 > 工具软件 > Struts+ > 使用案例 >

struts2.3.32升级到struts2.5.26

斜昊空
2023-12-01

下载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 = -4764627478894962478L;

    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);
    }

}
 类似资料: