【问题标题】:Curl POST command to pass json data to spring-boot app not workingCurl POST命令将json数据传递给spring-boot应用程序不起作用
【发布时间】:2017-11-05 15:16:52
【问题描述】:

查看了其他相关帖子,但似乎没有任何效果。

基本上,我想弄清楚如何将数据传递给我宁静的 spring-boot 应用程序。

这是我正在使用的 curl 命令:

$ curl -iX POST -H 'Content-Type: application/json' -d @args.json http://localhost:8080/myapp/dummyApi

args.json 包含:

file: args.json:

{
  "arg1": "hello",
  "arg2": 10, 
  "arg3": {
    "a": "1",
    "b": "2" 
  }
}

API 在MyController.java 中定义如下:

file: MyController.java

@RestController
@RequestMapping("/myapp")
public class MyController {

//...

static class DummyRet {
    private String foo;
    public DummyRet(String f) {
        foo = f;
    }
    public String getFoo() {
        return foo;
    }
    public void setFoo(String foo) {
        this.foo = foo;
    }
}

@RequestMapping(value="/dummyApi", method=RequestMethod.POST)
public DummyRet dummyApi(@RequestParam(value = "arg1", required = false, defaultValue = "") String arg1,
                               @RequestParam(value = "arg2", required = false, defaultValue = "") Long arg2,
                               @RequestParam(value = "arg3", required = false) Map<String, String> arg3) {
    LOGGER.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    LOGGER.info("Arguments received:");
    LOGGER.info("arg1: " + arg1);
    LOGGER.info("arg2: " + arg2);
    LOGGER.info("arg3: " + arg3);
    LOGGER.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    return new DummyRet("foo");
}

//...
}

curl 命令的返回是 200 成功(因为不需要任何参数)但是 args 的值没有达到dummyApi 方法

$ curl -iX POST -H 'Content-Type: application/json' -d @args.json http://localhost:8080/myapp/dummyApi
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 04 Jun 2017 15:37:42 GMT

{"foo":"foo"}

服务器控制台如下所示:

2017-06-04 18:17:56.818 DEBUG 32258 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing POST request for [/myapp/dummyApi]
2017-06-04 18:17:56.818 DEBUG 32258 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /myapp/dummyApi
2017-06-04 18:17:56.818 DEBUG 32258 --- [nio-8080-exec-7] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public com.xx.controllers.MyController$DummyRet com.xx.controllers.MyController.dummyApi(java.lang.String,java.lang.Long,java.util.Map<java.lang.String, java.lang.String>)]
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : Arguments received:
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : arg1: 
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : arg2: null
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : arg3: null
2017-06-04 18:17:56.819  INFO 32258 --- [nio-8080-exec-7] c.p.controllers.MyController       : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2017-06-04 18:17:56.819 DEBUG 32258 --- [nio-8080-exec-7] m.m.a.RequestResponseBodyMethodProcessor : Written [com.xx.controllers.MyController$DummyRet@c35d46f] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@301ec38b]
2017-06-04 18:17:56.819 DEBUG 32258 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-06-04 18:17:56.819 DEBUG 32258 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet        : Successfully completed request

我希望我没有遗漏任何重要的细节,但如果有任何遗漏,请告诉我。

【问题讨论】:

    标签: java json curl post spring-boot


    【解决方案1】:

    这行得通:

    我的 spring-boot java 方法有两个问题,

    1. 我为参数指定了@RrequestParam,而我应该使用@RequestBody
    2. 我有多个这样的方法参数,在 POST 中它应该是一个(见脚注)@RequestBody

    但由于我需要将多个参数传递给该方法,因此解决方案是将这些参数包装在一个支持对象中,如下所示:

    public static class Args {
        // members
        private String arg1;
        private Long arg2;
        private Map<String, String> arg3;
        // accessors
        public String getArg1() {return arg1;}
        public void setArg1(String arg1) {this.arg1 = arg1;}
        public Long getArg2() {return arg2;}
        public void setArg2(Long arg2) {this.arg2 = arg2;}
        public Map<String, String> getArg3() {return arg3;}
        public void setArg3(Map<String, String> arg3) {this.arg3 = arg3;}
    }
    

    接收器方法将是:

    @RequestMapping(value="/dummyApi", method=RequestMethod.POST)
    public DummyRet dummyApi(@RequestBody Args args) {
      LOGGER.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
      LOGGER.info("Arguments received:");
      LOGGER.info("arg1: " + args.getArg1().toString());
      LOGGER.info("arg2: " + args.getArg2().toString());
      LOGGER.info("arg3: " + args.getArg3().toString());
      LOGGER.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
      return new DummyRet("foo");
    }
    

    脚注:事实上,可以通过自定义实现传递多个参数,如this SO 响应中所述。没试过

    【讨论】:

      【解决方案2】:

      参考下面的示例,

      curl -H "Content-Type: application/json" --data @body.json 
      http://localhost:8080/ui/webapp/conf
      

      【讨论】:

      • 感谢您的建议,但我仍然得到与以前相同的行为
      • 你可以试试 chrome postman 扩展吗?如果您能够使用任何邮政客户端(例如邮递员)获得响应,那么 curl 也应该可以工作,因为它是客户端。邮递员:chrome.google.com/webstore/detail/postman/…
      • 抱歉耽搁了,刚刚尝试了 chrome postman,仍然得到相同的行为,以确保我没有在克隆 spring-boot-tutorial 的 Spring Boot 应用程序中使用任何有趣的东西。只添加了与dummyApi相关的代码
      • 很遗憾没有:(
      猜你喜欢
      • 2020-12-13
      • 2017-01-01
      • 1970-01-01
      • 2020-07-01
      • 2018-10-06
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多