Java Spring - 如何处理缺少的必需请求参数

时间:2016-06-10 10:53:02

标签: java spring spring-mvc

考虑以下映射:

@RequestMapping(value = "/superDuperPage", method = RequestMethod.GET)
public String superDuperPage(@RequestParam(value = "someParameter", required = true) String parameter)
{
    return "somePage";
}

我希望通过<{> 1}}中的来处理缺少的参数大小写。默认情况下,会返回required = false错误,但我想返回一个不同的页面。我怎样才能做到这一点?

4 个答案:

答案 0 :(得分:32)

如果请求中不存在必需的@RequestParam,Spring将抛出MissingServletRequestParameterException异常。您可以在同一个控制器或@ExceptionHandler中定义@ControllerAdvice来处理该异常:

@ExceptionHandler(MissingServletRequestParameterException.class)
public void handleMissingParams(MissingServletRequestParameterException ex) {
    String name = ex.getParameterName();
    System.out.println(name + " parameter is missing");
    // Actual exception handling
}
  

我想回来让我们说一个不同的页面。我如何实现这个目标?

正如Spring documentation所述:

  

非常类似于使用@RequestMapping注释的标准控制器方法   注释,方法参数和返回值   @ExceptionHandler方法可以灵活。例如,   可以在Servlet环境中访问HttpServletRequest   Portlet环境中的PortletRequest返回类型可以是   String,被解释为视图名称ModelAndView对象,a   ResponseEntity,或者您也可以添加@ResponseBody   方法返回值使用消息转换器转换并写入   响应流。

答案 1 :(得分:6)

替代

如果您在类上使用 @ControllerAdvice ,并且它扩展了Spring基类 ResponseEntityExceptionHandler 。为此,已在基类上创建了预定义的函数。您必须在处理程序中覆盖它。

    @Override
protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    String name = ex.getParameterName();
    logger.error(name + " parameter is missing");

    return super.handleMissingServletRequestParameter(ex, headers, status, request);
}

此基类非常有用,尤其是在您要处理框架创建的验证错误时。

答案 2 :(得分:3)

您可以使用可选类型,通过 Spring 4.1 以及 Java 8 执行此操作。在您的示例中,这意味着您的 @RequestParam String现在将具有Optional<String>类型。

Take a look at this article有关展示此功能的示例。

答案 3 :(得分:0)

也许不是那么相关,但我遇到了类似的需求:将 5xx 错误更改为 4xx 错误,因为缺少身份验证标头。

控制器如下:

@RequestMapping("list")
public ResponseEntity<Object> queryXXX(@RequestHeader(value = "Authorization") String token) {
...
}

当你在没有授权头的情况下卷曲它时,你会得到一个 5xx 错误:

curl --head -X GET "http://localhost:8081/list?xxx=yyy" -H "accept: */*"

HTTP/1.1 500
...

要将其更改为 401,您可以

@ExceptionHandler(org.springframework.web.bind.MissingRequestHeaderException.class)
@ResponseBody
public ResponseEntity<Object> authMissing(org.springframework.web.bind.MissingRequestHeaderException ex) {
        log.error(ex.getMessage(), ex);

        return IResponse.builder().code(401).message(ex.getMessage()).data(null).build();
}


@Data
public class IResponse<T> implements Serializable {
    private Integer code;
    private String message = "";
    private T data;
...
}

您可以通过自动化测试来验证:

@Test
void testQueryEventListWithoutAuthentication() throws Exception {
    val request = get("/list?enrollEndTime=1619176774&enrollStartTime=1619176774&eventEndTime=1619176774&eventStartTime=1619176774");
    mockMvc.perform(request).andExpect(status().is4xxClientError());
}