Java 在处理过程中发生错误时,rest控制器应如何操作

Java 在处理过程中发生错误时,rest控制器应如何操作,java,spring,rest,Java,Spring,Rest,我有一个我感兴趣的问题 假设我有一些rest控制器和一些用javascript编写的rest客户端。此客户端向控制器发送请求,并且在处理过程中出现一些错误。在这种情况下,控制器应该如何操作?应该返回null吗?还是用信息串 例如,我们有这样的控制器: @RequestMapping("/user", method = RequestMethod.POST) public @ResponseBody String createUser(User user) { try {

我有一个我感兴趣的问题

假设我有一些rest控制器和一些用javascript编写的rest客户端。此客户端向控制器发送请求,并且在处理过程中出现一些错误。在这种情况下,控制器应该如何操作?应该返回null吗?还是用信息串

例如,我们有这样的控制器:

@RequestMapping("/user", method = RequestMethod.POST)
public @ResponseBody String createUser(User user) {

    try {
        userService.create(user);   
    } catch(UserCreationException e) {
    }
}

这是一个非常简单的示例,但它是许多不同的控制器示例,比如返回一些资源或仅在服务器端更改状态的控制器,我不知道发生错误时该怎么办

您应该真正使用HTTP错误代码,并使用您的客户端技术(例如,您的案例中的JavaScript)处理错误

例如:给定未经授权读取/访问资源的用户,则应将403错误代码返回给客户端。通过使用标准HTTP/REST错误代码,您符合任何客户机都可以理解的API,无论是JavaScript还是其他什么


有了SpringMVC和Rest控制器,这真的很容易。为异常创建一个简单类,并用HTTP错误代码注释该类,例如403错误的
@ResponseStatus(value=HttpStatus.FORBIDDEN)
。然后在您的控制器中,您可以抛出异常,该异常将返回HTTP错误代码。

您应该真正使用HTTP错误代码,并使用客户端技术(即您的情况下的JavaScript)处理错误

例如:给定未经授权读取/访问资源的用户,则应将403错误代码返回给客户端。通过使用标准HTTP/REST错误代码,您符合任何客户机都可以理解的API,无论是JavaScript还是其他什么

有了SpringMVC和Rest控制器,这真的很容易。为异常创建一个简单类,并用HTTP错误代码注释该类,例如403错误的
@ResponseStatus(value=HttpStatus.FORBIDDEN)
。然后在控制器中,您可以抛出异常,该异常将返回HTTP错误代码。

根据,如果在处理过程中出现内部错误,服务器必须返回

如果错误是由于客户端执行了错误的请求而导致的:服务器必须返回一个错误代码>=400和<500

当然,在客户端,您必须注意正确处理这些错误(即显示友好的错误消息或类似信息)。

根据,如果处理过程中出现内部错误,服务器必须返回

如果错误是由于客户端执行了错误的请求而导致的:服务器必须返回一个错误代码>=400和<500

当然,在客户端,您必须注意正确处理这些错误(即显示友好的错误消息或类似的内容)。

为了改善开发人员(您的消费者)的体验,除了Http状态代码之外,最好在响应体上加上适当的错误消息进行响应

下面是spring的一个示例,主要抛出一个异常,您可以通过扩展ResponseEntityExceptionHandler@ControllerAdvice来处理该异常

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException  extends RuntimeException{
    private static final long serialVersionUID = 1L;
    public ResourceNotFoundException(String message) {
        super(message);
    }

}

@Controller
@RequestMapping("/XXXXXs")
public class DoctypesController {
    @RequestMapping( method = RequestMethod.GET , value="/xxx")
    public  ResponseEntity<?> getXXXXXX(HttpServletRequest request) {
         if (XXX == null ) {
               throw new ResourceNotFoundException("XXXX Not found for);
           }else{
            response = buildResponse(xxxx)
           }

         return response;
    }
}


@ControllerAdvice
public class XXXXEntityExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = { ResourceNotFoundException.class })
protected ResponseEntity<Object> handleMissingResource(RuntimeException ex, final WebRequest request) {
HttpStatus status = HttpStatus.NOT_FOUND;
    return new ResponseEntity<Object>(new Error(String.valueOf(status.value()), status.getReasonPhrase(),ex.getMessage()),status);
    }
}
@ResponseStatus(未找到HttpStatus.NOT_)
公共类ResourceNotFoundException扩展RuntimeException{
私有静态最终长serialVersionUID=1L;
公共资源NotFoundException(字符串消息){
超级(信息);
}
}
@控制器
@请求映射(“/XXXXX S”)
公共类doctypes控制器{
@RequestMapping(method=RequestMethod.GET,value=“/xxx”)
公共响应getXXXXXX(HttpServletRequest请求){
如果(XXX==null){
抛出新的ResourceNotFoundException(“找不到的XXXX”);
}否则{
响应=构建响应(xxxx)
}
返回响应;
}
}
@控制器建议
公共类XXXXEntityExceptionHandler扩展了ResponseEntityExceptionHandler{
@ExceptionHandler(值={ResourceNotFoundException.class})
受保护的ResponseEntity handleMissingResource(RuntimeException ex,最终WebRequest请求){
HttpStatus status=HttpStatus.NOT_FOUND;
返回新的ResponseEntity(新错误(String.valueOf(status.value())、status.GetReasonPhase()、ex.getMessage()、status);
}
}
为了改善开发人员(您的消费者)的体验,除了Http状态代码之外,最好在响应正文中添加适当的错误消息

下面是spring的一个示例,主要抛出一个异常,您可以通过扩展ResponseEntityExceptionHandler@ControllerAdvice来处理该异常

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException  extends RuntimeException{
    private static final long serialVersionUID = 1L;
    public ResourceNotFoundException(String message) {
        super(message);
    }

}

@Controller
@RequestMapping("/XXXXXs")
public class DoctypesController {
    @RequestMapping( method = RequestMethod.GET , value="/xxx")
    public  ResponseEntity<?> getXXXXXX(HttpServletRequest request) {
         if (XXX == null ) {
               throw new ResourceNotFoundException("XXXX Not found for);
           }else{
            response = buildResponse(xxxx)
           }

         return response;
    }
}


@ControllerAdvice
public class XXXXEntityExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = { ResourceNotFoundException.class })
protected ResponseEntity<Object> handleMissingResource(RuntimeException ex, final WebRequest request) {
HttpStatus status = HttpStatus.NOT_FOUND;
    return new ResponseEntity<Object>(new Error(String.valueOf(status.value()), status.getReasonPhrase(),ex.getMessage()),status);
    }
}
@ResponseStatus(未找到HttpStatus.NOT_)
公共类ResourceNotFoundException扩展RuntimeException{
私有静态最终长serialVersionUID=1L;
公共资源NotFoundException(字符串消息){
超级(信息);
}
}
@控制器
@请求映射(“/XXXXX S”)
公共类doctypes控制器{
@RequestMapping(method=RequestMethod.GET,value=“/xxx”)
公共响应getXXXXXX(HttpServletRequest请求){
如果(XXX==null){
抛出新的ResourceNotFoundException(“找不到的XXXX”);
}否则{
响应=构建响应(xxxx)
}
返回响应;
}
}
@控制器建议
公共类XXXXEntityExceptionHandler扩展了ResponseEntityExceptionHandler{
@ExceptionHandler(值={ResourceNotFoundException.class})
受保护的ResponseEntity handleMissingResource(RuntimeException ex,最终WebRequest请求){
HttpStatus status=HttpStatus.NOT_FOUND;
返回新的ResponseEntity(新错误(String.valueOf(status.value())、status.GetReasonPhase()、ex.getMessage()、status);
}
}