Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring MVC-AngularJS-File Upload-org.apache.commons.fileupload.FileUploadException_Java_Spring_Angularjs_Spring Mvc_File Upload - Fatal编程技术网

Java Spring MVC-AngularJS-File Upload-org.apache.commons.fileupload.FileUploadException

Java Spring MVC-AngularJS-File Upload-org.apache.commons.fileupload.FileUploadException,java,spring,angularjs,spring-mvc,file-upload,Java,Spring,Angularjs,Spring Mvc,File Upload,我有一个JavaSpringMVCWeb应用程序作为服务器。以及基于AngularJS的应用程序作为客户端 在AngularJS中,我必须上传一个文件并发送到服务器 这是我的html <form ng-submit="uploadFile()" class="form-horizontal" enctype="multipart/form-data"> <input type="file" name="file" ng-model="document.fileInput"

我有一个JavaSpringMVCWeb应用程序作为服务器。以及基于AngularJS的应用程序作为客户端

在AngularJS中,我必须上传一个文件并发送到服务器

这是我的html

<form ng-submit="uploadFile()" class="form-horizontal" enctype="multipart/form-data">
   <input type="file" name="file" ng-model="document.fileInput" id="file" onchange="angular.element(this).scope().setTitle(this)" />
   <input type="text" class="col-sm-4" ng-model="document.title" id="title" />
   <button class="btn btn-primary" type="submit">
         Submit
    </button>
</form>
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="268435456" /> <!-- 256 megs -->
</bean>
<dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>${commons-fileupload.version}</version> 
</dependency>
它将进入服务器。这是我的DocumentUploadController.java

@Controller
public class DocumentUploadController {

    @RequestMapping(value="/newDocument", headers = "'Content-Type': 'multipart/form-data'", method = RequestMethod.POST)
    public void UploadFile(MultipartHttpServletRequest request, HttpServletResponse response) {

        Iterator<String> itr=request.getFileNames();

        MultipartFile file=request.getFile(itr.next());

        String fileName=file.getOriginalFilename();
        System.out.println(fileName);
    }
}
如何解决这个问题

若有人告诉我如何从angularJS发送文件和其他表单数据并将其放入服务器中,那个将是非常棒的

更新1

@Michael:我只能在控制台中单击submit时才能看到这一点

POST http://localhost:9000/serverApp/rest/newDocument 500 (Internal Server Error) angular.js:9499
(anonymous function) angular.js:9499
sendReq angular.js:9333
$http angular.js:9124
$scope.uploadFile invoice.js:113
(anonymous function) angular.js:6541
(anonymous function) angular.js:13256
Scope.$eval angular.js:8218
Scope.$apply angular.js:8298
(anonymous function) angular.js:13255
jQuery.event.dispatch jquery.js:3074
elemData.handle
我的服务器正在其他端口8080上运行。我是尤森·约曼、格伦特和鲍尔。我已经提到了服务器端口。所以它转到服务器并运行它,然后抛出异常

更新2

边界没有设置

Request URL:http://localhost:9000/serverApp/rest/newDocument
Request Method:POST
Status Code:500 Internal Server Error

Request Headers view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:792
Content-Type:multipart/form-data
Cookie:ace.settings=%7B%22sidebar-collapsed%22%3A-1%7D; isLoggedIn=true; loggedUser=%7B%22name%22%3A%22admin%22%2C%22password%22%3A%22admin23%22%7D
Host:localhost:9000
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payload
------WebKitFormBoundaryCWaRAlfQoZEBGofY
Content-Disposition: form-data; name="file"; filename="csv.csv"
Content-Type: text/csv


------WebKitFormBoundaryCWaRAlfQoZEBGofY--
Response Headers view source
connection:close
content-length:5007
content-type:text/html;charset=utf-8
date:Thu, 09 Jan 2014 11:46:53 GMT
server:Apache-Coyote/1.1

我遇到了同样的问题,甚至在更新transformRequest之后也遇到了同样的问题。”有些情况下,标题边界似乎设置不正确

接下来,问题就解决了。从位置提取

通过设置“内容类型”:未定义,浏览器为我们将内容类型设置为多部分/表单数据,并填充正确的边界。手动设置“内容类型”:多部分/表单数据将无法填写请求的边界参数

不确定这是否对任何人有帮助,但可能会使人们更容易看到这篇文章。。。至少,这让它变得不那么困难。

你可以试试这个

.js

.爪哇

这是基于

有一个文件上传的好例子

导言 我也遇到了同样的问题,并找到了一个完整的解决方案,将json和文件从基于angular的页面发送到SpringMVC方法

主要问题是$http没有发送正确的内容类型头(我将解释原因)

关于多部分/表单数据的理论 要同时发送json和文件,我们需要发送一个多部分/表单数据,这意味着“我们在正文中发送不同的项,并用一个特殊的分隔符分隔”。这个特殊的分隔符称为“boundary”,它是一个字符串,在任何要发送的元素中都不存在

服务器需要知道正在使用哪一个边界,因此必须在内容类型头中指示它(内容类型多部分/表单数据;边界=$theu boundary\u used)

所以。。。需要两件事:

  • 在标题中-->指示多部分/表单数据以及使用的边界(此处是$http失败的地方)
  • 在正文-->中,用边界分隔每个请求参数
  • 良好请求的示例:

    标题 它告诉服务器“我发送了一个带有下一个分隔符(边界)的多部分消息:-------------------------------------129291770317552

    身体 这里我们发送两个参数,“clientInfo”和“file”,用边界分隔

    问题 如果请求是用$http发送的,那么边界不会在头中发送(第1点),因此Spring无法处理数据(它不知道如何分割请求的“部分”)

    另一个问题是,只有FormData知道边界…但是FormData没有访问权限,所以不可能知道正在使用哪个边界

    解决方案 您不应该在js中使用$http,而应该使用标准的XMLHttpRequest,例如:

    //create form data to send via POST
    var formData=new FormData();
    
    console.log('loading json info');
    formData.append('infoClient',angular.toJson(client,true)); 
    // !!! when calling formData.append the boundary is auto generated!!!
    // but... there is no way to know which boundary is being used !!!
    
    console.log('loading file);
    var file= ...; // you should load the fileDomElement[0].files[0]
    formData.append('file',file);
    
    //create the ajax request (traditional way)
    var request = new XMLHttpRequest();
    request.open('POST', uploadUrl);
    request.send(formData);
    
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public @ResponseBody Object newClient(
            @RequestParam(value = "infoClient") String infoClientString,
            @RequestParam(value = "file") MultipartFile file) {
    
        // parse the json string into a valid DTO
        ClientDTO infoClient = gson.fromJson(infoClientString, ClientDTO.class);
        //call the proper service method
        this.clientService.newClient(infoClient,file);
    
        return null;
    
    }
    
    然后,在Spring方法中,您可以有如下内容:

    //create form data to send via POST
    var formData=new FormData();
    
    console.log('loading json info');
    formData.append('infoClient',angular.toJson(client,true)); 
    // !!! when calling formData.append the boundary is auto generated!!!
    // but... there is no way to know which boundary is being used !!!
    
    console.log('loading file);
    var file= ...; // you should load the fileDomElement[0].files[0]
    formData.append('file',file);
    
    //create the ajax request (traditional way)
    var request = new XMLHttpRequest();
    request.open('POST', uploadUrl);
    request.send(formData);
    
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public @ResponseBody Object newClient(
            @RequestParam(value = "infoClient") String infoClientString,
            @RequestParam(value = "file") MultipartFile file) {
    
        // parse the json string into a valid DTO
        ClientDTO infoClient = gson.fromJson(infoClientString, ClientDTO.class);
        //call the proper service method
        this.clientService.newClient(infoClient,file);
    
        return null;
    
    }
    

    Carlos Verdes的回答无法与我的$http拦截器配合使用,该拦截器添加了授权头等等。因此,我决定添加到他的解决方案中,并使用$http创建我的解决方案

    客户端角度(1.3.15) 我的表单(使用controllerAs语法)假设一个文件和一个简单对象包含我们需要发送到服务器的信息。在这种情况下,我使用一个简单的名称和类型String属性

    <form>
        <input type="text" ng-model="myController.myObject.name" />
    
         <select class="form-control input-sm" ng-model="myController.myObject.type"
          ng-options="type as type for type in myController.types"></select>
    
         <input class="input-file" file-model="myController.file" type="file">
    
    </form>
    
    其次,我使用实例方法create创建了一个名为myObject的工厂,该实例方法允许我在调用服务器上的create时转换数据。该方法将所有内容添加到FormData对象中,并使用transformRequest方法()对其进行转换。将头设置为未定义非常重要。(旧的角度版本可能需要设置未定义的内容)。这将允许自动设置多重数据/边界标记(参见Carlos的帖子)

    客户端只需在myController中实例化一个新的myObject,并在提交表单时调用controller的create函数中的create方法

    this.myObject = new myObject();
    
    this.create = function() {
            //Some pre handling/verification
            this.myObject.create(this.myObject, this.file).then(
                                  //Do some post success/error handling
                                );
        }.bind(this);
    
    服务器端弹簧(4.0) 在RestController上,我现在可以简单地执行以下操作:(假设我们有一个pojomyobject)

    请注意,我没有使用requestparameters,只是让spring进行JSON到POJO/DTO的转换。确保您也正确设置了MultiPartResolverbean,并将其添加到pom.xml中。(如果需要,还有Jackson Mapper)

    spring context.xml

    <form ng-submit="uploadFile()" class="form-horizontal" enctype="multipart/form-data">
       <input type="file" name="file" ng-model="document.fileInput" id="file" onchange="angular.element(this).scope().setTitle(this)" />
       <input type="text" class="col-sm-4" ng-model="document.title" id="title" />
       <button class="btn btn-primary" type="submit">
             Submit
        </button>
    </form>
    
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="268435456" /> <!-- 256 megs -->
    </bean>
    
    <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version> 
    </dependency>
    
    
    
    pom.xml

    <form ng-submit="uploadFile()" class="form-horizontal" enctype="multipart/form-data">
       <input type="file" name="file" ng-model="document.fileInput" id="file" onchange="angular.element(this).scope().setTitle(this)" />
       <input type="text" class="col-sm-4" ng-model="document.title" id="title" />
       <button class="btn btn-primary" type="submit">
             Submit
        </button>
    </form>
    
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="268435456" /> <!-- 256 megs -->
    </bean>
    
    <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version> 
    </dependency>
    
    
    文件上传
    文件上传
    ${commons fileupload.version}
    
    这是一个烦人的问题,我希望能解决它!!使用XMLHttpRequest而不设置内容类型对我来说很有效,谢谢。我的类似问题经验在[此处][1][1]中分享:URL不是更容易访问的,请将其作为推荐的邮政编码并将引用放在响应末尾。URL对我来说很有用
    @RequestMapping(method = RequestMethod.POST)
    @Secured({ "ROLE_ADMIN" }) //This is why I needed my $httpInterceptor
    public void create(MyObject myObject, MultipartFile file) {
         //delegation to the correct service
    }
    
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="268435456" /> <!-- 256 megs -->
    </bean>
    
    <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version> 
    </dependency>