如何使用自定义struts.multipart.parser

时间:2012-01-20 07:16:25

标签: file-upload struts2 multipartform-data

我想通过设置进度监听器来实现自定义Struts2 MultiPartRequest来实现渐进式文件上传。

我已经通过实施属于Core-struts2的 MultiPartRequest 编写了我的自定义 FileUploadMultipartRequest

public class FileUploadMultipartRequest implements MultiPartRequest {

    static final Log log = LogFactory.getLog(MultiPartRequest.class);

    // maps parameter name -> List of FileItem objects
    private Map<String, List<FileItem>> files = new HashMap<String, List<FileItem>>();
    // maps parameter name -> List of param values
    private Map<String, List<String>> params = new HashMap<String, List<String>>();
    // any errors while processing this request
    private List<String> errors = new ArrayList<String>();

    private long maxSize;

    @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)
    public void setMaxSize(String maxSize) {

        this.maxSize = Long.parseLong(maxSize);
    }

    /**
     * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's
     * multipart classes (see class description).
     *
     * @param saveDir        the directory to save off the file
     * @param servletRequest the request containing the multipart
     * @throws java.io.IOException  is thrown if encoding fails.
     */
    public void parse(HttpServletRequest servletRequest, String saveDir) throws IOException {

        DiskFileItemFactory fac = new DiskFileItemFactory();
        // Make sure that the data is written to file
        fac.setSizeThreshold(0);

        if (saveDir != null) {

            fac.setRepository(new File(saveDir));
        }

        ProgressMonitor monitor = null;

        // Parse the request
        try {

            ServletFileUpload upload = new ServletFileUpload(fac);

            upload.setSizeMax(maxSize);

            monitor = new ProgressMonitor();
            upload.setProgressListener(monitor);
            servletRequest.getSession().setAttribute(ProgressMonitor.SESSION_PROGRESS_MONITOR, monitor);
            ...
        }
    }
    ...
}

我在struts.xml中设置属性

<constant name="struts.multipart.parser" value="com.cloudlabz.service.web.action.FileUploadMultipartRequest " />
<constant name="struts.multipart.maxSize" value="504857600" />

虽然我已经在struts.xml中设置了自定义的MultipartRequestHandeler,但Struts 2仍然执行自己的 JakartaMultiPartRequest (Struts2默认解析器来处理multipart请求)类而不是我的自定义FileUploadMultipartRequest类。

请建议我解决它的方法。

3 个答案:

答案 0 :(得分:4)

如果您使用的是Struts 2版本2.1.8 +,那么您需要更正struts.multipart.parserstruts.multipart.handler之类的内容

<constant name="struts.multipart.handler"
          value="com.cloudlabz.service.web.action.FileUploadMultipartRequest" /> 

在您的情况下jakarta将执行具有相同bean定义的struts-plugin.xml配置文件将执行的操作。

对于早期版本,似乎有一种方法,创建一个插件说MycustomFileUpload。放入WEB-INF / lib下,确保jar文件中应该有类和struts-plugin.xml文件。

将以下条目添加到struts-plugin.xml

<struts>
       <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest"
             name="jakartax"
             class="com.cloudlabz.service.web.action.FileUploadMultipartRequest"
             scope="default" />
</struts>

在这种情况下,您无需在struts.xml文件中定义常量。希望这对您有用。

答案 1 :(得分:1)

我刚刚实施了与2.3.4类似的解决方案,以获得上传的进度表。最简单的方法是复制JakartaMultiPartRequest并将其重命名为MonitoredMultiPartRequest。

然后将函数parseRequest更改为:

private List<FileItem> parseRequest(HttpServletRequest servletRequest,
                                    String saveDir) throws FileUploadException {

   DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);

   ServletFileUpload upload = new ServletFileUpload(fac);
   upload.setSizeMax(maxSize);

   ProgressMonitor monitor = new ProgressMonitor();
   upload.setProgressListener(monitor);
   servletRequest.getSession().setAttribute(ProgressMonitor.SESSION_PROGRESS_MONITOR, monitor);

   return upload.parseRequest(createRequestContext(servletRequest));
}

这会将progressmonitor添加到监听器(我基于this,然后在你的struts.xml中添加以下内容

<!-- Custom multipart parser with monitoring for progress bar -->
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="monitored" class="com.stackoverflow.multipart.MonitoredMultiPartRequest" scope="default" />
<constant name="struts.multipart.handler" value="monitored" />

正如您所看到的,我正在覆盖标准值,请参阅struts-default.xml https://cwiki.apache.org/WW/struts-defaultxml.html,您可以在其中查看其配置方式

<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="struts" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default"/>
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" />
<constant name="struts.multipart.handler" value="jakarta" />

答案 2 :(得分:0)

它应该是这样的:

<struts>
  <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest"
        name="jakartax"
        class="com.cloudlabz.service.web.action.FileUploadMultipartRequest"
        scope="prototype" />

  <constant name="struts.multipart.handler" value="jakartax" /> 
</struts>