【问题标题】:Angular http and spring boot rest serviceAngular http和spring boot rest服务
【发布时间】:2016-06-02 03:54:07
【问题描述】:

我正在从我的 Angular UI 调用 Spring Boot REST 服务。只要 Spring Boot Rest 服务作为 Spring Boot 应用程序执行,它就可以正常工作。但是一旦我将它转换为 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 Boot 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 Boot 应用程序,但随后它的所有请求参数都为空。

这是请求负载

------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"}

【问题讨论】:

    标签: angularjs jboss spring-boot angular-http


    【解决方案1】:

    我想你错过了@RequestBody

    当您将$http 与data 属性一起使用时,数据将在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;
    }
    

    【讨论】:

    • 现在我得到 HTTP 状态 415 不支持的媒体类型。 {"timestamp":1464874683832,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'multipart/form-data ;boundary=----WebKitFormBoundarymRKqwcUfa6CJzALs;charset=UTF-8' not supported","path":"/rest-services/fusiontables/upload"}
    【解决方案2】:

    终于明白了。

    我必须添加一个 Multipartresolver bean。

    @Configuration
    public class WebConfig extends WebMvcAutoConfiguration {
    @Bean
    public MultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }
    

    }

    这解决了问题。好像当我将它作为 Spring Boot 应用程序运行时,Spring 已经处理了它,但是当部署为 WAR 文件时,应该配置这个 bean

    【讨论】:

      【解决方案3】:

      你可以试试这个 Spring Controller 方法吗:

      @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;
        }
      }]);
      

      【讨论】:

      • 那也没用。我仍然在所有字段上得到空值。
      • 哪些字段为空?它在请求负载中是什么样的?
      • 我在我的问题中包含了请求有效负载。当我将整个内容作为@RequestBody 字符串打印出来时,它会在控制器中打印出来。但是当我使用 request.getParameter("stateCd") 时,它返回空值。关于角度服务,我也尝试过......但结果相同。这似乎是因为控制器无法识别请求负载的内容类型。
      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 2017-09-10
      • 2016-10-29
      • 2023-03-11
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多