Angular http 和 spring 引导休息服务
Angular http and spring boot rest service
我正在从我的 angular UI 调用 spring 引导 REST 服务。只要 Spring Boot Rest 服务作为 Spring 引导应用程序执行,它就可以正常工作。但是一旦我将它转换为 WAR 文件并部署在 Jboss 6.2.4 服务器上,我得到 404。我看到来自 UI 的 REST 服务调用成功但请求JSON 没有通过。根据请求 JSON,我传递了 2 个字符串和一个上传的 excel 文件。
这是我的 angular UI http 调用
App.service('getHeatMapDataService', ['$http', '$q', function ($http, $q) {
this.getHeatMapData = function (scope) {
var url = 'http://localhost:8080/rest-services/fusiontables/upload';
var deferred = $q.defer();
$http({
method: 'POST',
url: url,
headers: {
'Content-Type': undefined
},
data: {
stateCd: scope.stateCd,
addressExtras: scope.addressExtras,
uploadFile: scope.upFile
},
transformRequest: function (data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
var headers = headersGetter();
delete headers['Content-Type'];
return formData;
}
})
.success(function (data) {
deferred.resolve(data);
console.log("Success");
console.log(data);
})
.error(function (data, status) {
deferred.reject(status);
console.log("Failed");
});
return deferred.promise;
}
}]);
这是我的 Spring 引导 Rest 控制器工作时
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(HeatMapUploadCommand uploadCommand) {
logger.info("Heat Map Controller invoked " + uploadCommand);
return null;
}
这是我的上传命令
public class HeatMapUploadCommand {
private String stateCd;
private String addressExtras;
private MultipartFile uploadFile;
我在 Jboss 上部署后,请求仍然命中 Spring 启动应用程序,但随后它的所有请求参数都为空。
这是请求负载
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="stateCd"
CA
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="addressExtras"
1234
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="uploadFile"; filename="CAdata.xlsx"
Content-Type: application/vnd.openxmlformats- officedocument.spreadsheetml.sheet
------WebKitFormBoundaryvCCnl3nhIgoW1MwR--
我尝试将控制器更改为
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(@RequestParam(value="stateCd") String stateCd,
@RequestParam(value="addressExtras") String addressExtras,
@RequestParam(value="uploadFile") MultipartFile file) {
System.out.println("Heat Map Controller invoked " + stateCd);
return null;
}
仍然没有运气。这是我得到的回复。
{"timestamp":1464840821648,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required String parameter 'stateCd' is not present","path":"/rest-services/fusiontables/upload"}
我想你错过了 @RequestBody
。
当您将 $http
与数据 属性 一起使用时,数据会传入 request body
。
$http({
method: 'POST',
url: url,
data: {
stateCd: scope.stateCd,
addressExtras: scope.addressExtras,
uploadFile: scope.upFile
},
我认为一旦您添加 @RequestBody
,它可能会起作用。
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(@RequestBody HeatMapUploadCommand uploadCommand) {
logger.info("Heat Map Controller invoked " + uploadCommand);
return null;
}
你能试试这个 Spring 控制器方法吗:
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
String stateCd = request.getParameter("stateCd");
String addressExtras = request.getParameter("addressExtras");
......
Iterator<String> iterator = request.getFileNames();
while (iterator.hasNext()) {
MultipartFile multipartFile = request.getFile(iterator.next());
.....
}
.........
}
和 Angular 服务:
App.service('getHeatMapDataService', ['$http', '$q', function ($http,$q) {
this.getHeatMapData = function (scope) {
var url = 'http://localhost:8080/rest-services/fusiontables/upload';
var deferred = $q.defer();
var formData = new FormData();
formData.append('stateCd', scope.stateCd);
formData.append('addressExtras', scope.stateCd);
formData.append('file', scope.upFile);
$http.post( url, formData, {
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (result) {
console.log('200');
}).error(function () {
console.log('400-500');
});
return deferred.promise;
}
}]);
终于想通了。
我必须添加一个 Multipartresolver bean。
@Configuration
public class WebConfig extends WebMvcAutoConfiguration {
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
}
这解决了问题。似乎当我 运行 它作为 spring 引导应用程序时,spring 已经处理了它但是当部署为 WAR 文件时应该配置这个 bean
我正在从我的 angular UI 调用 spring 引导 REST 服务。只要 Spring Boot Rest 服务作为 Spring 引导应用程序执行,它就可以正常工作。但是一旦我将它转换为 WAR 文件并部署在 Jboss 6.2.4 服务器上,我得到 404。我看到来自 UI 的 REST 服务调用成功但请求JSON 没有通过。根据请求 JSON,我传递了 2 个字符串和一个上传的 excel 文件。
这是我的 angular UI http 调用
App.service('getHeatMapDataService', ['$http', '$q', function ($http, $q) {
this.getHeatMapData = function (scope) {
var url = 'http://localhost:8080/rest-services/fusiontables/upload';
var deferred = $q.defer();
$http({
method: 'POST',
url: url,
headers: {
'Content-Type': undefined
},
data: {
stateCd: scope.stateCd,
addressExtras: scope.addressExtras,
uploadFile: scope.upFile
},
transformRequest: function (data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
var headers = headersGetter();
delete headers['Content-Type'];
return formData;
}
})
.success(function (data) {
deferred.resolve(data);
console.log("Success");
console.log(data);
})
.error(function (data, status) {
deferred.reject(status);
console.log("Failed");
});
return deferred.promise;
}
}]);
这是我的 Spring 引导 Rest 控制器工作时
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(HeatMapUploadCommand uploadCommand) {
logger.info("Heat Map Controller invoked " + uploadCommand);
return null;
}
这是我的上传命令
public class HeatMapUploadCommand {
private String stateCd;
private String addressExtras;
private MultipartFile uploadFile;
我在 Jboss 上部署后,请求仍然命中 Spring 启动应用程序,但随后它的所有请求参数都为空。
这是请求负载
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="stateCd"
CA
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="addressExtras"
1234
------WebKitFormBoundaryvCCnl3nhIgoW1MwR
Content-Disposition: form-data; name="uploadFile"; filename="CAdata.xlsx"
Content-Type: application/vnd.openxmlformats- officedocument.spreadsheetml.sheet
------WebKitFormBoundaryvCCnl3nhIgoW1MwR--
我尝试将控制器更改为
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(@RequestParam(value="stateCd") String stateCd,
@RequestParam(value="addressExtras") String addressExtras,
@RequestParam(value="uploadFile") MultipartFile file) {
System.out.println("Heat Map Controller invoked " + stateCd);
return null;
}
仍然没有运气。这是我得到的回复。
{"timestamp":1464840821648,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required String parameter 'stateCd' is not present","path":"/rest-services/fusiontables/upload"}
我想你错过了 @RequestBody
。
当您将 $http
与数据 属性 一起使用时,数据会传入 request body
。
$http({
method: 'POST',
url: url,
data: {
stateCd: scope.stateCd,
addressExtras: scope.addressExtras,
uploadFile: scope.upFile
},
我认为一旦您添加 @RequestBody
,它可能会起作用。
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(@RequestBody HeatMapUploadCommand uploadCommand) {
logger.info("Heat Map Controller invoked " + uploadCommand);
return null;
}
你能试试这个 Spring 控制器方法吗:
@RequestMapping(value="/upload", method=RequestMethod.POST)
@ResponseBody
public String getBoundaries(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
String stateCd = request.getParameter("stateCd");
String addressExtras = request.getParameter("addressExtras");
......
Iterator<String> iterator = request.getFileNames();
while (iterator.hasNext()) {
MultipartFile multipartFile = request.getFile(iterator.next());
.....
}
.........
}
和 Angular 服务:
App.service('getHeatMapDataService', ['$http', '$q', function ($http,$q) {
this.getHeatMapData = function (scope) {
var url = 'http://localhost:8080/rest-services/fusiontables/upload';
var deferred = $q.defer();
var formData = new FormData();
formData.append('stateCd', scope.stateCd);
formData.append('addressExtras', scope.stateCd);
formData.append('file', scope.upFile);
$http.post( url, formData, {
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (result) {
console.log('200');
}).error(function () {
console.log('400-500');
});
return deferred.promise;
}
}]);
终于想通了。
我必须添加一个 Multipartresolver bean。
@Configuration
public class WebConfig extends WebMvcAutoConfiguration {
@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
}
这解决了问题。似乎当我 运行 它作为 spring 引导应用程序时,spring 已经处理了它但是当部署为 WAR 文件时应该配置这个 bean