【问题标题】:Spring boot API call with multiple @RequestParam具有多个 @RequestParam 的 Spring Boot API 调用
【发布时间】:2019-07-04 00:22:00
【问题描述】:

我需要查找日期范围之间的条目,并希望在 Spring Boot API 中进行 GET 调用,如下所示,

$ curl -X GET http://localhost:8080/api/v1/appointments/findWithRange?start=2018-10-01&end=2018-10-15

我编写了 GET 调用,

@GetMapping("/findWithRange")
    public ResponseEntity<List<Appointment>> findAllWithCreationRange(@RequestParam("start")  Date start, @RequestParam("end") Date end) {

        List<Appointment> appointments = service.findAllWithCreationRange(start, end);

        if (Objects.isNull(appointments)) {
            ResponseEntity.badRequest().build();
        }

        return ResponseEntity.ok(appointments);
    }

我得到了返回响应,

{"timestamp":"2019-02-10T07:58:22.151+0000","status":400,"error":"Bad Request","message":"Required Date parameter 'end' is not present","path":"/api/v1/appointments/findWithRange"}

如何正确编写调用?似乎我无法调试,因为断点没有捕获。

【问题讨论】:

  • 你确定要从你的 shell 中引用你的 &amp; 吗?
  • 什么意思?
  • 在您获得 curl 输出并打印类似 [1] 12345 的内容之前,shell 是否会立即返回?
  • 是的,我只是发现 API 很好,并且在 Chrome 中可以正常工作。问题仅在终端中。
  • 你需要了解主题shell quoting,这是你的问题。

标签: java rest spring-boot curl https


【解决方案1】:

你的问题很简单——在你的电话中

$ curl -X GET http://localhost:8080/api/v1/appointments/findWithRange?start=2018-10-01&end=2018-10-15

&amp; 标志告诉操作系统'在后台运行curl -X GET http://localhost:8080/api/v1/appointments/findWithRange?start=2018-10-01'。这就是 end 日期未定义的原因。

只需用双引号将您的网址括起来:

$ curl -X GET "http://localhost:8080/api/v1/appointments/findWithRange?start=2018-10-01&end=2018-10-15"

【讨论】:

  • 是的,很简单,但我花了大约 1.5 小时来尝试各种选项并阅读所有代码,直到我在 Chrome 中输入相同的命令(有效):|
  • @Arefe 以后要密切注意你的输出。在这种情况下,curl -X 会告诉您它只传递了第一个请求参数,这将是一个很大的提示。
【解决方案2】:

您应该指定@DateTimeFormat

Here你可以找到更多详情

【讨论】:

    【解决方案3】:

    如果你想接收参数作为日期,那么需要定义模式。 试试这个:

    @GetMapping("/findWithRange")
        public ResponseEntity<List<Appointment>> findAllWithCreationRange(@RequestParam("start") @DateTimeFormat(pattern = "yyyy-MM-dd") Date start, @RequestParam("end") @DateTimeFormat(pattern = "yyyy-MM-dd") Date end) {
    
            List<Appointment> appointments = service.findAllWithCreationRange(start, end);
    
            if (Objects.isNull(appointments)) {
                ResponseEntity.badRequest().build();
            }
    
            return ResponseEntity.ok(appointments);
        }
    

    如果要接收 sql.Date 则需要使用自定义反序列化器。试试这个:

    @GetMapping("/findWithRange")
            public ResponseEntity<List<Appointment>> findAllWithCreationRange(@RequestParam("start") @JsonDeserialize(using = SqlDateConverter.class) Date start, @RequestParam("end") @JsonDeserialize(using = SqlDateConverter.class) Date end) {
    
                List<Appointment> appointments = service.findAllWithCreationRange(start, end);
    
                if (Objects.isNull(appointments)) {
                    ResponseEntity.badRequest().build();
                }
    
                return ResponseEntity.ok(appointments);
            }
    

    Sql 日期转换器:

    public class SqlDateConverter extends JsonDeserializer<Date> {
    
        @Override
        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            return Date.valueOf(p.getText());
        }
    }
    

    如果您想全局反序列化 sql.Date,请尝试仅添加此 bean:

    @Bean
        public Jackson2ObjectMapperBuilder configureObjectMapper() {
            Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
            ObjectMapper objectMapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addDeserializer(Date.class,new SqlDateConverter());
            objectMapper.registerModule(module);
            builder.configure(objectMapper);
            return builder;
        }
    

    【讨论】:

    • 是的,我在检查其他答案后尝试过,不幸的是,这并没有解决问题。
    • 试试这个反序列化器
    猜你喜欢
    • 2016-09-19
    • 2018-07-11
    • 2015-02-03
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多