【问题标题】:HTTP Status 400 - Required String parameter 'walletName' is not presentHTTP 状态 400 - 必需的字符串参数“钱包名称”不存在
【发布时间】:2017-08-19 13:03:52
【问题描述】:

我使用Java/ Spring MVC RESTful 应用程序并在执行POST 请求时获得400 HTTP status error。提供@RestController方法,

@RequestMapping(value = "/generateAddress", method = RequestMethod.POST)
    public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestParam("walletName") String walletName,
                                                             @RequestParam("currencyName") String currencyName) {

        logger.info("walletName {} and currencyName {}", walletName, currencyName);

        // return if the wallet name or the currency is null
        if (Objects.isNull(walletName) || Objects.isNull(currencyName)) {
            return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
        }

        WalletInfo walletInfo = walletService.generateAddress(walletName, currencyName);

        if (Objects.isNull(walletInfo)) {
            return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
        }

        WalletInfoWrapper walletInfoWrapper = new WalletInfoWrapper();
        walletInfoWrapper.setName(walletInfo.getName());

        return new ResponseEntity<WalletInfoWrapper>(walletInfoWrapper, HttpStatus.CREATED);
    }

下面提供的Postman 中的POST 请求,

错误信息提示,Required String parameter 'walletName' is not present

我还可以提供servicesdataase 层的代码,用于观察下拉操作。这里有什么问题?

UPDATE

我像这样更新了Postman 请求,但仍然有同样的错误,

UPDATE 1

我还是有同样的问题,

POST有数据,

{"walletName":"puut","currencyName":"Bitcoin"}

代码如下,

@RequestMapping(value = "/generateAddress", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestBody WalletWithMoneyRequest walletWithMoneyRequest) {

        String walletName = walletWithMoneyRequest.getWalletName();

        String currencyName = walletWithMoneyRequest.getCurrencyName();

        logger.info("walletName {} and currencyName {}", walletName, currencyName);

        // return if the wallet name or the currency is null
        if (Objects.isNull(walletName) || Objects.isNull(currencyName)) {
            return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
        }

        WalletInfo walletInfo = walletService.generateAddress(walletName, currencyName);

        if (Objects.isNull(walletInfo)) {
            return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
        }

        WalletInfoWrapper walletInfoWrapper = new WalletInfoWrapper();
        walletInfoWrapper.setName(walletInfo.getName());

        return new ResponseEntity<WalletInfoWrapper>(walletInfoWrapper, HttpStatus.CREATED);
    }

提供POJO

private class WalletWithMoneyRequest {

        String walletName;

        String currencyName;

        public WalletWithMoneyRequest(String walletName, String currencyName) {
            this.walletName = walletName;
            this.currencyName = currencyName;
        }

        public WalletWithMoneyRequest() {
        }

        public String getWalletName() {
            return walletName;
        }

        public String getCurrencyName() {
            return currencyName;
        }

        public void setCurrencyName(String currencyName) {
            this.currencyName = currencyName;
        }

        public void setWalletName(String walletName) {
            this.walletName = walletName;
        }
    }

这是错误信息,

这里是 Tomcat 服务器信息,

org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver: 08/19/2017 19:45:55 - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `mobi.puut.controllers.WalletRestController$WalletWithMoneyRequest` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `mobi.puut.controllers.WalletRestController$WalletWithMoneyRequest` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor
 at [Source: (PushbackInputStream); line: 1, column: 2]

Tomcat Localhost log

Tomcat Catalina log

【问题讨论】:

  • 您似乎正在发送一个 JSON 字符串作为参数,但这不是您的控制器所期望的。或者这就是 Postman 中的样子?
  • @Artin,您的服务器控制台或日志是否有任何输出可能表明您的服务器不喜欢您的请求的原因?
  • 是的,我确实有一条消息,请查看更新后的帖子
  • 看到了输出。好的。尝试将您的课程 WalletWithMoneyRequest 设为公开而不是私有。
  • 让它public 没有帮助,我仍然得到HTTP status of 400。虽然我认为我们已经通过问题中提供的错误消息解决了这个问题。

标签: java hibernate rest spring-mvc


【解决方案1】:

编辑

在您的 Postman 请求中,不要发送 JSON,而是将值发送为 x-www-form-urlencoded

【讨论】:

  • 和以前一样的错误,我已经用信息更新了答案
  • @Artin 对不起,试试x-www-form-urlencoded 它会像@zerpsed 提到的那样在 URL 中发送参数
【解决方案2】:

您的控制器需要 2 个通常如下所示的请求参数:/someurl?walletName=my-wallets-name&currencyName=dollars。

您在帖子正文中发送一个 json 字符串,但没有形式参数。您需要更新您的 POST 或您的控制器以使两端一致。我认为您可能想用具有两个字符串成员的 Java pojo 替换两个 @RequestParam 注释字符串:walletName 和 currencyName,将该 pojo 作为参数放在您的请求方法中,并在其前面加上注释 @RequestBody。这将匹配您的 json 帖子。

要让您的控制器接受正文中带有 JSON 的帖子,请像这样编辑它:

@RequestMapping(value = "/generateAddress", method = RequestMethod.POST)
public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestBody
    WalletWithMoneyRequest myJsonRequestComingIn) {
    logger.info("walletName {} and currencyName {}", myJsonRequestComingIn.getWalletName(), myJsonRequestComingIn.getCurrencyName());

还有你的pojo

public class WalletWithMoneyRequest{ 

    private String walletName;
    private String currencyName;

    //getters and setters down here. 

【讨论】:

  • 我避免提供明确的答案,这样如果你想学习新东西,你就有机会弄清楚。让我知道,如果您需要,我会用代码示例进行更新。
  • 代码示例将对答案有所帮助。如果你这样做,请提供(update either the POST, or the controller)正确执行操作的两种方式。
  • 看看我发布的答案。我接受了你的建议
  • @Artin,太好了。很高兴你得到它。
【解决方案3】:

详细说明 zerpsed 的回答。

将签名改为:

public ResponseEntity<WalletInfoWrapper> generateAddress(@ResponseBody WalletPOJO walletCurrency)

WalletPOJO 有两个字段 walletName 和 currencyName

【讨论】:

    【解决方案4】:

    我相信这个问题现在已经解决了。我使用了POJO,正如RESTful 方法中的@RequestBody 参数所建议的那样。这里的问题是我需要将POJO 从类中取出(尽管在同一个文件中),然后将实体目录作为实体放入。

    class WalletWithMoneyRequest {
    
        String walletName;
    
        String currencyName;
    
        public WalletWithMoneyRequest(String walletName, String currencyName) {
            this.walletName = walletName;
            this.currencyName = currencyName;
        }
    
        public WalletWithMoneyRequest() {
        }
    
        public String getWalletName() {
            return walletName;
        }
    
        public String getCurrencyName() {
            return currencyName;
        }
    
        public void setCurrencyName(String currencyName) {
            this.currencyName = currencyName;
        }
    
        public void setWalletName(String walletName) {
            this.walletName = walletName;
        }
    }
    

    主要问题是认为HQL 中有错误,

    我写了currency =: currency应该是currency = :currency

    我仍然无法在数据库中拥有数据,因为我需要修改database 层中的方法。

    【讨论】:

      【解决方案5】:

      En POSTMAN 在 params 中设置变量

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-12
        • 2018-05-10
        • 2013-08-01
        • 2015-02-12
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多