Java Spring控制器-显示JSON而不是白标签错误页面(在浏览器中)

Java Spring控制器-显示JSON而不是白标签错误页面(在浏览器中),java,spring-boot,spring-mvc,Java,Spring Boot,Spring Mvc,Hi有一个简单的spring控制器,在出现错误时返回ResponseStatusException @RestController @RequestMapping("/process") public class ProcessWorkitemController { @Autowired MyService service; @GetMapping("/{id}") public ResponseEntity<?&

Hi有一个简单的spring控制器,在出现错误时返回ResponseStatusException

@RestController
@RequestMapping("/process")
public class ProcessWorkitemController {
    @Autowired MyService service;
    
    @GetMapping("/{id}")
    public ResponseEntity<?> findById(@PathVariable Long id) {
        Optional<MyObj> opt = service.getObj(id);
        opt.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Process id %s not found", id), null));
        
        return ResponseEntity.ok(opt.get());
    }
}
当我使用浏览器调用同一服务时,它会显示带有custmo错误消息的白标签错误页面

我想要一个JSON作为响应,甚至在浏览器上,这是可能的吗


提前感谢。

我会避免使用
ResponseStatusException
,尤其是在构建需要统一方式处理异常的应用程序时。我要做的是:

  • 创建一个新类并使用
    @RestControllerAdvice
    注释。这将有效地成为应用程序异常处理的主要入口点
  • 创建处理不同类型异常的方法,并使用异常中的消息和/或信息返回响应
  • 只需从服务层或控制器层抛出这样的异常,并让异常处理程序处理它
  • 下面是一个简单的例子(忽略内部类——只有在那里才能节省空间)

  • 异常处理程序:
  • 控制器
  • @RestController
    @请求映射(“/process”)
    公共类进程控制器{
    @GetMapping(“/{id}”)
    公共响应findById(@PathVariable Long id){
    返回可选
    .of(1L)
    .filter(number->number.equals(id))
    .map(ResponseEntity::ok)
    .OrelsThrow(()->new ProcessNotFoundException(String.format(“找不到id为%s的进程,id)));
    }
    }
    

    所有这些就绪后,您应该有一种统一的方法来处理异常,无论客户端如何,它也总是返回正确的消息。

    也许浏览器中的
    接受类型
    请求头不会将
    应用程序/json
    作为其值发送?正如Pranjal提到的,这种情况的发生是因为您的浏览器正在请求它;了解它是如何工作的很重要。我看不出问题出在哪里。无法理解为什么使用接受的答案时问题没有出现。有什么解释吗?非常感谢。尝试了您的解决方案,效果非常好,现在我甚至可以在浏览器中看到Json作为响应。但是,我还需要有关调用路径的信息。非常感谢。解决了将
    HttpServletRequest
    对象传递到
    handleException
    方法,然后从中获取Uri
    request.getRequestURI()
    {
       "timestamp": "2021-01-20T10:59:48.082+0000",
       "status": 404,
       "error": "Not Found",
       "message": "Process id 1 not found",
       "path": "/workspace-manager/process/1"
    }
    
    @RestControllerAdvice
    public class MyExceptionHandler {
    
        @ExceptionHandler(ServiceException.class)
        public ResponseEntity<ExceptionResponse> handleException(ServiceException e) {
            return ResponseEntity
                .status(e.getStatus())
                .body(new ExceptionResponse(e.getMessage(), e.getStatus().value()));
        }
    
        public static class ExceptionResponse {
    
            private final String message;
            public String getMessage() { return message; }
    
            private final Integer code;
            public Integer getCode() { return code; }
    
            public ExceptionResponse(String message, Integer code) {
                this.message = message;
                this.code = code;
            }
    
        }
    
    }
    
    package com.ariskourt.test.controllers;
    
    import org.springframework.http.HttpStatus;
    
    public abstract class ServiceException extends RuntimeException{
    
        public ServiceException(String message) {
            super(message);
        }
    
        public abstract HttpStatus getStatus();
    
    }
    
    @RestController
    @RequestMapping("/process")
    public class ProcessController {
    
        @GetMapping("/{id}")
        public ResponseEntity<?> findById(@PathVariable Long id) {
            return Optional
            .of(1L)
            .filter(number -> number.equals(id))
            .map(ResponseEntity::ok)
            .orElseThrow(() -> new ProcessNotFoundException(String.format("Process with id %s not found", id)));
        }
    
    }