वसंत में फिल्टर में फेंके गए अपवादों को कैसे प्रबंधित करें?


109

मैं 5xx त्रुटि कोड को प्रबंधित करने के लिए सामान्य तरीके का उपयोग करना चाहता हूं, चलो विशेष रूप से इस मामले को कहते हैं जब डीबी मेरे पूरे वसंत एप्लिकेशन में नीचे है। मैं एक ढेर ट्रेस के बजाय एक बहुत त्रुटि त्रुटि चाहता हूँ।

नियंत्रकों के लिए मेरे पास @ControllerAdviceअलग-अलग अपवादों के लिए एक वर्ग है और यह इस मामले को भी पकड़ रहा है कि डीबी अनुरोध के बीच में रोक रहा है। लेकिन यह सब नहीं है। मैं भी एक प्रचलित CorsFilterप्रचलित है OncePerRequestFilterऔर वहाँ जब मैं कॉल doFilterमैं CannotGetJdbcConnectionExceptionऔर यह हो जाएगा द्वारा प्रबंधित नहीं किया जाएगा @ControllerAdvice। मैंने कई चीजें ऑनलाइन पढ़ीं जो केवल मुझे और भ्रमित करती थीं।

इसलिए मेरे पास बहुत सारे प्रश्न हैं:

  • क्या मुझे एक कस्टम फ़िल्टर लागू करने की आवश्यकता है? मैंने पाया ExceptionTranslationFilterलेकिन यह केवल संभालती है AuthenticationExceptionया AccessDeniedException
  • मैंने अपने स्वयं के कार्यान्वयन के बारे में सोचा HandlerExceptionResolver, लेकिन इससे मुझे संदेह हुआ, मेरे पास प्रबंधन करने के लिए कोई कस्टम अपवाद नहीं है, इससे अधिक स्पष्ट तरीका होना चाहिए। मैंने एक कोशिश / कैच जोड़ने और एक कार्यान्वयन को कॉल करने की कोशिश की HandlerExceptionResolver(काफी अच्छा होना चाहिए, मेरा अपवाद कुछ खास नहीं है) लेकिन यह प्रतिक्रिया में कुछ भी वापस नहीं कर रहा है, मुझे 200 का दर्जा और एक खाली शरीर मिला है।

क्या इससे निपटने का कोई अच्छा तरीका है? धन्यवाद


हम स्प्रिंग बूट के BasicErrorController को ओवरराइड कर सकते हैं। मैंने इसके बारे में यहाँ ब्लॉग किया है: naturalprogrammer.com/blog/1685463/…
संजय

जवाबों:


86

तो यही वह है जो मैंने किया:

मैंने यहां फ़िल्टर के बारे में मूल बातें पढ़ीं और मुझे लगा कि मुझे एक कस्टम फ़िल्टर बनाने की ज़रूरत है जो पहले फ़िल्टर श्रृंखला में होगा और सभी रनटाइम अपवादों को पकड़ने के लिए एक कोशिश पकड़ होगी जो वहां हो सकती है। फिर मुझे मैन्युअल रूप से जसन बनाने और प्रतिक्रिया में डालने की आवश्यकता है।

तो यहाँ मेरा कस्टम फ़िल्टर है:

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);
    }
}

और फिर मैंने इसे web.xml में वेब से पहले जोड़ा CorsFilter। और यह काम करता है!

<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>

क्या आप अपना ErrorResponse Class पोस्ट कर सकते हैं?
शिव कुमार

1
@ शिवकुमार ErrorResponse वर्ग शायद सरल कोड / संदेश गुणों के साथ एक सरल डीटीओ है।
रतिज

23

मैं @kopelitsa के उत्तर के आधार पर एक समाधान प्रदान करना चाहता था । मुख्य अंतर:

  1. नियंत्रक अपवाद हैंडलिंग का उपयोग करके पुन: उपयोग करना HandlerExceptionResolver
  2. XML config पर Java config का उपयोग करना

सबसे पहले, आपको यह सुनिश्चित करने की आवश्यकता है, कि आपके पास एक वर्ग है जो एक नियमित रेस्टकंट्रोलर / कंट्रोलर में होने वाले अपवादों को संभालता है (एक वर्ग जिसे एनोटेट किया गया है @RestControllerAdviceया @ControllerAdviceविधि के साथ एनोटेट किया गया है @ExceptionHandler)। यह एक नियंत्रक में होने वाले आपके अपवादों को संभालता है। यहाँ 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) {
        (...)
    }
}

स्प्रिंग सुरक्षा फ़िल्टर श्रृंखला में इस व्यवहार का पुन: उपयोग करने के लिए, आपको एक फ़िल्टर परिभाषित करने और इसे अपने सुरक्षा कॉन्फ़िगरेशन में हुक करने की आवश्यकता है। फ़िल्टर को उपरोक्त परिभाषित अपवाद हैंडलिंग के अपवाद को पुनर्निर्देशित करना होगा। यहाँ एक उदाहरण है:

@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);
        }
    }
}

तब बनाया गया फ़िल्टर SecurityConfiguration में जोड़ा जाना चाहिए। आपको इसे बहुत पहले श्रृंखला में हुक करने की आवश्यकता है, क्योंकि पूर्ववर्ती फ़िल्टर के अपवाद नहीं पकड़े जाएंगे। मेरे मामले में, इससे पहले इसे जोड़ना उचित था LogoutFilterआधिकारिक डॉक्स में डिफ़ॉल्ट फ़िल्टर श्रृंखला और उसका क्रम देखें । यहाँ एक उदाहरण है:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private FilterChainExceptionHandler filterChainExceptionHandler;

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

}

19

मैं खुद इस मुद्दे पर आता हूं और मैंने एक पंजीकृत फ़िल्टर में फेंकने के लिए ExceptionControllerएनोटेट के साथ मेरे पुन: उपयोग के लिए नीचे दिए गए चरणों का प्रदर्शन किया ।@ControllerAdviseExceptions

स्पष्ट रूप से अपवाद को संभालने के कई तरीके हैं लेकिन, मेरे मामले में, मैं चाहता था कि अपवाद मेरे द्वारा संभाला जाए ExceptionControllerक्योंकि मैं जिद्दी हूं और इसलिए भी कि मैं एक ही कोड को कॉपी / पेस्ट नहीं करना चाहता (अर्थात मेरे पास कुछ प्रोसेसिंग / लॉगिंग है कोड में ExceptionController)। मैं JSONएक फिल्टर से नहीं फेंक दिए गए बाकी अपवादों की तरह ही सुंदर प्रतिक्रिया देना चाहता हूं ।

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

वैसे भी, मैं अपना उपयोग करने में कामयाब रहा ExceptionHandlerऔर मुझे कुछ अतिरिक्त करना पड़ा जैसा कि नीचे चरणों में दिखाया गया है:

कदम


  1. आपके पास एक कस्टम फ़िल्टर है जो एक अपवाद को फेंक या नहीं कर सकता है
  2. आपके पास एक स्प्रिंग कंट्रोलर है जो @ControllerAdviseMyExceptionController का उपयोग करके अपवादों को संभालता है

नमूना कोड

//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); 
     }
}

और अब नमूना स्प्रिंग नियंत्रक जो Exceptionसामान्य मामलों में संभालता है (यानी अपवाद जो आमतौर पर फ़िल्टर स्तर में नहीं फेंके जाते हैं, जिसे हम फ़िल्टर में फेंके गए अपवादों के लिए उपयोग करना चाहते हैं)

//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
}

जो लोग उपयोग करना चाहते हैं के साथ समाधान साझा करना ExceptionControllerके लिए Exceptionsएक फिल्टर में फेंक दिया।


10
ठीक है, आप अपने स्वयं के समाधान को साझा करने के लिए स्वागत करते हैं जो इसे करने का तरीका लगता है :)
रफ

1
यदि आप एक नियंत्रक को अपने फ़िल्टर में वायर्ड होने से बचना चाहते हैं (जो कि @ Bato-BairTsyrenov है जो मैं मान रहा हूं), तो आप आसानी से उस तर्क को निकाल सकते हैं, जहाँ आप ErrorDTO को अपनी @Componentकक्षा में बनाते हैं और फ़िल्टर में उसका उपयोग करते हैं नियंत्रक।
राउडीगर शुल्ज

1
मैं आपके साथ पूरी तरह से सहमत नहीं हूं, क्योंकि यह आपके फिल्टर में एक विशिष्ट नियंत्रक को इंजेक्ट करने के लिए बहुत साफ नहीं है।
psv

जैसा कि इसमें बताया गया answerहै, एक तरीका है! मैंने यह दावा नहीं किया है कि यह सबसे अच्छा तरीका है। अपनी चिंता को साझा करने के लिए धन्यवाद @psv मुझे यकीन है कि समुदाय आपके मन में समाधान की सराहना करेगा :)
रफ

12

तो, यहाँ मैंने उपरोक्त उत्तरों के समामेलन के आधार पर क्या किया है ... हमने पहले से ही एक GlobalExceptionHandlerएनोटेट किया हुआ था @ControllerAdviceऔर मैं फ़िल्टर से आए अपवादों को संभालने के लिए उस कोड को फिर से उपयोग करने का एक तरीका खोजना चाहता था।

सबसे सरल समाधान जो मुझे मिल सकता है, वह अपवाद हैंडलर को अकेला छोड़ना, और एक त्रुटि नियंत्रक को निम्नानुसार लागू करना था:

@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");
    }
  }
}

इसलिए, अपवादों के कारण होने वाली कोई भी त्रुटि पहले से होकर गुज़रती है ErrorControllerऔर एक @Controllerसंदर्भ के भीतर से उन्हें वापस लाकर अपवाद हैंडलर को फिर से निर्देशित कर दी जाती है , जबकि कोई भी अन्य त्रुटि (अपवाद के कारण सीधे नहीं) ErrorControllerबिना संशोधन के पास हो जाती है ।

किसी भी कारण से यह वास्तव में एक बुरा विचार है?


1
धन्यवाद अब इस समाधान का परीक्षण, लेकिन मेरे मामले में सही काम करते हैं।
मैकीज

स्प्रिंग बूट 2.0+ के लिए स्वच्छ और सरल एक जोड़ आपको जोड़ना चाहिए @Override public String getErrorPath() { return null; }
Fma

आप "javax.servlet.error.exception" के बजाय javax.servlet.RequestDispatcher.ERROR_EXCEPTION का उपयोग कर सकते हैं
मार्क्स

9

यदि आप एक सामान्य तरीका चाहते हैं, तो आप web.xml में एक त्रुटि पृष्ठ परिभाषित कर सकते हैं:

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

और स्प्रिंग 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.";
    }
}

लेकिन बाकी आपी में लोकेशन के साथ पुनर्निर्देशन एक अच्छा उपाय नहीं है।
जम्मेटीस

@jmattheis उपरोक्त कोई अनुप्रेषित नहीं है।
होल्मिस 83

सच है, मैंने स्थान देखा और सोचा कि यह http स्थान के साथ कुछ है। फिर मुझे यही चाहिए (:
jmattheis

क्या आप जावा कॉन्फ़िगरेशन को web.xml के बराबर जोड़ सकते हैं, यदि कोई मौजूद है?
k-den

1
@ k-den वर्तमान में मेरे विचार से कोई जावा कॉन्फिगरेशन समतुल्य नहीं है, लेकिन आप web.xml और Java कॉन्फिगरेशन को मिला सकते हैं।
holmis83

5

डिफ़ॉल्ट स्प्रिंग बूट / त्रुटि हैंडलर को ओवरराइड करके यह मेरा समाधान है

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) ;
    }

}

क्या यह किसी भी ऑटो कॉन्फ़िगरेशन को प्रभावित करता है?
समेट बसकिस

ध्यान दें कि HandlerExceptionResolver आवश्यक रूप से अपवाद को संभालता नहीं है। तो यह HTTP 200 के माध्यम से गिर सकता है। कॉल करने से पहले response.setStatus (..) का उपयोग करना सुरक्षित लगता है।
थॉमसआर

5

बस प्रदान किए गए अन्य ठीक जवाबों को पूरक करने के लिए, जैसा कि मैंने हाल ही में एक साधारण स्प्रिंगबूट ऐप में एक एकल त्रुटि / अपवाद हैंडलिंग घटक को फ़िल्टर किया था, जो अपवादों को फेंक सकता है, अन्य अपवादों के साथ संभवतः नियंत्रक विधियों से फेंका गया है।

सौभाग्य से, ऐसा लगता है कि आपको लगातार प्रतिक्रिया पेलोड प्रदान करने के लिए स्प्रिंग की डिफ़ॉल्ट त्रुटि हैंडलर के ओवरराइड के साथ अपने नियंत्रक सलाह को संयोजित करने से रोकने के लिए कुछ भी नहीं है, आपको तर्क साझा करने, फिल्टर से अपवादों का निरीक्षण करने, विशिष्ट सेवा-फेंकने वाले अपवादों को पकड़ने आदि की अनुमति देता है।

उदाहरण के लिए


@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

जब आप आवेदन की स्थिति का परीक्षण करना चाहते हैं और HTTP त्रुटि की स्थिति में मैं एक फ़िल्टर का सुझाव दूंगा। नीचे दिया गया फ़िल्टर सभी HTTP अनुरोधों को संभालता है। एक जावा फिल्टर के साथ स्प्रिंग बूट में सबसे छोटा समाधान।

कार्यान्वयन में विभिन्न शर्तें हो सकती हैं। यदि आवेदन तैयार है, तो मेरे मामले में एप्लिकेशन प्रबंधक परीक्षण।

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

उपरोक्त उत्तरों में सुझाए गए विभिन्न तरीकों के माध्यम से पढ़ने के बाद, मैंने कस्टम फ़िल्टर का उपयोग करके प्रमाणीकरण अपवादों को संभालने का निर्णय लिया। मैं निम्न विधि का उपयोग करके त्रुटि प्रतिक्रिया वर्ग का उपयोग करके प्रतिक्रिया की स्थिति और कोड को संभालने में सक्षम था।

मैंने एक कस्टम फ़िल्टर बनाया और AddFilterAfter विधि का उपयोग करके अपने सुरक्षा कॉन्फ़िगरेशन को संशोधित किया और 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);
}
}

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;
     }
   }

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

आप कैच ब्लॉक के अंदर निम्न विधि का उपयोग कर सकते हैं:

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

ध्यान दें कि आप किसी भी HttpStatus कोड और एक कस्टम संदेश का उपयोग कर सकते हैं।


-1

यह अजीब है क्योंकि @ControllerAdvice को काम करना चाहिए, क्या आप सही अपवाद को पकड़ रहे हैं?

@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
    }
}

CorsFilter में इस अपवाद को पकड़ने की कोशिश करें और 500 त्रुटि, कुछ इस तरह से भेजें

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

CorsFilter कार्यों में अपवाद को संभालना, लेकिन यह बहुत साफ नहीं है। वास्तव में मुझे क्या जरूरत है सभी फिल्टर के लिए अपवाद को संभाल रहा है
kopelitsa

35
से पहुंच अपवाद को Filterपकड़ नहीं सकता है @ControllerAdviceक्योंकि पहुंच नहीं सकता है DispatcherServlet
थान गुयेन वान

-1

इसके लिए आपको एक कस्टम फ़िल्टर बनाने की आवश्यकता नहीं है। हमने इसे कस्टम अपवाद बनाकर हल किया है जो ServletException (जो doFilter विधि से फेंका गया है, घोषणा में दिखाया गया है) का विस्तार करता है। ये तब पकड़े जाते हैं और हमारे वैश्विक त्रुटि हैंडलर द्वारा नियंत्रित किए जाते हैं।

संपादित करें: व्याकरण


क्या आप अपने वैश्विक त्रुटि हैंडलर का एक कोड स्निपेट साझा करना चाहेंगे?
नीरज वर्नेकर

यह मेरे लिए काम नहीं करता है। मैंने कस्टम अपवाद बनाया, जो ServletException का विस्तार करता है, अपवाद अपवाद में इस अपवाद के लिए समर्थन जोड़ा, लेकिन यह वहाँ अवरोधन नहीं है।
मार्क्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.