[英]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:到目前为止我已经尝试过:
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
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
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.