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

daupos2t  于 2023-10-24  发布在  Spring
关注(0)|答案(5)|浏览(170)

考虑以下Map:

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

我想通过在required = false中添加而不是来处理缺少参数的情况。默认情况下,返回400错误,但我想返回,比如说,一个不同的页面。我如何实现这一点?

x6yk4ghg

x6yk4ghg1#

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

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

我想返回让我们说一个不同的页面。我如何实现这一点?
正如Spring文档所述:
与使用@RequestMapping注解的标准控制器方法非常相似,@ExceptionHandler方法的方法参数和返回值可以是灵活的。例如,HttpServletRequest可以在Servlet环境中访问,PortletRequest可以在Portlet环境中访问。返回类型可以是String,它被解释为视图名称,一个ModelAndView对象,一个ResponseEntity,或者你也可以添加@ResponseBody,让方法返回值用消息转换器转换并写入响应流。

3yhwsihp

3yhwsihp2#

一个替代
如果你在你的类上使用**@ControllerAdvice**,并且它扩展了Spring基类ResponseIdentyExceptionException。已经为此在基类上创建了一个预定义的函数。你必须在你的处理程序中覆盖它。

@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);
}

这个基类非常有用,特别是当您想要处理框架创建的验证错误时。

neskvpey

neskvpey3#

您可以在Spring 4.1Java 8中通过利用Optional类型来做到这一点。在您的示例中,这意味着您的**@RequestParam**String现在将具有Optional<String>类型。
Take a look at this article的示例展示了此功能。

enxuqcxy

enxuqcxy4#

我今天(30/08/2023)使用Spring 3.1.3时遇到了同样的问题。您可以通过重写ResponseEntityExceptionHandler基类的受保护函数handleMissingServletRequestParameter来解决此问题。

@ControllerAdvice
class DevBlogExceptionHandler : ResponseEntityExceptionHandler() {

    override fun handleMissingServletRequestParameter(
        ex: MissingServletRequestParameterException,
        headers: HttpHeaders,
        status: HttpStatusCode,
        request: WebRequest
    ): ResponseEntity<Any>? {

        val errorMessages = listOf("Required query parameter \"${ex.parameterName}\" is missing")

        val error = DevBlogException(
            status = HttpStatus.BAD_REQUEST,
            errors = errorMessages,
            timeStamp = LocalDateTime.now(),
            statusCode = status.value()
        )

        return ResponseEntity<Any>(error, error.status);
    }

}
r7xajy2e

r7xajy2e5#

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

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

当你cURL它没有授权头,你得到一个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());
}

相关问题