为Spring Rest控制器添加全局错误处理

时间:2018-09-12 10:54:46

标签: spring spring-mvc controller

我有很多这样的控制器

@RestController
@RequestMapping("/contracts")
public class ContractsController {

    @Autowired
    ContractsService service;

    @PostMapping("/selectAll")
    public WebMessageModel selectAll(@RequestBody ContractFiltersInputModel inputModel) {
        return new WebMessageModel(true, service.selectAll(inputModel));
    }
}

我还有另一个控制器

@Controller
public class BaseController {

    private static Logger logger = LoggerFactory.getLogger(IndexController.class);

    @RequestMapping
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {

            String requestURI = request.getRequestURI();
            StringBuffer requestURL = request.getRequestURL();
            logger.info("-----requestURI => " + requestURI + ", requestURL => " + requestURL);

            request.getRequestDispatcher(requestURI).forward(request, response);

            logger.info("-----response has been commited");

        } catch (Throwable t) {
            t.printStackTrace();
            request.getRequestDispatcher("/handleException").forward(request, response);

        }

    }
}

我需要所有传入的请求都通过此BaseController,以便制作一个全局TRY-CATCH块。我该如何实施?这种方法真的好主意吗?也许还有其他一些很棒的方法?

3 个答案:

答案 0 :(得分:1)

如果要在进入控制器方法之前拦截到控制器端点的每个请求,则需要实现import java.sql.*; import java.util.*; import javax.swing.JOptionPane; public class sqlCreateDataBase { public static void main(String [] args) { try { Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/;create = true", "root", null); Statement stmt = conn.createStatement(); String databaseName = "Login"; String sql = "CREATE DATABASE " + databaseName; stmt.executeUpdate(sql); System.out.println("Creating the Login table..."); stmt.execute("CREATE TABLE login(" + "Username CHAR(25), " + "Password CHAR(10)"); stmt.close(); conn.close(); System.out.println("Done"); } catch(Exception ex) { System.out.print("Error: " + ex.getMessage()); } } } 。您可以阅读此tutorial来了解如何实现过滤器。

如果要在一个地方捕获对控制器端点的请求所导致的所有异常(该异常可能已在任何地方抛出-控制器,服务,存储库等),则应实现filter s在ExceptionHandler中。一个简单的例子是这样的:

ControllerAdvice

以上内容可确保在此处捕获异常处理程序中指定的任何异常,以便可以简化来自REST API的异常响应。在同一here上有更多内容。

答案 1 :(得分:0)

您要寻找的是@ControllerAdvicehttp://blog.codeleak.pl/2013/11/controlleradvice-improvements-in-spring.html

的使用方法如下

答案 2 :(得分:0)

您可以use filters在请求之前或之后执行一些逻辑。在您的情况下,全局错误处理会更有用:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })
    protected ResponseEntity<Object> handleConflict(
      RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, 
          new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

此摘录摘自here