Làm cách nào để quản lý các ngoại lệ được đưa vào các bộ lọc trong Spring?


106

Tôi muốn sử dụng cách chung để quản lý mã lỗi 5xx, hãy nói cụ thể trường hợp db bị lỗi trên toàn bộ ứng dụng mùa xuân của tôi. Tôi muốn một json lỗi khá lớn thay vì một dấu vết ngăn xếp.

Đối với các bộ điều khiển, tôi có một @ControllerAdvicelớp cho các trường hợp ngoại lệ khác nhau và điều này cũng bắt được trường hợp db đang dừng ở giữa yêu cầu. Nhưng điều này không phải là tất cả. Tôi cũng tình cờ có một tùy chỉnh CorsFiltermở rộng OncePerRequestFiltervà ở đó khi tôi gọi, doFiltertôi nhận được CannotGetJdbcConnectionExceptionvà nó sẽ không được quản lý bởi @ControllerAdvice. Tôi đọc một số thứ trên mạng chỉ khiến tôi thêm bối rối.

Vì vậy, tôi có rất nhiều câu hỏi:

  • Tôi có cần triển khai bộ lọc tùy chỉnh không? Tôi đã tìm thấy ExceptionTranslationFilternhưng điều này chỉ xử lý AuthenticationExceptionhoặc AccessDeniedException.
  • Tôi đã nghĩ đến việc thực hiện của riêng mình HandlerExceptionResolver, nhưng điều này khiến tôi nghi ngờ, tôi không có bất kỳ ngoại lệ tùy chỉnh nào để quản lý, phải có một cách rõ ràng hơn thế này. Tôi cũng đã cố gắng thêm thử / bắt và gọi một triển khai của HandlerExceptionResolver(phải đủ tốt, ngoại lệ của tôi không có gì đặc biệt) nhưng điều này không trả về bất kỳ thứ gì trong phản hồi, tôi nhận được trạng thái 200 và phần thân trống.

Có cách nào tốt để đối phó với điều này? Cảm ơn


Chúng ta có thể ghi đè BasicErrorController của Spring Boot. Tôi đã viết blog về nó ở đây: naturalprogrammer.com/blog/1685463/…
Sanjay

Câu trả lời:


83

Vì vậy, đây là những gì tôi đã làm:

Tôi đã đọc kiến ​​thức cơ bản về bộ lọc ở đây và tôi phát hiện ra rằng tôi cần tạo một bộ lọc tùy chỉnh sẽ nằm đầu tiên trong chuỗi bộ lọc và sẽ có một thử nghiệm để nắm bắt tất cả các ngoại lệ thời gian chạy có thể xảy ra ở đó. Sau đó, tôi cần tạo json theo cách thủ công và đưa nó vào phản hồi.

Đây là bộ lọc tùy chỉnh của tôi:

public class ExceptionHandlerFilter extends OncePerRequestFilter {

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } catch (RuntimeException e) {

            // custom error response class used across my project
            ErrorResponse errorResponse = new ErrorResponse(e);

            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            response.getWriter().write(convertObjectToJson(errorResponse));
    }
}

    public String convertObjectToJson(Object object) throws JsonProcessingException {
        if (object == null) {
            return null;
        }
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(object);
    }
}

Và sau đó tôi đã thêm nó vào web.xml trước CorsFilter. Và nó hoạt động!

<filter> 
    <filter-name>exceptionHandlerFilter</filter-name> 
    <filter-class>xx.xxxxxx.xxxxx.api.controllers.filters.ExceptionHandlerFilter</filter-class> 
</filter> 


<filter-mapping> 
    <filter-name>exceptionHandlerFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<filter> 
    <filter-name>CorsFilter</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 

<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Bạn có thể đăng Lớp ErrorResponse của mình không?
Shiva kumar

@Shivakumar Lớp ErrorResponse có lẽ là một DTO đơn giản với các thuộc tính mã / thông báo đơn giản.
ratijas

18

Tôi muốn cung cấp giải pháp dựa trên câu trả lời của @kopelitsa . Sự khác biệt chính là:

  1. Sử dụng lại việc xử lý ngoại lệ bộ điều khiển bằng cách sử dụng HandlerExceptionResolver.
  2. Sử dụng cấu hình Java trên cấu hình XML

Trước tiên, bạn cần đảm bảo rằng bạn có một lớp xử lý các ngoại lệ xảy ra trong RestController / Controller thông thường (một lớp được chú thích bằng @RestControllerAdvicehoặc @ControllerAdvicevà (các) phương thức được chú thích bằng @ExceptionHandler). Điều này xử lý các ngoại lệ của bạn xảy ra trong bộ điều khiển. Đây là một ví dụ sử dụng RestControllerAdvice:

@RestControllerAdvice
public class ExceptionTranslator {

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorDTO processRuntimeException(RuntimeException e) {
        return createErrorDTO(HttpStatus.INTERNAL_SERVER_ERROR, "An internal server error occurred.", e);
    }

    private ErrorDTO createErrorDTO(HttpStatus status, String message, Exception e) {
        (...)
    }
}

Để sử dụng lại hành vi này trong chuỗi bộ lọc Spring Security, bạn cần xác định một Bộ lọc và nối nó vào cấu hình bảo mật của bạn. Bộ lọc cần chuyển hướng ngoại lệ đến xử lý ngoại lệ đã xác định ở trên. Đây là một ví dụ:

@Component
public class FilterChainExceptionHandler extends OncePerRequestFilter {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            log.error("Spring Security Filter Chain Exception:", e);
            resolver.resolveException(request, response, null, e);
        }
    }
}

Bộ lọc đã tạo sau đó cần được thêm vào SecurityConfiguration. Bạn cần kết nối nó vào chuỗi từ rất sớm, vì tất cả các ngoại lệ của bộ lọc trước đó sẽ không bị bắt. Trong trường hợp của tôi, nó là hợp lý để thêm nó trước LogoutFilter. Xem chuỗi bộ lọc mặc định và thứ tự của nó trong tài liệu chính thức . Đây là một ví dụ:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private FilterChainExceptionHandler filterChainExceptionHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
            (...)
    }

}

17

Tôi tự mình gặp sự cố này và tôi đã thực hiện các bước bên dưới để sử dụng lại ExceptionControllercái được chú thích của tôi @ControllerAdviseđể Exceptionsném vào Bộ lọc đã đăng ký.

Rõ ràng là có nhiều cách để xử lý ngoại lệ nhưng, trong trường hợp của tôi, tôi muốn ngoại lệ được xử lý bởi ExceptionControllervì tôi cứng đầu và cũng vì tôi không muốn sao chép / dán cùng một mã (tức là tôi có một số xử lý / ghi nhật ký. mã trong ExceptionController). Tôi muốn trả lại JSONphản hồi đẹp giống như phần còn lại của các trường hợp ngoại lệ không phải từ Bộ lọc.

{
  "status": 400,
  "message": "some exception thrown when executing the request"
}

Dù sao, tôi đã quản lý để sử dụng ExceptionHandlervà tôi phải làm thêm một chút như hình dưới đây trong các bước:

Các bước


  1. Bạn có một bộ lọc tùy chỉnh có thể có hoặc không có ngoại lệ
  2. Bạn có một bộ điều khiển Spring xử lý các ngoại lệ bằng cách sử dụng @ControllerAdviseMyExceptionController tức là

Mã mẫu

//sample Filter, to be added in web.xml
public MyFilterThatThrowException implements Filter {
   //Spring Controller annotated with @ControllerAdvise which has handlers
   //for exceptions
   private MyExceptionController myExceptionController; 

   @Override
   public void destroy() {
        // TODO Auto-generated method stub
   }

   @Override
   public void init(FilterConfig arg0) throws ServletException {
       //Manually get an instance of MyExceptionController
       ApplicationContext ctx = WebApplicationContextUtils
                  .getRequiredWebApplicationContext(arg0.getServletContext());

       //MyExceptionHanlder is now accessible because I loaded it manually
       this.myExceptionController = ctx.getBean(MyExceptionController.class); 
   }

   @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        try {
           //code that throws exception
        } catch(Exception ex) {
          //MyObject is whatever the output of the below method
          MyObject errorDTO = myExceptionController.handleMyException(req, ex); 

          //set the response object
          res.setStatus(errorDTO .getStatus());
          res.setContentType("application/json");

          //pass down the actual obj that exception handler normally send
          ObjectMapper mapper = new ObjectMapper();
          PrintWriter out = res.getWriter(); 
          out.print(mapper.writeValueAsString(errorDTO ));
          out.flush();

          return; 
        }

        //proceed normally otherwise
        chain.doFilter(request, response); 
     }
}

Và bây giờ là Bộ điều khiển mùa xuân mẫu xử lý Exceptiontrong các trường hợp bình thường (tức là các ngoại lệ thường không được đưa vào cấp Bộ lọc, cái mà chúng tôi muốn sử dụng cho các ngoại lệ được đưa vào Bộ lọc)

//sample SpringController 
@ControllerAdvice
public class ExceptionController extends ResponseEntityExceptionHandler {

    //sample handler
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(SQLException.class)
    public @ResponseBody MyObject handleSQLException(HttpServletRequest request,
            Exception ex){
        ErrorDTO response = new ErrorDTO (400, "some exception thrown when "
                + "executing the request."); 
        return response;
    }
    //other handlers
}

Chia sẻ giải pháp với những người muốn sử dụng ExceptionControllerđể Exceptionsném trong Bộ lọc.


10
Vâng, bạn được hoan nghênh chia sẻ giải pháp của riêng bạn mà nghe có vẻ là cách để làm điều đó :)
Raf

1
Nếu bạn muốn tránh để Bộ điều khiển có dây vào bộ lọc của mình (mà tôi cho là @ Bato-BairTsyrenov đang đề cập đến), bạn có thể dễ dàng trích xuất logic nơi bạn tạo ErrorDTO thành @Componentlớp riêng của nó và sử dụng nó trong Bộ lọc và trong Bộ điều khiển.
Rüdiger Schulz

1
Tôi không hoàn toàn đồng ý với bạn, vì điều này không được rõ ràng lắm khi đưa một bộ điều khiển cụ thể vào bộ lọc của bạn.
psv

Như đã đề cập trong answerđây là một trong những cách! Tôi đã không tuyên bố rằng đó là cách tốt nhất. Cảm ơn bạn đã chia sẻ mối quan tâm của mình @psv Tôi chắc chắn rằng cộng đồng sẽ đánh giá cao giải pháp mà bạn nghĩ đến :)
Raf

12

Vì vậy, đây là những gì tôi đã làm dựa trên sự kết hợp của các câu trả lời ở trên ... Chúng tôi đã có GlobalExceptionHandlerchú thích @ControllerAdvicevà tôi cũng muốn tìm cách sử dụng lại mã đó để xử lý các ngoại lệ đến từ các bộ lọc.

Giải pháp đơn giản nhất mà tôi có thể tìm thấy là để bộ xử lý ngoại lệ một mình và triển khai bộ điều khiển lỗi như sau:

@Controller
public class ErrorControllerImpl implements ErrorController {
  @RequestMapping("/error")
  public void handleError(HttpServletRequest request) throws Throwable {
    if (request.getAttribute("javax.servlet.error.exception") != null) {
      throw (Throwable) request.getAttribute("javax.servlet.error.exception");
    }
  }
}

Vì vậy, bất kỳ lỗi nào gây ra bởi ngoại lệ trước tiên sẽ chuyển qua ErrorControllervà được chuyển hướng đến trình xử lý ngoại lệ bằng cách ném lại chúng từ bên trong một @Controllerngữ cảnh, trong khi bất kỳ lỗi nào khác (không do ngoại lệ trực tiếp gây ra) sẽ đi qua ErrorControllermà không sửa đổi.

Bất kỳ lý do tại sao đây thực sự là một ý tưởng tồi?


1
Cảm ơn bây giờ đã thử nghiệm giải pháp này nhưng trong trường hợp của tôi hoạt động hoàn hảo.
Maciej

sạch sẽ và đơn giản một bổ sung cho khởi động mùa xuân 2.0+ bạn nên thêm @Override public String getErrorPath() { return null; }
FMA

bạn có thể sử dụng javax.servlet.RequestDispatcher.ERROR_EXCEPTION thay vì "javax.servlet.error.exception"
Marx

9

Nếu bạn muốn một cách chung chung, bạn có thể xác định một trang lỗi trong web.xml:

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/500</location>
</error-page>

Và thêm ánh xạ trong Spring MVC:

@Controller
public class ErrorController {

    @RequestMapping(value="/500")
    public @ResponseBody String handleException(HttpServletRequest req) {
        // you can get the exception thrown
        Throwable t = (Throwable)req.getAttribute("javax.servlet.error.exception");

        // customize response to what you want
        return "Internal server error.";
    }
}

Nhưng trong phần còn lại, chuyển hướng theo vị trí không phải là một giải pháp tốt.
jmattheis

@jmattheis Ở trên không phải là chuyển hướng.
holmis83

Đúng vậy, tôi đã thấy vị trí và nghĩ rằng nó có gì đó liên quan đến vị trí http. Sau đó, đây là những gì tôi cần (:
jmattheis

Bạn có thể thêm cấu hình Java tương đương với web.xml, nếu có?
k-den

1
@ k-den Không có cấu hình Java tương đương trong thông số kỹ thuật hiện tại mà tôi nghĩ, nhưng bạn có thể kết hợp cấu hình web.xml và Java.
holmis83

5

Đây là giải pháp của tôi bằng cách ghi đè Spring Boot / trình xử lý lỗi mặc định

package com.mypackage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * This controller is vital in order to handle exceptions thrown in Filters.
 */
@RestController
@RequestMapping("/error")
public class ErrorController implements org.springframework.boot.autoconfigure.web.ErrorController {

    private final static Logger LOGGER = LoggerFactory.getLogger(ErrorController.class);

    private final ErrorAttributes errorAttributes;

    @Autowired
    public ErrorController(ErrorAttributes errorAttributes) {
        Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest aRequest, HttpServletResponse response) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest);
        Map<String, Object> result =     this.errorAttributes.getErrorAttributes(requestAttributes, false);

        Throwable error = this.errorAttributes.getError(requestAttributes);

        ResponseStatus annotation =     AnnotationUtils.getAnnotation(error.getClass(), ResponseStatus.class);
        HttpStatus statusCode = annotation != null ? annotation.value() : HttpStatus.INTERNAL_SERVER_ERROR;

        result.put("status", statusCode.value());
        result.put("error", statusCode.getReasonPhrase());

        LOGGER.error(result.toString());
        return new ResponseEntity<>(result, statusCode) ;
    }

}

nó có ảnh hưởng đến bất kỳ cấu hình tự động nào không?
Samet Baskıcı

Lưu ý rằng HandlerExceptionResolver không nhất thiết phải xử lý ngoại lệ. Vì vậy, nó có thể rơi xuống dưới dạng HTTP 200. Sử dụng response.setStatus (..) trước khi gọi nó có vẻ an toàn hơn.
ThomasRS

5

Chỉ để bổ sung cho các câu trả lời tốt khác được cung cấp, vì gần đây tôi cũng muốn có một thành phần xử lý lỗi / ngoại lệ duy nhất trong ứng dụng SpringBoot đơn giản có chứa các bộ lọc có thể tạo ra các ngoại lệ, với các ngoại lệ khác có thể được ném từ các phương thức bộ điều khiển.

May mắn thay, có vẻ như không có gì ngăn cản bạn kết hợp lời khuyên của bộ điều khiển với ghi đè trình xử lý lỗi mặc định của Spring để cung cấp tải trọng phản hồi nhất quán, cho phép bạn chia sẻ logic, kiểm tra các ngoại lệ từ bộ lọc, bẫy các ngoại lệ do dịch vụ cụ thể đưa ra, v.v.

Ví dụ


@ControllerAdvice
@RestController
public class GlobalErrorHandler implements ErrorController {

  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ExceptionHandler(ValidationException.class)
  public Error handleValidationException(
      final ValidationException validationException) {
    return new Error("400", "Incorrect params"); // whatever
  }

  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  @ExceptionHandler(Exception.class)
  public Error handleUnknownException(final Exception exception) {
    return new Error("500", "Unexpected error processing request");
  }

  @RequestMapping("/error")
  public ResponseEntity handleError(final HttpServletRequest request,
      final HttpServletResponse response) {

    Object exception = request.getAttribute("javax.servlet.error.exception");

    // TODO: Logic to inspect exception thrown from Filters...
    return ResponseEntity.badRequest().body(new Error(/* whatever */));
  }

  @Override
  public String getErrorPath() {
    return "/error";
  }

}

3

Khi bạn muốn kiểm tra trạng thái của ứng dụng và trong trường hợp có sự cố, trả về lỗi HTTP, tôi sẽ đề xuất một bộ lọc. Bộ lọc bên dưới xử lý tất cả các yêu cầu HTTP. Giải pháp ngắn nhất trong Spring Boot với bộ lọc javax.

Trong việc thực hiện có thể được các điều kiện khác nhau. Trong trường hợp của tôi, thử nghiệm ApplicationManager nếu ứng dụng đã sẵn sàng.

import ...ApplicationManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class SystemIsReadyFilter implements Filter {

    @Autowired
    private ApplicationManager applicationManager;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (!applicationManager.isApplicationReady()) {
            ((HttpServletResponse) response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "The service is booting.");
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {}
}

2

Sau khi đọc qua các phương pháp khác nhau được đề xuất trong các câu trả lời ở trên, tôi quyết định xử lý các ngoại lệ xác thực bằng cách sử dụng bộ lọc tùy chỉnh. Tôi có thể xử lý trạng thái phản hồi và mã bằng cách sử dụng lớp phản hồi lỗi bằng phương pháp sau.

Tôi đã tạo một bộ lọc tùy chỉnh và sửa đổi cấu hình bảo mật của mình bằng cách sử dụng phương thức addFilterAfter và thêm vào sau lớp CorsFilter.

@Component
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    //Cast the servlet request and response to HttpServletRequest and HttpServletResponse
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;

    // Grab the exception from the request attribute
    Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
    //Set response content type to application/json
    httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);

    //check if exception is not null and determine the instance of the exception to further manipulate the status codes and messages of your exception
    if(exception!=null && exception instanceof AuthorizationParameterNotFoundException){
        ErrorResponse errorResponse = new ErrorResponse(exception.getMessage(),"Authetication Failed!");
        httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write(convertObjectToJson(errorResponse));
        writer.flush();
        return;
    }
    // If exception instance cannot be determined, then throw a nice exception and desired response code.
    else if(exception!=null){
            ErrorResponse errorResponse = new ErrorResponse(exception.getMessage(),"Authetication Failed!");
            PrintWriter writer = httpServletResponse.getWriter();
            writer.write(convertObjectToJson(errorResponse));
            writer.flush();
            return;
        }
        else {
        // proceed with the initial request if no exception is thrown.
            chain.doFilter(httpServletRequest,httpServletResponse);
        }
    }

public String convertObjectToJson(Object object) throws JsonProcessingException {
    if (object == null) {
        return null;
    }
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(object);
}
}

Lớp SecurityConfig

    @Configuration
    public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    AuthFilter authenticationFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAfter(authenticationFilter, CorsFilter.class).csrf().disable()
                .cors(); //........
        return http;
     }
   }

Lớp ErrorResponse

public class ErrorResponse  {
private final String message;
private final String description;

public ErrorResponse(String description, String message) {
    this.message = message;
    this.description = description;
}

public String getMessage() {
    return message;
}

public String getDescription() {
    return description;
}}

0

Bạn có thể sử dụng phương pháp sau bên trong khối bắt:

response.sendError(HttpStatus.UNAUTHORIZED.value(), "Invalid token")

Lưu ý rằng bạn có thể sử dụng bất kỳ mã HttpStatus nào và thông báo tùy chỉnh.


-1

Thật kỳ lạ vì @ControllerAdvice sẽ hoạt động, bạn có đang bắt đúng Exception không?

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = DataAccessException.class)
    public String defaultErrorHandler(HttpServletResponse response, DataAccessException e) throws Exception {
       response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
       //Json return
    }
}

Cũng cố gắng bắt ngoại lệ này trong CorsFilter và gửi lỗi 500, giống như thế này

@ExceptionHandler(DataAccessException.class)
@ResponseBody
public String handleDataException(DataAccessException ex, HttpServletResponse response) {
    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    //Json return
}

Xử lý ngoại lệ trong CorsFilter hoạt động, nhưng nó không được sạch sẽ cho lắm. Trong thực tế những gì tôi thực sự cần là xử lý các ngoại lệ cho tất cả các bộ lọc
kopelitsa

35
Ngoại lệ ném từ Filtercó thể không được bắt bởi @ControllerAdvicevì có thể không đạt DispatcherServlet.
Thanh Nguyen Van

-1

Bạn không cần tạo Bộ lọc tùy chỉnh cho việc này. Chúng tôi đã giải quyết vấn đề này bằng cách tạo các ngoại lệ tùy chỉnh mở rộng ServletException (được ném từ phương thức doFilter, được hiển thị trong khai báo). Các lỗi này sau đó sẽ được xử lý bởi trình xử lý lỗi toàn cầu của chúng tôi.

chỉnh sửa: ngữ pháp


Bạn có phiền chia sẻ đoạn mã của trình xử lý lỗi toàn cầu không?
Neeraj Vernekar

nó không hiệu quả với tôi. Tôi đã tạo ngoại lệ tùy chỉnh, mở rộng ServletException, thêm hỗ trợ cho ngoại lệ này trong ExceptionHandler, nhưng nó đã không bị chặn ở đó.
Marx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.