简体   繁体   English

RestController 方法在 Spring 4.3 中返回了 Content-Type = application/javascript,但在 Spring 5.6 中返回了 application/json

[英]RestController method returned Content-Type = application/javascript in Spring 4.3, but application/json in Spring 5.6

I have this method:我有这个方法:

    @RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ValuesJsonObject getValuesAsJson(@RequestParam final String ownerId, @RequestParam final String searchString, @RequestParam final Long valueTypeId,
                                            @RequestParam(required = false) final boolean extendedSearch, @RequestParam(required = false) final String meta3Filter,
                                            @RequestParam(required = false) final String meta4Filter, @RequestParam(required = false) final String valueFilter,
                                            @RequestParam(required = false) final String searchFields, @RequestParam(required = false) final Boolean distinct) {
        //...Some Code
        final ValuesJsonObject valuesObject = new ValuesJsonObject();
        valuesObject.setValues(values);
            
        return valuesObject;
                                            
                                            
}

This method is used to fetch data that is used for a GWT select box.此方法用于获取用于 GWT select 框的数据。 The response normally looks something like this:响应通常看起来像这样:

/**/ gwt_jsonp .P0.onSuccess({"values":[{"denotation":"ZFO - Franconia","value":"ZFO - Franconia","description":null,"meta1":null,"meta3":null,"meta4":null}]}); /**/ gwt_jsonp .P0.onSuccess({"values":[{"denotation":"ZFO - Franconia","value":"ZFO - Franconia","description":null,"meta1":null," meta3":null,"meta4":null}]});

It's some kind of GWT callback thing where JSON data is inside this Javascript function.这是某种 GWT 回调,其中 JSON 数据在这个 Javascript function 中。

The response content-type was application/javascript in Spring 4.3 environment.在 Spring 4.3 环境中,响应内容类型为application/javascript Now, after the upgrade, the response-type is application/json.现在,升级后,响应类型为 application/json。 I tried to create a header and manually set up a ResponseEntity with a header that has Content-Type = "application/javascript" but still application/json is returned.我尝试创建一个 header 并手动设置一个 ResponseEntity 和一个 header 的 Content-Type = "application/javascript" 但仍然返回 application/json。

在此处输入图像描述

What I've tried so far:到目前为止我已经尝试过:

  1. Set @RequestMapping to @RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = "text/javascript) -> Response Content-Type in browser turns to text/html设置@RequestMapping为@RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = "text/javascript) -> Response Content-Type in browser 转为text/html

  2. Removed produces tag in RequestMapping entirely -> Response Content-Type in browser turns to application/xml;charset=UTF-8完全移除了 RequestMapping 中的 produces 标签 -> 浏览器中的 Response Content-Type 变为application/xml;charset=UTF-8

  3. Tried to manually set the Response headers like that, but that got me a 500 error:试图像那样手动设置 Response 标头,但这让我遇到了 500 错误:

    HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_TYPE, "text/javascript"); headers.add(HttpHeaders.CONTENT_TYPE, "text/javascript"); return new ResponseEntity<>(valuesObject, headers, HttpStatus.OK);返回新的 ResponseEntity<>(valuesObject, headers, HttpStatus.OK);

Edit: Some new findings, When I remove the data from the body and just ad null. then the content-type is set properly, If I have the data in the body.编辑:一些新发现,当我从正文中删除数据并且只是广告 null 时,内容类型设置正确,如果我在正文中有数据。 I receive a 500 error.我收到 500 错误。 It must have something to do with the payload (but it worked before the Spring update....).它一定与有效负载有关(但它在 Spring 更新之前有效....)。

What I then tried was to properly transform the payload into JSON data using ObjectMapper.然后我尝试使用 ObjectMapper 将有效负载正确转换为 JSON 数据。 The response data then looks like normal JSON and the content-type is correctly set to application/javascript:然后响应数据看起来像正常的 JSON 并且内容类型正确设置为 application/javascript:

Response:回复:

{"values":[{"denotation":"ZFO - Franconia","value":"ZFO - Franconia","description":null,"meta1":null,"meta3":null,"meta4":null}]}

BUT the Javascript callback is missing in this response.但是此响应中缺少 Javascript 回调。 Question is how to add this back again.问题是如何将其再次添加回来。 I think that's a GWT issue...我认为这是一个 GWT 问题......

I have a solution for my problem.我有解决问题的方法。

When we upgraded to Spring 5.6, Spring's AbstractJsonpResponseBodyAdvice was removed.当我们升级到 Spring 5.6 时,Spring 的AbstractJsonpResponseBodyAdvice被移除了。 I think this extension class was responsible for setting the correct content-type in our response and converting everything to JSONP.我认为这个扩展 class 负责在我们的响应中设置正确的内容类型并将所有内容转换为 JSONP。 When the class was gone, the wrong content-type was set.当 class 消失时,设置了错误的内容类型。 So I had to manually set content-type to text/javascript in @RequestMapping, but I also had to provide it in the header of the response.所以我必须在@RequestMapping 中手动将内容类型设置为 text/javascript,但我还必须在响应的 header 中提供它。

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "text/javascript");

I also had to capture the callback address of the JSONP / GWT call in a new parameter in method signature我还必须在方法签名的新参数中捕获 JSONP / GWT 调用的回调地址

@RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = "text/javascript")
    public ResponseEntity getValuesAsJson(@RequestParam final String ownerId, @RequestParam final String searchString, @RequestParam final Long valueTypeId,
                                          @RequestParam(required = false) final boolean extendedSearch, @RequestParam(required = false) final String meta3Filter,
                                          @RequestParam(required = false) final String meta4Filter, @RequestParam(required = false) final String valueFilter,
                                          @RequestParam(required = false) final String searchFields, @RequestParam(required = false) final Boolean distinct,
                                          @RequestParam(required = true) final String callback) {

And finally I wrapped the Javascript method name around the JSON data:最后,我将 Javascript 方法名称包装在 JSON 数据周围:

return ResponseEntity.ok()
        .headers(headers)
        .body(callback + "(" + valuesObjectAsJson + ")");

This was basically the solution someone else here on SA proposed but I can't find the thread again.这基本上是 SA 上其他人提出的解决方案,但我再也找不到线程了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Spring 中读取 Content-Type 应用程序/json - Reading Content-Type application/json in Spring spring rest webservices使用application / json content-type返回multipart / form-data - spring rest webservices return multipart/form-data with application/json content-type Spring Security 拒绝 Fetch OPTIONS Preflight Outright If content-type = &#39;application/json&#39; - Spring Security Rejects Fetch OPTIONS Preflight Outright If content-type = 'application/json' 使用 Fetch API javascript 将 Content-Type 设置为 application/Json - set Content-Type to application/Json using Fetch API javascript Spring MVC - 不支持内容类型“应用程序/json” - Spring MVC - Content type 'application/json' not supported 没有为Content-Type定义解析器:application / json - No parser defined for Content-Type: application/json Spring MVC中内容类型应用程序/ x-www-form-urlencoded的请求参数的顺序 - Order of request parameters for content-type application/x-www-form-urlencoded in Spring MVC 在Spring Boot中使用内容类型application / x-www-form-urlencoded的请求的自定义反序列化器 - Custom deserializer for requests with content-type application/x-www-form-urlencoded in Spring Boot 春季的内容类型和@ResponseBody - Content-type and @ResponseBody in spring RESTEasy:找不到内容类型应用程序/json 类型的编写器 - RESTEasy: Could not find writer for content-type application/json type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM