如何从HttpServletRequest获取MultipartEntity

5

我正试图从Java Spring控制器调用一个Web服务。以下是代码:

private void storeImages(MultipartHttpServletRequest multipartRequest) {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpPost postRequest = new HttpPost(
                    "http://localhost:8080/dream/storeimages.htm");
    MultipartFile multipartFile1 = multipartRequest.getFile("file1");
    MultipartEntity multipartEntity = new MultipartEntity(
                    HttpMultipartMode.BROWSER_COMPATIBLE);
    multipartEntity.addPart("file1",
                    new ByteArrayBody(multipartFile1.getBytes(),
                                    multipartFile1.getContentType(),
                                    multipartFile1.getOriginalFilename()));
    postRequest.setEntity(multipartEntity);
    HttpResponse response = httpClient.execute(postRequest);
    if (response.getStatusLine().getStatusCode() != 201) {
        throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatusLine().getStatusCode());
    }
}

以上只是部分代码。我正在尝试确定如何在服务器端检索它。在服务器端,我有以下Spring控制器代码:

@RequestMapping(value = "/storeimages.htm", method = RequestMethod.POST)
public ModelAndView postItem(HttpServletRequest request,
                HttpServletResponse response) {
    logger.info("Inside /secure/additem/postitem.htm");
    try {
        // How to get the MultipartEntity object here. More specifically i
        // want to get back the Byte array from it
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return new ModelAndView("success");
}

我执行了这段代码,控制权转移到了服务器端。但我卡在了如何从multipartentity对象中获取字节数组的问题上。
编辑后的要求: 这是需求:用户从网站上传图片(已完成并且运作良好)。提交表单后,控制权传递到Spring控制器(已完成并且运作良好)。在Spring控制器中,我使用Multipart获取表单的内容(已完成并且运作良好)。现在我想调用一个Web服务,将图像字节数组发送到图像服务器(需要完成此任务)。在图像服务器上,我希望接收此Web服务请求,并从HTTPServlerRequest中获取所有字段,存储图像并返回(需要完成此任务)。

你的目标Servlet版本是什么?自从Servlet 3.0以来,HttpServletRequest已经有了一个getParts()方法,可以随后用于获取InputStream。 - Charlie
如何检查是否正在使用Servlet 3.0。我正在使用Tomcat 7。我已经尝试编写以下代码,但似乎无效。列表大小为0。List formData = new ArrayList(request.getParts()); Part part = formData.get(0); String parameterName = part.getName(); logger.info("STORC IMAGES - " + parameterName); - user1241438
@user1241438,Tomcat 7 是一个支持 Servlet 3.0 的容器。 - Ralph
4个回答

7

最终解决了。以下是对我有效的方法。

客户端

private void storeImages(HashMap<String, MultipartFile> imageList) {
    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost postRequest = new HttpPost("http://localhost:8080/dream/storeimages.htm");

        MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        Set set = imageList.entrySet(); 
        Iterator i = set.iterator(); 
        while(i.hasNext()) { 
            Map.Entry me = (Map.Entry)i.next(); 
            String fileName = (String)me.getKey();
            MultipartFile multipartFile = (MultipartFile)me.getValue();
            multipartEntity.addPart(fileName, new ByteArrayBody(multipartFile.getBytes(), 
                    multipartFile.getContentType(), multipartFile.getOriginalFilename()));
        } 
        postRequest.setEntity(multipartEntity);
        HttpResponse response = httpClient.execute(postRequest);

        if (response.getStatusLine().getStatusCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + response.getStatusLine().getStatusCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));

        String output;
        while ((output = br.readLine()) != null) {
            logger.info("Webservices output - " + output);
        }
        httpClient.getConnectionManager().shutdown();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

服务器端

@RequestMapping(value = "/storeimages.htm", method = RequestMethod.POST)
public void storeimages(HttpServletRequest request, HttpServletResponse response)
{
    logger.info("Inside /secure/additem/postitem.htm");
    try
    {
        //List<Part> formData = new ArrayList(request.getParts());
        //Part part = formData.get(0);
        //Part part = request.getPart("file1");
        //String parameterName = part.getName();
        //logger.info("STORC IMAGES - " + parameterName);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

        Set set = multipartRequest.getFileMap().entrySet(); 
        Iterator i = set.iterator(); 
        while(i.hasNext()) { 
            Map.Entry me = (Map.Entry)i.next(); 
            String fileName = (String)me.getKey();
            MultipartFile multipartFile = (MultipartFile)me.getValue();
            logger.info("Original fileName - " + multipartFile.getOriginalFilename());
            logger.info("fileName - " + fileName);
            writeToDisk(fileName, multipartFile);
        } 
    }
    catch(Exception ex)
    {
        ex.printStackTrace();
    }
}

public void writeToDisk(String filename, MultipartFile multipartFile)
{
    try
    {
        String fullFileName = Configuration.getProperty("ImageDirectory") + filename;
        FileOutputStream fos = new FileOutputStream(fullFileName);
        fos.write(multipartFile.getBytes());
        fos.close();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
}

2
在我的项目中,我们过去使用来自com.oreilly.servlets的MultipartParser来处理与multipart请求对应的HttpServletRequests,如下所示:
// Should be able to handle multipart requests upto 1GB size.
MultipartParser parser = new MultipartParser(aReq, 1024 * 1024 * 1024);
// If the content type is not multipart/form-data, this will be null.
if (parser != null) {
    Part part;
    while ((part = parser.readNextPart()) != null) {
        if (part instanceof FilePart) {
            // This is an attachment or an uploaded file.
        }
        else if (part instanceof ParamPart) {
            // This is request parameter from the query string
        }
    }
}

希望这有所帮助。

2

你可以使用Spring的多部分支持,而不是手动完成所有这些操作。

控制器可以像这样工作(此示例使用一个命令对象来存储额外的用户输入--(这是一个工作项目的示例))。

@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(@Valid final DocumentCreateCommand documentCreateCommand,
        final BindingResult bindingResult) throws IOException {
    if (bindingResult.hasErrors()) {
      return new ModelAndView("documents/create", "documentCreateCommand", documentCreateCommand);            
    } else {            
        Document document = this.documentService.storeDocument(
               documentCreateCommand.getContent().getBytes(),
               StringUtils.getFilename(StringUtils.cleanPath(documentCreateCommand.getContent().getOriginalFilename())));
               //org.springframework.util.StringUtils

        return redirectToShow(document);
    }
}


@ScriptAssert(script = "_this.content.size>0", lang = "javascript", message = "{validation.Document.message.notDefined}")
public class DocumentCreateCommand {
    @NotNull private org.springframework.web.multipart.MultipartFile content;       
    Getter/Setter
}

为了启用Spring Multipart支持,您需要配置一些内容:
web.xml(在CharacterEncodingFilter之后和HttpMethodFilter之前添加org.springframework.web.multipart.support.MultipartFilter)
 <filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    <!-- uses the bean: filterMultipartResolver -->
</filter>

<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在您的应用程序的核心Spring配置(不是MVC Servlet)中添加以下内容:
<!-- allows for integration of file upload functionality, used by an filter configured in the web.xml -->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="filterMultipartResolver" name="filterMultipartResolver">
     <property name="maxUploadSize" value="100000000"/>
</bean>

您还需要commons fileupload库,因为Spring的MultipartFile只是一种适配器。

<dependency>
     <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.1</version>
</dependency>

更多细节请参见:Spring参考文档,第15.8章Spring的multipart(文件上传)支持


从我的网站上,当用户上传图片时,我已经在控制器中使用了多部分来获取文件。目前我正在将图像存储在数据库中,但现在我决定可以调用一个 Web 服务将这些图像传递到另一个仅存储图像的服务器。因此,我需要创建一个 Web 服务请求,其中包含图像,并希望在服务器端检索它,以便我可以存储图像。以上解决方案似乎无法解决这个问题。 - user1241438
1
我无法从你的问题中推导出这些要求。 - Ralph
这是要求。 用户从网站上传图片(已完成并正常工作)。 在表单提交后,控制权转移到Spring控制器(已完成并正常工作)。 在Spring控制器中,我使用Multipart来获取表单的内容(已完成并正常工作)。 现在我想调用一个Web服务,将图像字节数组发送到图像服务器(需要完成)。 在图像服务器上,我希望接收此Web服务请求,并从HTTPServlerRequest中获取所有字段,存储图像并返回(需要完成)。 - user1241438
@user1241438,请在您的问题中更新此要求! - Ralph

0

要处理控制器的Spring文件,您需要在app-config.xml中指定如下:

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

并将代码处理如下

    MultipartEntityBuilder paramsBuilder = MultipartEntityBuilder.create();
    Charset chars = Charset.forName("UTF-8");
    paramsBuilder.setCharset(chars);

    if (null != obj.getFile()){
    FileBody fb = new FileBody(obj.getFile());
    paramsBuilder.addPart("file", fb);
    }

这是为红色多部分而设的

private File getFile(MultipartFile file) {

    try {
        File fichero = new File(file.getOriginalFilename());
        fichero.createNewFile();
        FileOutputStream fos = new FileOutputStream(fichero);
        fos.write(file.getBytes());
        fos.close();
        return fichero;
    } catch (Exception e) {
        return null;
    }

}

希望这可以帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接