Java 从WebSocket消息处理MethodArgumentNotValidException

Java 从WebSocket消息处理MethodArgumentNotValidException,java,spring-boot,validation,websocket,Java,Spring Boot,Validation,Websocket,我使用SpringWebSocket,我有一个带有验证注释的模型,希望在保存之前捕获它的验证消息。考虑这个 @控制器< /代码>我正在测试: @Controller public class MessageThreadController { /* A plain XHR post request with a JSON body to match MessageThread. */ @RequestMapping( headers={"Accept=a

我使用SpringWebSocket,我有一个带有验证注释的模型,希望在保存之前捕获它的验证消息。考虑这个<代码> @控制器< /代码>我正在测试:

@Controller
public class MessageThreadController {
    /* A plain XHR post request with a JSON body to match MessageThread. */
    @RequestMapping(
        headers={"Accept=application/hal+json", "Content-Type=application/json", "X-Requested-With=XMLHttpRequest"},
        method={RequestMethod.POST},
        produces="application/hal+json",
        value="/api/unsecure/thread/create")
    public HttpEntity createPost(@Valid @RequestBody MessageThread messageThread) throws Exception {
        return ResponseEntity.ok("valid");
    }

    /* The same request above but for WebSocket.*/
    @MessageMapping("/api/secure/thread/create")
    @SendToUser("/api/secure/broadcast")
    public HttpEntity createMessage(@Valid @RequestBody MessageThread messageThread) throws Exception {
        return ResponseEntity.ok("valid");
    }
}
我有一个
@ControllerAdvice
来捕获可能发生的
异常
s:

@ControllerAdvice
public class MessageThreadControllerAdvice {
    private static final Logger log = LoggerFactory.getLogger(MessageThreadControllerAdvice.class);

    /* MessageThreadController.createPost() validation exception are handled here. */
    @ExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException.class)
    public void methodArgumentNotValidExceptionHandler(
        org.springframework.web.bind.MethodArgumentNotValidException e) {
        log.trace("methodArgumentNotValidExceptionHandler");
    }

    /* MessageThreadController.createMessage() validation exception are handled here. */
    @ExceptionHandler(org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException.class)
    @SendToUser("/api/secure/broadcast")
    public void methodArgumentNotValidWebSocketExceptionHandler(
        org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException e) {
        log.trace("methodArgumentNotValidWebSocketExceptionHandler");
    }

    /* All exceptions are handled here. */
    @ExceptionHandler
    @SendToUser("/api/secure/broadcast")
    public void exceptionHandler(Exception e) {
        log.trace("exceptionHandler");
    }
}
这里是问题的对象:

@Getter @Setter
public class MessageThread {
    @Size(min=1, message="{validation.userIds.empty}")
    @NotNull(message="{validation.userIds.null}")
    private Set<BigInteger> userIds;
}
验证开始了。问题在于,只有来自
MessageThreadController.createPost()
的异常得到处理,而来自
MessageThreadController.createMessage()
的异常没有得到处理:

2020-08-21 11:54:00.651错误4444---[nboundChannel-4]。WebSocketAnnotationMethodMessageHandler:消息处理程序方法中未处理的异常

org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException:无法解析public void controller.MessageThreadController.createMessage(model.form.MessageThread)中索引0处的方法参数抛出java.lang.Exception:1个错误:[字段“UserId”上的对象“MessageThread”中的字段错误:拒绝的值[]];代码[Size.messageThread.userIds,Size.userIds,Size.java.util.Set,Size];参数[org.springframework.context.support.DefaultMessageSourceResolvable:code[messageThread.userIds,userIds];参数[];默认消息[userIds],2147483647,1];默认消息[Size必须介于1和2147483647]]


如何处理websocket消息中抛出的
MethodArgumentNotValidException

您可以使用
@MessageExceptionHandler
注释对
@ControllerAdvice
方法进行注释

@ControllerAdvice
公共类MessageThreadControllerAdvice{
私有静态最终记录器log=LoggerFactory.getLogger(MessageThreadControllerAdvice.class);
/*MessageThreadController.createPost()验证异常在此处处理*/
@ExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException.class)
public void methodArgumentNotValidExceptionHandler(
org.springframework.web.bind.MethodArgumentNotValidException(e){
trace(“methodArgumentNotValidExceptionHandler”);
}
/*MessageThreadController.createMessage()验证异常在此处处理*/
@MessageExceptionHandler(org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException.class)
@发送程序(“/api/secure/broadcast”)
public void methodArgumentNotValidWebSocketExceptionHandler(
org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException){
trace(“methodArgumentNotValidWebSocketExceptionHandler”);
}
/*所有异常都在这里处理*/
@例外处理程序
@发送程序(“/api/secure/broadcast”)
公共无效例外处理程序(例外e){
log.trace(“exceptionHandler”);
}
}
此注释也可应用于
@Controller
级别

请注意,自Spring 4.2以来,
@ControllerAdvice
级别支持此注释

{"userIds":[]}