【问题标题】:Spring Restful Service + Spring for android, missing parameter while uploading fileSpring Restful Service + Spring for android,上传文件时缺少参数
【发布时间】:2013-11-05 16:01:47
【问题描述】:

我和Spring restservice打了2天,文件上传打不开。

我的控制器及其方法基于指南http://spring.io/guides/gs/uploading-files/

但是我有很多问题。首先我必须包含库:jackson-mapper-asl 因为我的请求总是返回错误。我想知道为什么在 Spring Webservice 模板项目中没有添加这个库。

自从我添加了 jackson-mapper-asl 库后,我的简单 GET 请求得到了正确处理。 但是,当我按照本指南中的描述实现处理文件上传的方法时,它根本不起作用。

这是我的 Controller 类及其方法实现:

@Controller
@RequestMapping("/controller")
public class GreetingsController {

@RequestMapping(value="/upload2", method=RequestMethod.POST)
public @ResponseBody String handleFileUpload2(@RequestParam("name") String name, @RequestParam("myfile") MultipartFile file){
    if (file != null && !file.isEmpty()) {
        try {
            byte[] bytes = file.getBytes();
            BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(name + "-uploaded")));
            stream.write(bytes);
            stream.close();
            return "You successfully uploaded " + name + " into " + name + "-uploaded !";
        } catch (Exception e) {
            return "You failed to upload " + name + " => " + e.getMessage();
        }
    } else {
        return "You failed to upload " + name + " because the file was empty.";
    }
}

这是我发出请求的 android 代码的一部分:

final String serviceAddress3= "http://someaddress:8080/testappx2/controller/upload2";
String mb05 = sdcardMountPoint + "/DCIM/halfMB.jar";
final RestTemplate restTemplate = new RestTemplate(true);           

FileSystemResource fsr = new FileSystemResource(mb05);
final LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("name", "superplik");
map.add("myfile", fsr);

Thread t = new Thread(new Runnable(){
    public void run() {
        Object result = restTemplate.postForObject(serviceAddress2, map, String.class);     
    }
});
t.start();

我使用以下库:

* spring-core 3.0.5.RELEASE
* spring-web 3.0.5.RELEASE
* spring-webmvc 3.0.5.RELEASE
* jackson-mapper-asl 1.9.13

我尝试使用 SoapUI 并直接从 Android 模拟 APP 发出 POST 请求。我得到的唯一结果是:org.springframework.web.client.HttpClientErrorException: 400 Bad Request 我决定深入研究我的应用程序服务器日志,发现我的请求并不“完整”

请求句柄日志如下:

16:09:46,029 TRACE [org.jboss.as.web.security] (http--0.0.0.0-8080-2) Begin invoke, caller=null
16:09:46,030 TRACE [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Bound request context to thread: org.apache.catalina.connector.RequestFacade@6195db1d
16:09:46,032 DEBUG [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) DispatcherServlet with name 'mvc-dispatcher' processing POST request for [/testappx2/controller/upload]
16:09:46,034 TRACE [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Testing handler map [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping@16321271] in DispatcherServlet with name 'mvc-dispatcher'
16:09:46,035 DEBUG [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] (http--0.0.0.0-8080-2) Mapping [/controller/upload] to HandlerExecutionChain with handler [hello.GreetingsController@6ee8560d] and 2 interceptors
16:09:46,037 TRACE [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Testing handler adapter [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter@5769a85d]
16:09:46,039 DEBUG [org.apache.tomcat.util.http.Parameters] (http--0.0.0.0-8080-2) Set encoding to ISO-8859-1
16:09:46,040 DEBUG [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver] (http--0.0.0.0-8080-2) Resolving exception from handler [hello.GreetingsController@6ee8560d]: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present
16:09:46,043 DEBUG [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] (http--0.0.0.0-8080-2) Resolving exception from handler [hello.GreetingsController@6ee8560d]: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present
16:09:46,045 DEBUG [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (http--0.0.0.0-8080-2) Resolving exception from handler [hello.GreetingsController@6ee8560d]: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present
16:09:46,047 DEBUG [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Null ModelAndView returned to DispatcherServlet with name 'mvc-dispatcher': assuming HandlerAdapter completed request handling
16:09:46,048 TRACE [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@6195db1d
16:09:46,049 DEBUG [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-2) Successfully completed request
16:09:46,050 TRACE [org.springframework.web.context.support.XmlWebApplicationContext] (http--0.0.0.0-8080-2) Publishing event in WebApplicationContext for namespace 'mvc-dispatcher-servlet': ServletRequestHandledEvent: url=[/testappx2/controller/upload]; client=[172.16.241.58]; method=[POST]; servlet=[mvc-dispatcher]; session=[null]; user=[null]; time=[20ms]; status=[OK]
16:09:46,051 TRACE [org.springframework.web.context.support.XmlWebApplicationContext] (http--0.0.0.0-8080-2) Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/testappx2/controller/upload]; client=[172.16.241.58]; method=[POST]; servlet=[mvc-dispatcher]; session=[null]; user=[null]; time=[20ms]; status=[OK]
16:09:46,052 TRACE [org.jboss.as.web.security] (http--0.0.0.0-8080-2) End invoke, caller=null
16:09:46,052 TRACE [org.jboss.security.SecurityRolesAssociation] (http--0.0.0.0-8080-2) Setting threadlocal:null
16:09:46,052 TRACE [org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager] (http--0.0.0.0-8080-2) popped object: org.jboss.as.connector.deployers.processors.CachedConnectionManagerSetupProcessor$CachedConnectionManagerSetupAction@4bae320

Appserver 说“name”参数没有传递:[hello.GreetingsController@6ee8560d]: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present

有趣的是(我偶然发现的)当我省略向 LinkedMultiValueMap 添加“myfile”参数时,它会找到它,解析它,然后它会进入方法的主体。

应用服务器日志:

16:52:29,391 DEBUG [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] (http--0.0.0.0-8080-1) Resolving exception from handler [hello.GreetingsController@788a7860]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'myfile' is not present
16:52:29,391 DEBUG [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (http--0.0.0.0-8080-1) Resolving exception from handler [hello.GreetingsController@788a7860]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'myfile' is not present
16:52:29,392 DEBUG [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-1) Null ModelAndView returned to DispatcherServlet with name 'mvc-dispatcher': assuming HandlerAdapter completed request handling
16:52:29,393 TRACE [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-1) Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@8f22ae
16:52:29,393 DEBUG [org.springframework.web.servlet.DispatcherServlet] (http--0.0.0.0-8080-1) Successfully completed request
16:52:29,394 TRACE [org.springframework.web.context.support.XmlWebApplicationContext] (http--0.0.0.0-8080-1) Publishing event in WebApplicationContext for namespace 'mvc-dispatcher-servlet': ServletRequestHandledEvent: url=[/testappx3/controller/upload2]; client=[172.16.241.58]; method=[POST]; servlet=[mvc-dispatcher]; session=[null]; user=[null]; time=[35ms]; status=[OK]
16:52:29,394 TRACE [org.springframework.web.context.support.XmlWebApplicationContext] (http--0.0.0.0-8080-1) Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/testappx3/controller/upload2]; client=[172.16.241.58]; method=[POST]; servlet=[mvc-dispatcher]; session=[null]; user=[null]; time=[35ms]; status=[OK]
16:52:29,395 TRACE [org.jboss.as.web.security] (http--0.0.0.0-8080-1) End invoke, caller=null

现在 appserver 说没有“myfile”参数。

我认为在此方法中声明超过 1 个 RequestParameter 有问题。但是尝试了多个StringRequestParameters,这似乎工作正常。

我做错了什么?我是麻风病还是什么的?

提前致谢!

【问题讨论】:

标签: java android json spring rest


【解决方案1】:

我终于解决了这个问题。在我读到的某处,我需要在我的一个 spring 上下文文件中声明名为 multipartResolver 的魔术 bean(我什至不确定这是否是上下文文件,这些所有 spring 的东西对我来说都是新的)在我的情况下是 @ 987654322@文件

我必须添加的其他 bean 条目。

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

    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="1000000000" />
</bean>

添加这个 bean 也导致无法在我的JBoss AS 7.1 中部署这个应用程序,抛出这样的异常: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileItemFactory

我搜索了这个类,发现它是commons-fileupload 库的一部分。 来自 maven 存储库的依赖关系:

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

此依赖项允许我在 JBoss AS 7.1 中部署和启用应用程序。

然而,我的战斗并没有结束。然后我继续测试这项服务。不幸的是,这次引发了另一个 servlet 异常,原因是: java.lang.ClassNotFoundException: org.apache.commons.io.output.DeferredFileOutputStream

我再次用谷歌搜索,发现所需的类是 apache 库 commons-io 的一部分

依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

结束。 PS。可悲的是,我使用的是来自 Spring 官方网站的指南,没有提到额外的必需库,也没有提到 mutlipartResolver bean。我觉得有点可笑...

感谢您阅读所有这些内容 :)

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 2014-11-11
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多