javascript 如何让 Spring @RestController 接受 JSON 格式的参数而不是 www-form-urlencoded?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31757179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get a Spring @RestController to accept parameters in JSON format rather than www-form-urlencoded?
提问by Jared
Using Spring 4.1.7 on JDK 1.8, I have an @RestController class that looks like this:
在 JDK 1.8 上使用 Spring 4.1.7,我有一个看起来像这样的 @RestController 类:
@RestController
public class ServiceAController {
public static final Logger LOG = Logger.getLogger(ServiceAController.class);
@RequestMapping(value="/rest/servicea", method=RequestMethod.POST)
public ServiceAResponse serviceA(@RequestParam(value="parmA", defaultValue="defaultParmA") String parmA,
@RequestParam(value="parmB", defaultValue="defaultParmB") String parmB,
@RequestParam(value="parmC", defaultValue="defaulParmC") String parmC) {
LOG.info("Inside Service A handler: " + parmA + " B: "+ parmB + " C: "+ parmC);
}
When I send a POST to /rest/servicea from a javascript like this, everything works, and I see the values "a", "b", and "c" printed in my log:
当我从这样的 javascript 向 /rest/servicea 发送 POST 时,一切正常,我看到我的日志中打印了值“a”、“b”和“c”:
var data = {
"parmA": "a",
"parmB": "b",
"parmC": "c"
}
$.ajax({
type: "POST",
url: "./rest/servicea",
contentType: "application/x-www-form-urlencoded",
data: data,
dataType: "json",
success: submitAuthSuccess,
error: submitAuthFailure
})
However, when I try to change the call from the javascript to this (to change the protocol to REST rather than www-urlencode), I get the default values (defaultParmA, defaultParmB, defaultParmC) in my log:
但是,当我尝试将调用从 javascript 更改为此(将协议更改为 REST 而不是 www-urlencode)时,我在日志中获得了默认值(defaultParmA、defaultParmB、defaultParmC):
var data = {
"parmA": "a",
"parmB": "b",
"parmC": "c"
}
$.ajax({
type: "POST",
url: "./rest/servicea",
contentType: "application/json",
data: JSON.stringify(data),
dataType: "json",
success: submitAuthSuccess,
error: submitAuthFailure
})
I think I'm missing something in the @RestController class to get it to parse the JSON rather than expecting www-urlencoded data.
我想我在 @RestController 类中遗漏了一些东西来让它解析 JSON 而不是期待 www-urlencoded 数据。
I tried changing the @RequestMapping
annotation on the serviceA
method to add the consumes="application/json"
attribute, but that had no effect.
我尝试更改方法@RequestMapping
上的注释serviceA
以添加consumes="application/json"
属性,但这没有效果。
What can I change to make this work, using JSON rather than urlencoded data in the POST body?
在 POST 正文中使用 JSON 而不是 urlencoded 数据,我可以改变什么来使这项工作?
回答by Sotirios Delimanolis
The @RequestParam
javadoc states
该@RequestParam
javadoc的状态
Annotation which indicates that a method parameter should be bound to a web request parameter.
指示方法参数应绑定到 Web 请求参数的注释。
This is retrieved through the various ServletRequest
methods for request parameters. For example, ServletRequest#getParameterMap()
which states
这是通过ServletRequest
请求参数的各种方法检索的。例如,ServletRequest#getParameterMap()
其中规定
Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.
请求参数是随请求发送的额外信息。对于 HTTP servlet,参数包含在查询字符串或发布的表单数据中。
In your second snippet, you aren't sending either. You're sending JSON in the request body.
在你的第二个片段中,你也没有发送。您在请求正文中发送 JSON。
Spring has a mechanism (it has many, and custom ones) for deserializing that into the data you expect. The standard solution is @RequestBody
, assuming you have an appropriately registered HttpMessageConverter
that can handle the JSON. Spring automatically registers MappingHymanson2HttpMessageConverter
if you have Hymanson 2 on the classpath, which can correctly deserialize JSON into Java POJO types.
Spring 有一种机制(它有许多自定义机制)用于将其反序列化为您期望的数据。标准解决方案是@RequestBody
,假设您有一个HttpMessageConverter
可以处理 JSON的适当注册。MappingHymanson2HttpMessageConverter
如果类路径上有 Hymanson 2,Spring 会自动注册,它可以正确地将 JSON 反序列化为 Java POJO 类型。
The documentationgives a number of examples and explains how you would use it. With JSON, you could define a POJO type with fields that correspond to the ones you send
该文档提供了许多示例并解释了您将如何使用它。使用 JSON,您可以使用与您发送的字段相对应的字段来定义 POJO 类型
class RequestPojo {
private String paramA;
private String paramB;
private String paramC;
// and corresponding getters and setters
}
and add a @RequestBody
annotated parameter of this type to your handler method
并将@RequestBody
此类型的带注释的参数添加到您的处理程序方法中
public ServiceAResponse serviceA(@RequestBody RequestPojo pojo) {
pojo.getParamB(); // do something
return ...;
}
Hymanson lets you define, through annotations or through configuration of the ObjectMapper
, how to deal with absent values.
Hymanson 允许您通过注释或 的配置来定义ObjectMapper
如何处理缺失值。
@RestController
is not involved here. As its javadoc states,
@RestController
这里不涉及。正如其 javadoc 所述,
Types that carry this annotation are treated as controllers where
@RequestMapping
methods assume@ResponseBody
semantics by default.
带有此注释的类型被视为控制器,其中
@RequestMapping
方法@ResponseBody
默认采用语义。
回答by Serj
It looks to me like you are passing a single JSON object at this point, rather than a set of parameters, hence Spring cannot match what you're sending to any of the parameters you've provided.
在我看来,此时您正在传递一个 JSON 对象,而不是一组参数,因此 Spring 无法将您发送的内容与您提供的任何参数相匹配。
Try
尝试
@RequestBody List<ListUnit> listOfUnits
instead of @RequestParam
而不是@RequestParam