2014-06-30 11 views
9

(समाधान प्रश्न के अंत में तैनात)विधिपत्र विश्व स्तर पर का उपयोग कर स्प्रिंग MVC जावा आधारित एनोटेशन का उपयोग कर

मैं एक स्प्रिंग 4 MVC एप्लिकेशन बनाने रहा कॉन्फ़िगर किया गया 404 अपवाद संभाल। और यह जावा एनोटेशन का उपयोग कर पूरी तरह से कॉन्फ़िगर किया गया है। web.xml नहीं है। अनुप्रयोग, AbstractAnnotationConfigDispatcherServletInitializer के कहने और WebMvcConfigurerAdapter इसलिए की तरह उपयोग करके कॉन्फ़िगर किया गया है

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = {"com.example.*"}) 
@EnableTransactionManagement 
@PropertySource("/WEB-INF/properties/application.properties") 
public class WebAppConfig extends WebMvcConfigurerAdapter { 
... 
} 

और

public class WebAppInitializer extends 
    AbstractAnnotationConfigDispatcherServletInitializer { 
... 
} 

मैं अब 404 पृष्ठों यानी HttpStatus.NOT_FOUND एक वैश्विक/सभी अपवाद संचालक को जोड़ने के लिए कोशिश कर रहा हूँ, लेकिन कोई सफलता। मैंने कोशिश की कुछ तरीकों से नीचे दिए गए हैं।

import org.springframework.http.HttpStatus; 
import org.springframework.web.bind.annotation.ControllerAdvice; 
import org.springframework.web.bind.annotation.ExceptionHandler; 
import org.springframework.web.bind.annotation.ResponseStatus; 
import org.springframework.web.servlet.ModelAndView; 
import org.springframework.web.servlet.NoHandlerFoundException; 
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; 

@ControllerAdvice 
public class GlobalExceptionHandlerController { 

    @ExceptionHandler 
    @ResponseStatus(HttpStatus.NOT_FOUND) 
    public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) { 
      ModelAndView mav = new ModelAndView(); 
      return mav; 
    } 

    @ExceptionHandler 
    @ResponseStatus(HttpStatus.NOT_FOUND) 
    public ModelAndView handleExceptiond (NoHandlerFoundException ex) { 
      ModelAndView mav = new ModelAndView(); 
      return mav; 
    } 

    @ResponseStatus(HttpStatus.NOT_FOUND) 
    @ExceptionHandler(NoHandlerFoundException.class) 
    public void handleConflict() { 

    } 

    @ResponseStatus(HttpStatus.NOT_FOUND) 
    @ExceptionHandler(NoSuchRequestHandlingMethodException.class) 
    public void handlesdConflict() { 
    } 

} 

इनमें से कोई भी विधि निष्पादित नहीं होती है। मैं इसे संभालने के तरीके के रूप में एक नुकसान में हूँ। मैं web.xml becasue का उपयोग नहीं करना चाहता हूं तो मुझे इसके लिए केवल एक बनाना होगा।

समाधान मैं क्या mentioned here @Sotirios किया था। यहां मेरा भाग WebAppInitializer कोड है जो प्रेषक को ठीक से सेट करेगा।

public class WebAppInitializer extends 
     AbstractAnnotationConfigDispatcherServletInitializer { 

    ... 

    @Override 
    protected void registerDispatcherServlet(ServletContext servletContext) { 

     String servletName = super.getServletName(); 
     Assert.hasLength(servletName, "getServletName() may not return empty or null"); 

     WebApplicationContext servletAppContext = super.createServletApplicationContext(); 
     Assert.notNull(servletAppContext, 
       "createServletApplicationContext() did not return an application " + 
       "context for servlet [" + servletName + "]"); 

     DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext); 

     //>>> START: My custom code, rest is exqact copy of the super class 
     dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); 
     //>>> END 

     ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet); 
     Assert.notNull(registration, 
       "Failed to register servlet with name '" + servletName + "'." + 
       "Check if there is another servlet registered under the same name."); 

     registration.setLoadOnStartup(1); 
     registration.addMapping(getServletMappings()); 
     registration.setAsyncSupported(isAsyncSupported()); 

     Filter[] filters = getServletFilters(); 
     if (!ObjectUtils.isEmpty(filters)) { 
      for (Filter filter : filters) { 
       super.registerServletFilter(servletContext, filter); 
      } 
     } 

     super.customizeRegistration(registration); 
    } 

    ... 
} 

हालांकि मैं इस समाधान के साथ विशेष रूप से खुश क्योंकि मेरी केवल कस्टम कोड 1 लाइन & बाकी सीधे सुपर वर्ग से नकल कर रहा है नहीं कर रहा हूँ। मेरी इच्छा है कि ऐसा करने के लिए एक अच्छा तरीका था।

+0

मैं नहीं जानता कि क्यों उन्होंने ऐसा नहीं किया 'डिस्पैचर सर्वलेट' को कुछ 'संरक्षित' विधि के माध्यम से दृश्यमान बनाएं, लेकिन कस्टम समाधान अच्छा लगता है। –

+0

प्रतिक्रिया के लिए धन्यवाद @Sotirios धन्यवाद, बस सिर्फ DispatcherServlet – Ysak

उत्तर

13

By default, the DispatcherServlet does not throw a NoHandlerFoundException. आपको इसे सक्षम करने की आवश्यकता है।

AbstractAnnotationConfigDispatcherServletInitializer आपको DispatcherServlet बनाया गया है, इसे ओवरराइड करने देना चाहिए। कि करो और फोन

DispatcherServlet dispatcherServlet = ...; // might get it from super implementation 
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); 
+0

धन्यवाद ओवरराइड क्यों न करें। लेकिन मुझे 'एब्स्ट्रेशन एन्टरोटेशन कॉन्फिग डिस्प्लेटर सर्वलेटइनेनाइज़र' में 'प्रेषक सर्वलेट' प्राप्त करने में सक्षम नहीं लगता है। – Chantz

+0

@Chantz 'registerDispatcherServlet' को ओवरराइड करें। क्या करना है इसका विचार पाने के लिए सुपर प्रकार के कार्यान्वयन को देखें। –

+1

एक साल बाद ... क्या ऐसा करने का एक आसान तरीका है? मैं आमतौर पर अपने प्रारंभकर्ता में रजिस्टर डिस्पैटर सर्वलेट को ओवरराइड नहीं करता हूं इसलिए मुझे यह विधि भी वर्बोज़ मिलती है। उन सभी पंक्तियों को सिर्फ एक पंक्ति जोड़ने के लिए लिखा गया है। – Link

4

सक्षम DispatcherServlet web.xml configuartion के माध्यम से एक NoHandlerFoundException फेंक देते हैं।

<init-param> 
    <param-name>throwExceptionIfNoHandlerFound</param-name> 
    <param-value>true</param-value> 
</init-param> 
2

इसके बजाय अधिभावी registerDispatcherServlet एक के रूप में इस createDispatcherServlet विधि ओवरराइड कर सकते हैं।

@Override 
    protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) { 
     DispatcherServlet ds = new DispatcherServlet(servletAppContext); 
     ds.setThrowExceptionIfNoHandlerFound(true); 
     return ds; 
    } 
0

मैं @Ysak (प्रतिष्ठा < 50) द्वारा उपरोक्त पोस्ट पर टिप्पणी नहीं कर सकते हैं, हालांकि मैं पुष्टि कर सकता है कि इस विधि ओपी द्वारा वर्णित सेटअप के साथ काम करता है। सक्षम करने के लिए

@Configuration 
@EnableWebMvc 
@ComponentScan("com.acme.tat.controllers") 
public class WebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { 
... 
@Override 
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
     configurer.enable(); 
} 

} 

इस सेट के साथ, कोई अपवाद उत्पन्न होती है:

मैं जोड़ना होगा कि एक और गाइड से मैं भी DefaultServletHandling मेरी WebConfig में विन्यस्त एक अलग समस्या को ठीक करने के लिए किया था, जैसा कि नीचे। एक बार मैंने इस लाइन को हटा दिया और मैन्युअल संसाधन स्थापित किया हैडलर सब कुछ अपेक्षित के रूप में काम किया।

इस सरल एक लाइन विधि के कारण मुझे 404 रीडायरेक्ट करने के लिए लगभग 2.5 घंटे लग गए।

0

मैंने अपने आवेदन में निम्नलिखित प्रविष्टि के साथ समस्या का समाधान किया।YML

server.error.whitelabel.enabled: false 
spring.mvc.throw-exception-if-no-handler-found: true 

और निम्नलिखित ControllerExceptionHandler:

@ControllerAdvice 
public class ControllerExceptionHandler { 

@ExceptionHandler(Exception.class) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
public String processMethodNotSupportedException(Exception exception) { 
    exception.printStackTrace(); 
    return "error"; 
} 

} 

और पिछले नहीं बल्कि कम से कम मैं एक टेम्पलेट कहा, "/html/error.html"

संबंधित मुद्दे