3

在 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);
}

当我从这样的 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 
    })

但是,当我尝试将调用从 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 
    })

我想我在 @RestController 类中遗漏了一些东西来让它解析 JSON,而不是期待 www-urlencoded 数据。

我尝试更改方法@RequestMapping上的注释serviceA以添加consumes="application/json"属性,但这没有效果。

在 POST 正文中使用 JSON 而不是 urlencoded 数据,我可以进行哪些更改来完成这项工作?

4

2 回答 2

3

javadoc@RequestParam状态

指示方法参数应绑定到 Web 请求参数的注释。

ServletRequest这是通过请求参数的各种方法检索的。例如,ServletRequest#getParameterMap()哪些国家

请求参数是随请求发送的额外信息。对于 HTTP servlet,参数包含在查询字符串或发布的表单数据中。

在您的第二个片段中,您也没有发送。您在请求正文中发送 JSON。

Spring 有一种机制(它有许多自定义机制)可以将其反序列化为您期望的数据。标准解决方案是,假设您有一个可以处理 JSON@RequestBody的适当注册。如果类路径上有 Jackson 2,HttpMessageConverterSpring 会自动注册,它可以正确地将 JSON 反序列化为 Java POJO 类型。MappingJackson2HttpMessageConverter

文档提供了许多示例并解释了您将如何使用它。使用 JSON,您可以定义一个 POJO 类型,其中包含与您发送的字段相对应的字段

class RequestPojo {
    private String paramA;
    private String paramB;
    private String paramC;
    // and corresponding getters and setters
}

并将@RequestBody这种类型的带注释的参数添加到您的处理程序方法中

public ServiceAResponse serviceA(@RequestBody RequestPojo pojo) {
    pojo.getParamB(); // do something
    return ...;
}

Jackson 允许您通过注释或配置来定义ObjectMapper如何处理缺失值。

@RestController这里不涉及。正如其 javadoc 所述,

带有此注释的类型被视为控制器,其中 @RequestMapping方法@ResponseBody默认采用语义。

于 2015-08-01T01:24:12.607 回答
0

在我看来,此时您正在传递一个 JSON 对象,而不是一组参数,因此 Spring 无法将您发送的内容与您提供的任何参数相匹配。

尝试

@RequestBody List<ListUnit> listOfUnits

而不是@RequestParam

于 2015-08-01T01:11:58.930 回答