【问题标题】:Manage exception管理异常
【发布时间】:2017-05-26 14:10:58
【问题描述】:

我开发了一个应用程序 spring boot。我想管理异常而不向客户端发送错误 500。

我想做这样的事情:

 @RequestMapping(value = "/testRest", method = RequestMethod.GET)
    public @ResponseBody Person tst(HttpServletResponse response) {
        try {
            return ldapService.getUserByPrimaryKey("tst@ts.com");
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return (Person) "{\"ERROR\": \" + e.getMessage() +\"}";   // This not work
        }
    }

你有什么想法吗?

【问题讨论】:

    标签: java spring exception spring-boot


    【解决方案1】:

    return (Person) "{\"ERROR\": \" + e.getMessage() +\"}"; // 这不行

    这不起作用,因为您试图将 String 对象转换为 Person 类型。我相信它甚至不应该编译。

    有两种方法可以解决这个问题:

    • 返回 Person 对象,因为您使用的是 @ResponseBody,它将被序列化为 JSON
    • 如果要手动返回 JSON 响应,则应返回 String 而不是 Person 并正确设置 Content-Type 标头(通过使用 @RequestMapping(produces = "application/json"response.setContentType("application/json")

    我还建议阅读 Exception Handling in Spring MVC 文章以找到更多在 Spring MVC 中处理异常的方法。


    更新:

    在这种简单的情况下,您可以使用带有单个字段的Map

    public @ResponseBody Map<String, String> tst(HttpServletResponse response) {
       ...
       return Collections.singletonMap("ERROR": e.getMessage());
    

    【讨论】:

    • 我想要的是什么时候可以返回 Person 对象,什么时候不可以,例如错误 500 我会返回一个像 {"error": "the exception details"}跨度>
    • 你应该在描述中提到这一点。在这种情况下,您必须使用类似@AdviceController(参见spring.io/blog/2013/11/01/…)的东西,因为不可能从方法返回具有不同类型的对象。
    【解决方案2】:

    使用 ControllerAdvice,我解释一下:

    @ControllerAdvice
    public class MyExceptionsHandlerController{
    
      @ExceptionHandler(Exception.class)
      @ResponseBody Person handleException(){
       //do what you want 
      }
    }
    

    请注意,使用Exception 过于通用,您应该更加细化您要处理的异常类型。

    【讨论】:

      【解决方案3】:

      做这样的事情:

      public static class Person{
          //other fields
          public String error = null;
      
          public String getError() {
              return error;
          }
      
          public void setError(String error) {
              this.error = error;
          }
      }
      
      @RequestMapping(value = "/testRest", method = RequestMethod.GET)
      public @ResponseBody Person tst(HttpServletResponse response) throws Exception {
          try {
              return ldapService.getUserByPrimaryKey("tst@ts.com");
          } catch (Exception e) {
              Person person = new Person();
              person.setError("{\"ERROR\": " + e.getMessage() +"}");          
              return person;
          }
      }
      

      你不想发回 500 不要这样做:

      response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      

      你也不能在java中将字符串转换为Person类。

      【讨论】:

      • 感谢@tsolak Peteosian,这意味着我必须在每个对象中添加一个字段错误,该错误将在 catch 部分中设置
      • 您的建议可行,但生成的 JSON 看起来会很奇怪,因为 error 成员将保存的不是错误字符串,而是带有错误的 json。
      • 只是不要使用大括号。这只是格式化错误的问题。
      猜你喜欢
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 2015-03-10
      • 2016-02-02
      • 1970-01-01
      相关资源
      最近更新 更多