java - 如何将 JSON 对象作为 PathVariable 传递给 spring 控制器
问题描述
我正在使用 angularjs 开发 spring 应用程序。我想将 JSON 对象作为 a@PathVariable
传递给 spring 控制器,但是使用下面的代码,当将 JSON 对象作为 PathVariable 传递时,它没有命中 spring 控制器,也没有显示任何错误。任何输入?
示例代码:js:
myApp.controller('passJSONTestController', function ($rootScope, $scope, MyService) {
$scope.submitdata=function(){
$scope.myJSONData = [
{ 'name':$scope.name,
'sinNumber': $scope.sinNo,
'status': $scope.status,
'message':$scope.message,
}
];
var fd=new FormData();
angular.forEach($scope.files,function(file){
console.log("file " + file);
fd.append('file',file);
});
MyService.sendJSON($scope.myJSONData,fd).then(
function (response) {
//
},
function (errResponse) {
}
);
}
});
我的服务.js
myService.sendJSON = function (myJSONData,fd) {
var deferred = $q.defer();
var myUrl = applnURL + '/dataStack/' + myJSONData + '/getAllDataInfo.form';
var config = {
transformRequest: angular.identity,
headers : {
'Content-Type': undefined
}
}
$http.post(repUrl, fd, config ).then(function (response) {
}, function (response) {
});
return deferred.promise;
}
弹簧控制器:
@Controller
@RequestMapping("/dataStack")
public class GetData {
@RequestMapping(value = "/{myJSONData}/getAllDataInfo", method = RequestMethod.POST)
public
@ResponseBody
String sendInfo(@RequestParam("file") List<MultipartFile> multiPartFileList,@PathVariable("myJSONData") List<MyDTO> myDTO){
System.out.println("In Spring controller");
}
为什么通过的请求没有命中弹簧控制器?PS:如果我删除 spring 控制器中的路径变量并将其从 mySerivce.js 中删除,那么它正在命中 spring 控制器。
--------------已编辑(更新代码)-------------- 我添加了以下类:
@Configuration
public class MultiFileResolverConfig {
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
System.out.println("--In configuration file multipartResolver--");
return new CommonsMultipartResolver();
}
}
spring-servlet.xml 我<bean>
在 sprig-servlet.xml 配置文件中添加了下面
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000"/>
</bean>
html代码:
<html>
..elements for name,sinNumber,status,message
<input type = "file" name="file" file-model="file" multiple/>
..//submit button
</html>
js代码:
myApp.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]);
});
});
}
};
}]);
myApp.controller('passJSONTestController', function ($rootScope, $scope, MyService) {
$scope.submitdata=function(){
$scope.myJSONData = [
{ 'name':$scope.name,
'sinNumber': $scope.sinNo,
'status': $scope.status,
'message':$scope.message,
}
];
var fd=new FormData();
angular.forEach($scope.files,function(file){
console.log("file " + file);
fd.append('file',file);
});
fd.append("json",$scope.myJSONData);
MyService.sendJSON(fd).then(
function (response) {
//
},
function (errResponse) {
}
);
}
});
服务.js
myService.sendJSON = function (fd) {
var deferred = $q.defer();
var myUrl = applnURL + '/dataStack/getAllDataInfo.form';
var config = {
transformRequest: angular.identity,
headers : {
'Content-Type': undefined
}
}
$http.post(myUrl, fd, config ).then(function (response) {
}, function (response) {
});
return deferred.promise;
}
弹簧控制器:
@Controller
@RequestMapping("/dataStack")
public class GetDataController{
@RequestMapping(value = "/getAllDataInfo", method = RequestMethod.POST)
public @ResponseBody
String uploadMultipleFileHandler(MultipartHttpServletRequest req) {
System.out.println("in spring upload multiple files");
List<MultipartFile> multiPartFileList = req.getFiles("file");
System.out.println("in multiPartFileList " + multiPartFileList.size());//size is always zero
String[] json = (String[]) req.getParameterMap().get("json");//getting the values submitted
//code here..
我正在获取 json 对象的值,但无法获取文件详细信息。multiPartFileList.size() 的大小为零。我尝试仅添加类 MultiFileResolverConfig 并删除<bean>
spring-servlet.xml 中的声明,但文件详细信息仍未传递给 spring 控制器。
解决方案
2018 年 6 月 22 日更新
当涉及到多部分请求时,请注意 Spring Boot 和 Spring MVC 的工作方式不同。默认情况下,Spring MVC 不提供MultipartResolver,因此无法解析多部分请求。您必须在 ApplicationContext 中提供一个“multipartResolver”bean。但是,Spring MVC 确实为此提供了两种实现;StandardServletMultipartResolver
和CommonsMultipartResolver
。将其中任何一个配置到您的应用程序上下文中都可以。例如:
@Configuration
public class SomeConfig {
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
}
注意:bean 的名称很重要。
另一方面,Spring Boot 将StandardServletMultipartResolver
代表您自动配置一个实例,因此能够“开箱即用”地解决多部分请求。
原始答案
您也应该使用 FormData 对象传递附加数据。
更改您的客户端代码以附加其他数据:
myApp.controller('passJSONTestController', function ($rootScope, $scope, MyService) {
$scope.submitdata=function(){
$scope.myJSONData = [
{ 'name':$scope.name,
'sinNumber': $scope.sinNo,
'status': $scope.status,
'message':$scope.message,
}
];
var fd=new FormData();
angular.forEach($scope.files,function(file){
console.log("file " + file);
fd.append('file',file);
});
// do this instead
data.append('json', JSON.stringify($scope.myJSONData);
...
在您的控制器中修复请求映射并使其接受MultipartHttpServletRequest
参数而不是List<MultipartFile>
:
@Controller
@RequestMapping("/dataStack")
public class GetData {
@RequestMapping(value = "/getAllDataInfo", method = RequestMethod.POST)
public
@ResponseBody
String sendInfo(MultipartHttpServletRequest req){
List<MultipartFile> multiPartFileList = req.getFiles("file");
...
String[] json = req.getParameterMap().get("json");
// Jackson deserialization...but you could use any...Gson, etc
ObjectMapper mapper = new ObjectMapper();
TypeReference<Map<String,String>> typeRef = new TypeReference<Map<String,String>>() {};
Map<String,String> data = mapper.readValue(json[0], typeRef);
...
确保更新 MyService 以发布到新的请求映射:
myService.sendJSON = function (fd) {
var deferred = $q.defer();
var myUrl = applnURL + '/dataStack/getAllDataInfo.form';
...
我认为这应该为你做。
高温高压