在 POST Spring 4.x MVC 上未解析 JSON 有效负载

Posted

技术标签:

【中文标题】在 POST Spring 4.x MVC 上未解析 JSON 有效负载【英文标题】:JSON Payload not Parsed on POST Spring 4.x MVC 【发布时间】:2014-09-25 14:02:23 【问题描述】:

伙计们,我发现许多示例(实际上所有示例)都是围绕使用 @ResponseBody 设计的,就像这篇文章 (click here) 一样。但是,我似乎无法将这一切与这么多看似矛盾的方式放在一起来做一件简单的事情。我承认,我对 Spring 的最后一次使用仅限于 2.5,可悲的是,这让我只能和上一个版本一样好。我必须为该项目编写自己的服务,而 Spring 显然是要走的路。我使用这组出色的示例 (click here) 来整合最初的概念,并且在我的 Sencha Touch 应用程序中的 REST 代理中一切正常。或者我是这么想的。直到我开始向控制器发送和发布 JSON 有效负载。突然没有从 HTTP 请求映射的数据。

这是我的控制器,请记住这是 Spring 4,根据我所阅读的内容,@ReponseBody 在 Spring 3 中使用,并且由于使用了 @RestController 而不是 Spring 3 中的 @Controller,因此现在委托了该功能。因此,对于像我这样的人来说,配置细节是粗略的,一个对 Java 有很好的掌握,但对 Spring 等框架没有丰富经验的人。我向您询问有关配置 bean 的“位置”的详细信息,因为在 2.5 中,它是一个用于配置的 XML 动物园。似乎命名约定现在是以前留给 XML 文件的关联的规则。它们在一定程度上是过去的,但不像现在看起来那样。

     @RequestMapping(value = "/create/wellTestID", method = RequestMethod.POST,headers="Accept=application/json")
     public List<WellTest> getWellTestByWellTestID(@PathVariable Long wellTestID, 
             @RequestParam(defaultValue = "99999")  Long wellFacilityID, 
             @RequestParam(defaultValue = "101")    int operatorPersonID, 
             @RequestParam(defaultValue = "67845")  int durationSeconds, 
             @RequestParam(defaultValue = "100")    long grossRate, 
             @RequestParam(defaultValue = "400")    long waterCut, 
             @RequestParam(defaultValue = "30")     long percentGas, 
             @RequestParam(defaultValue = "500")    long temperature, 
             @RequestParam(defaultValue = "60")     long flowLinePressure, 
             @RequestParam(defaultValue = "50")     long casingPressure, 
             @RequestParam(defaultValue = "0")      int allocation, 
             @RequestParam(defaultValue = "3")      int wellTestTypeID,  
             @RequestParam(defaultValue = "you")    String createUser,
             @RequestParam(defaultValue = "me-me")  String lastModifiedUser,
             @RequestParam(defaultValue = "1-1-2014") String startDate, 
             @RequestParam(defaultValue = "1-1-2014") String createDate, 
             @RequestParam(defaultValue = "1-1-2014") String lastModifiedDate, 
             WellTest wellTest) throws ParseException 
         wellTestService.createWellTest(wellTest);
      List<WellTest> wt = wellTestService.getWellTestByWellTestID(wellTestID);
      return wt;
     

我可以获取此参数的唯一方法是将请求参数连接到 URL 上,我们都知道这是错误的。但是在花了几天时间确定问题之后,我会采取任何可行的方法。我使用的测试工具确实没有帮助我为这个问题做好准备,因为 POST 一个 JSON 有效负载与表单变量不同。

这就是问题所在,如果有人遇到这种异常情况,我希望专家会在这里回复一个完整且经过验证的解决方案。

问题是:如何使用 Jackson 解析和绑定 POST 上的 JSON 有效负载(对于 W3C 的建议,PUT 的工作方式相同) - 如果这有所不同,我正在使用 Glassfish 4.0。

在使用我们许多人开始使用的这些“免费”示例时,我有一个问题供人们考虑。问题总是,我的意思是,总是运行任何提供的使用服务的演示软件。在我无法完成这项工作后,我发现更新实际上是 GET,它具有我觉得奇怪的可变模式,但在请求它之前已连接到 URL。我花了太多时间试图学习这个以用知识实现它,但我无法及时做到。

感谢所有关于这篇文章的回答。你有我的感激之情。

柯蒂斯·费舍尔

我收到的答案会引发更多问题,而不是让我更接近答案。我很感激,但我无法仅凭这些知识来实现​​任何东西。

这是 bean 的加载方式...

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org /2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans     
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.aspecteg.springservice.controller" />
<mvc:annotation-driven />
</beans>

好吧,我在编辑戴维斯女士的帖子时犯了一个错误,我提出的问题进入了称为同行评审的以太坊。毫无疑问,我会因为一些违规行为而受到惩罚。

首先,我要感谢您和 Sumner 先生的回答。我的下一个问题是因为我注意到 Davis 女士的示例建立在 Sumner 先生的建议之上,而且 JSON 和 Jave (WellTest) 中的模型对象似乎都是由

MyObject res = myObjectRepository.save(myObject);

代码行。现在这看起来很酷。不过我还有几个问题...

什么是对象...

 @Autowired
private MyObjectRepository myObjectRepository;

它是如何“连接”进来的?

@ResponseStatus(HttpStatus.CREATED)

上面的@ResponseStatus 负责什么?

你使用的 Logger 是什么,Log4J?

鉴于下面的代码,你们有任何更正吗?

@RestController
@RequestMapping("/service/welltest")
public class WellTestController 

private static Logger LOG = LoggerFactory.getLogger(MyObjectsController.class);

@Autowired
private MyObjectRepository myObjectRepository; //NEED MORE INFO ON THIS - Curtis

@RequestMapping(value = "/update/wellTestID",  method = RequestMethod.PUT,headers="Accept=application/json",
                     consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public WellTest createUserPayment(@RequestBody WellTest wellTest) 
    WellTest wt = myObjectRepository.save(wellTest);
    LOG.info("the result of the save: "+wt.toString());
    return res;


最后,由于我的 bean 是通过 xml 文件加载的,而不是带注释的类,因此定义中是否需要加载任何 Jackson beans 或对象?或任何其他配置细节?一旦我收到你们任何一个关于我的问题的回复,我就会执行此操作。如果我有一段时间没有收到你们的任何消息,我会尝试 Sumner 先生的解决方案的变体,因为我不知道如何实现 Davis 女士的 @autoWired 部分。不过我已经准备好了!

谢谢你们...

柯蒂斯·费舍尔

【问题讨论】:

我不明白你的问题。如果您的类路径中有 Jackson 库并在您的 servlet 上下文 @Configuration 类上使用默认的 @EnabledWebMvc,您只需使用 @RequestBody 注释您的 @Controller 处理程序方法 POJO 类型参数。它将请求的主体反序列化为 POJO。 您没有收到任何答复,只有一条评论。您还没有收到答案,因为您的问题太宽泛了。你需要专注于一个问题,陈述它,并陈述你尝试过的事情。您不是在写电子邮件,而是在问一个问题。见***.com/help/how-to-ask 【参考方案1】:

我不完全理解您的问题,因为您没有明确指出问题的实质。话虽如此,以下应该可以正常工作:

@RestController
class FooController 
  @RequestMapping(
    value = "/some/endpoint",
    method = RequestMethod.POST,
    consumes = MediaType.APPLICATION_JSON_VALUE,
    produces = MediaType.APPLICATION_JSON_VALUE
  )
  public MyResponseObject someEndpoint(@RequestBody MyRequestObject requestBody)
  
    MyResponseObject responseObject = new MyResponseObject();
    responseObject.setSomeProperty("foo");
    responseObject.setAnotherProperty(responseObject.getSomeProperty("bar"));

    return responseObject;
  

【讨论】:

感谢 Summers 先生提供此信息,我想我通过编辑 Davis 女士的回答来回复你们两个是错误的。它说在任何人都可以阅读之前,它需要进行同行评审。其他人可能会告诉我我做得不对 - 论坛。我会在这方面做得更好,我保证。这需要一些练习!另外,我很高兴我用“Parse”这个作品来描述我的问题,即使不是那么清楚,我也得到了你的关注……再次感谢! 我继续使用您的示例,它完美地映射。我有我需要的东西来继续这个概念 Sencha 应用程序。谢谢你们,这正是我所需要的。【参考方案2】:

这是使用 RestController 处理 POST 请求的示例。您的 JSON 只需包含 MyObject 类中所需的字段。如果您需要进一步说明,请告诉我。

@RestController
@RequestMapping(value = "/myPath")
public class MyObjectsController 

    private static Logger LOG = LoggerFactory.getLogger(MyObjectsController.class);

    @Autowired
    private MyObjectRepository myObjectRepository;

    @RequestMapping(value = "", method = POST)
    @ResponseStatus(HttpStatus.CREATED)
    public MyObject createUserPayment(@RequestBody MyObject myObject) 
        MyObject res = myObjectRepository.save(myObject);
        LOG.info("the result of the save: "+res);
        return res;
    

【讨论】:

以上是关于在 POST Spring 4.x MVC 上未解析 JSON 有效负载的主要内容,如果未能解决你的问题,请参考以下文章

Grails / Spring Security - 注册电子邮件未解锁帐户

405 - 请求方法“POST”不支持 Spring MVC + Spring Security

我们如何在 Spring MVC 中调用 requestmethod=POST?

Jquery POST在spring mvc中给出403禁止错误

spring mvc 默认请求是get 还是 post

Spring MVC HTTP 状态 405 - 不支持请求方法“POST”