在文件上传

时间:2015-12-01 16:32:23

标签: java spring spring-mvc spring-security spring-data

我正在使用Spring Security 4.我在上传多部分文件时收到错误。

Caused by: java.io.IOException: Missing content for multipart request
    at org.eclipse.jetty.util.MultiPartInputStream.parse(MultiPartInputStream.java:501)

在应用程序配置中我有。

@Bean(name = "filterMultipartResolver")
     public CommonsMultipartResolver commonsMultipartResolver(){
         CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
         commonsMultipartResolver.setDefaultEncoding("utf-8");
         commonsMultipartResolver.setMaxUploadSize(50000000);
         return commonsMultipartResolver;
     }

在webserver配置

ServletRegistration.Dynamic registration = servletCon.addServlet("dispatcher", new DispatcherServlet(servletConfig));
        registration.setLoadOnStartup(1);
        //it recognizes every url starting with / in localhost
        registration.addMapping("/");
        registration.setMultipartConfig(new MultipartConfigElement("/tmp", 1024*1024*5, 1024*1024*5*5, 1024*1024));

在AbstractSecurityWebApplicationInitializer

@Configuration
public class SecurityWebApplicationIntializer extends AbstractSecurityWebApplicationInitializer {
    @Override
      protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        insertFilters(servletContext, new MultipartFilter());
      }
}

正如我在Stack overflow here中发现的那样,我删除了Commons File Upload。它使MultipartResolver不可用。

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?

请提供有关在Spring Security中使用MultiPart文件的一些信息。

这是我的JSP文件

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>

 <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
</head>
<body ng-app='fileUpload'  ng-controller='UploadController'>
    <form enctype="multipart/form-data"
        ng-submit="submitForm()">
        File to upload: <input type="file" file-model="picBlob"><br /> Name: <input
            type="text" name="name" ng-model="result.success"><br /> <br /> <input type="submit"
            value="Upload"> Press here to upload the file!
            <input type="hidden" id="csrf" name="${_csrf.parameterName}" value="${_csrf.token}"  />
    </form>
    <script type="text/javascript">
    var tms = angular.module('fileUpload', []);

     tms.controller('UploadController', ['$scope', '$window','$http','fileUpload', function($scope, $window,$http,fileUpload) {
         $scope.result = {};
         var token = $("meta[name='_csrf']").attr("content");
          var header = $("meta[name='_csrf_header']").attr("content");
         $scope.submitForm = function(){

             var pic = $scope.picBlob;
             var uploadUrl = "/upload?_csrf="+token
             console.log(pic);
             fileUpload.uploadFileToUrl($scope.result,$scope.picBlob, uploadUrl);

         };

     }]);
     tms.directive('fileModel', ['$parse', function ($parse) {
            return {
                restrict: 'A',
                link: function(scope, element, attrs) {
                    var model = $parse(attrs.fileModel);
                    var modelSetter = model.assign;
                    element.bind('change', function(){
                        scope.$apply(function(){
                            modelSetter(scope, element[0].files[0]);
                        });
                    });
                }
            };
        }]);
     tms.service('fileUpload', ['$http', function ($http) {
            this.uploadFileToUrl = function(memberJson,file, uploadUrl){
                var fd = new FormData();
                fd.append('file', file);
                fd.append('properties', new Blob([JSON.stringify(memberJson)], {
                    type: "application/json"
                }));
                console.log(fd);
                $http.post(uploadUrl, fd, {
                    transformRequest: angular.identity,
                    headers: {'Content-Type': undefined}
                })
                .success(function(){
                })
                .error(function(){
                });
            }
        }]);

    </script>
</body>
</html>

这是我的控制器

package com.mindfiresolutions.springmaven.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.mindfiresolutions.springmaven.models.Result;

@Controller
public class FileUploadController {

    @RequestMapping(value="/upload", method=RequestMethod.GET)
    public @ResponseBody Result provideUploadInfo() {
        Result res = new Result();
        res.setError("You can upload a file by posting to this same URL.");
        return res;
    }

    @RequestMapping(value="/upload", method=RequestMethod.POST, consumes = {"multipart/form-data"})
    public @ResponseBody Result handleFileUpload( @RequestPart("properties") Result res,
            @RequestParam("file") MultipartFile file){
        Result result = new Result();
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream =
                        new BufferedOutputStream(new FileOutputStream(new File("/tmp/new.txt")));
                stream.write(bytes);
                stream.close();
                result.setSuccess("You successfully uploaded " + res.getSuccess() + "!");
                return result;
            } catch (Exception e) {
                result.setError("You failed to upload " + res.getSuccess() + " => " + e.getMessage());
                return result;
            }
        } else {
            result.setError("You failed to upload " + res.getSuccess() + " because the file was empty.");
            return result;
        }
    }

}

1 个答案:

答案 0 :(得分:1)

我得到了解决方案。在Controller中调整

@RequestMapping(value="/upload", method=RequestMethod.POST, consumes = {"multipart/form-data"})
    public @ResponseBody Result handleFileUpload( Result res,
            @RequestParam("file") MultipartFile file){
        Result result = new Result();
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream =
                        new BufferedOutputStream(new FileOutputStream(new File("/tmp/new.txt")));
                stream.write(bytes);
                stream.close();
                result.setSuccess("You successfully uploaded " + res.getSuccess() + "!");
                return result;
            } catch (Exception e) {
                result.setError("You failed to upload " + res.getSuccess() + " => " + e.getMessage());
                return result;
            }
        } else {
            result.setError("You failed to upload " + res.getSuccess() + " because the file was empty.");
            return result;
        }
    }

Spring识别该对象,Spring将您的请求参数干净地绑定到您的类实例。它明确地寻找没有得到的对象。

参考:here