Spring用数组查询参数响应400

时间:2019-02-09 22:22:01

标签: spring spring-boot spring-mvc

我具有以下春季启动@RestController请求映射:

@RequestMapping({"/api/blog"})
@RestController
public class BlogController {

   @RequestMapping(value = "/test", method = RequestMethod.GET)
   public Iterable<Blog> filterBy(
        @RequestParam(required = false, name = "filter") String filterStr,
        @RequestParam(required = false, name = "range") String rangeStr,
        @RequestParam(required = false, name="sort") String sortStr) {

           ...
   }
}

请求应如下所示:

GET http://my.api.url/api/blog/test?sort=['title','ASC']&range=[0, 24]&filter={title:'bar'}

但是,提供任何数组查询参数(范围和/或排序)都会导致响应400,除了“ HTTP状态400-错误的请求”之外,没有其他细节

仅使用文件管理器查询参数进行请求即可。添加范围和/或使用空值排序有效。当我添加方括号[]时,它似乎失败了。

我尝试添加以下异常处理程序以将问题调试到控制器和ControllerAdvice类:

@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
  logger.warn("Returning HTTP 400 Bad Request", e);
}

但是这不会被触发。 我怀疑框架中发生了什么,导致400甚至没有到达控制器。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您必须对参数进行URL编码!测试时,您应该对过滤器,范围和排序参数进行URL编码。请尝试以下操作:

"text/event-stream"

答案 1 :(得分:0)

尝试将参数定义为Lists,不要使用方括号。

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public Iterable<Blog> filterBy(
        @RequestParam(required = false, name = "filter") List<String> filterStr,
        @RequestParam(required = false, name = "range") List<String> rangeStr,
        @RequestParam(required = false, name = "sort") List<String> sortStr) {

     filterStr.forEach(s -> System.out.print(", "+ s));
     System.out.println();
     rangeStr.forEach(s -> System.out.print(", "+ s));
     System.out.println();
     sortStr.forEach(s -> System.out.print(", "+ s));
     System.out.println();
     return new ArrayList<>();
    }

    // test url with mockmvc  
    @Test
    public void filterBy() throws Exception {
        mockMvc.perform(get("/test?filter=1,2,3,4&range=5,7,8&sort=desc"))
            .andExpect(status().is2xxSuccessful());
    }

    @Test
    public void filterBy() throws Exception {
       mockMvc.perform(get("/test?filter=1&filter=2&filter=3&filter=4&range=[5,7,8]&sort=desc"))
            .andExpect(status().is2xxSuccessful());
    }

对我来说,第一个测试打印:

, 1, 2, 3, 4
, 5, 7, 8
, desc

第二个测试打印:

, 1, 2, 3, 4
, [5, 7, 8] // brackets dont seem to work that good
, desc