Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 23

Thread: ResponseEntity<?> return type @ExceptionHandler method in 3.2.0.RC2

  1. #11
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    mvc:annotation-driven needs to be used next to the component-scan (unless you configure all your @Controllers by hand)... It isn't a replacement...

    There aren't any conflicts I know about between the 2... Could you post the stacktrace? Switching to java based configuration shouldn't solve the problem because you still need component-scan and annotation-driven (@ComponentScan and @EnableWebMvc) ... So that isn't the solution...

    And could you also post your original configuration and maybe a controller? (There might be something conflicting in there!).

    One thing about the component-scan (and you wouldn't be the first to fall in that trap) is that there is also one in the ContextLoaderLIstener with the same base package which leads to duplication of all your beans! A rule of thumb your component-scan for the dispatcherservlet should (in general) only be scanning for @Controllers (in short disable default filters and add a include-filter for the Controller annotation). And your ContextLoaderListener for anything BUT @Controller (simply include an exclusion for @Controller).
    Last edited by Marten Deinum; Dec 12th, 2012 at 06:06 AM. Reason: Add component-scan note.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  2. #12

    Default

    I've departed pretty far from what I had.

    Can you clarify: should I be able to completely do away with the servlet.xml config file, and use annotations only? Or MUST I have mvc:annotation-driven in there? Like I said, the docs suggest it's either-or. What I'm reading here implies I don't need both.

  3. #13
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    I'm going to give the default consultant answer it depends... For the mvc part you don't need an xml file you can create a class annotate it with @Configuration and add @EnableWebMvc (the jva config alternative to mvc:annotation-driven)... I suggest you also let that class extend WebMvcConfigurationSupport which makes it easier to modify the default settings or extend on them.

    Basically with Servlet 3.0 and Spring 3.x you can create a xml less application. However depending on the other spring products you use YMMV as not all spring products have a full java configuration option yet. (Spring Web Flow and Spring Batch for instance ) then you still need an xml file for that part of the configuration.

    Sample (from the top of my head).
    Code:
    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = {"your.base.package", useDefaultFilters=false, filters = Filter{type=ANNOTATION, value=org.springframework.stereotype.Controller.class}}
    public class WebContextConfiguration extends WebMvcConfigurationSupport {
    
    }
    Initializer
    Code:
    public class MyApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
      protected Class[] getRootConfigClasses() {
        return new Class[] { RootContext.class}; // Or whatever you called it
      }
      
    
      protected Class[] getServletConfigClasses() {
        return new Class[] {WebContextConfiguration.class}; // Or whatever you called it
      }
    
    
    }
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  4. #14

    Default

    I'm trying to implement it as described under "A 100% code-based approach to configuration" here: http://static.springsource.org/sprin...itializer.html

    So far, my container spits out:

    [12-12-12 04:28:22.086] {main} WebApp[production/webapp/default/ROOT,STARTING] No Spring WebApplicationInitializer types detected on classpath

    It's 4:30 am. I'm going to bed.

  5. #15

    Default

    Marten,

    I've gotten past the servlet-3.0 stuff. My org.springframework.web.WebApplicationInitializer is being configured now, but I'm having trouble configuring Spring as described in "A 100% code-based approach to configuration". But I get an exception "Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!".

    The exception occurs when I try to create and register the ContextLoaderListener.

    I have a class that looks like this (which is almost identical to the one in the docs):

    Code:
    public
    class
    WebappInitializer implements org.springframework.web.WebApplicationInitializer
    {
        @Override
        public
        void
        onStartup(ServletContext inContainer)
        {
            sLogger.debug("enter onStartup");
            
            //  Create the root Spring application context…
            
            sLogger.debug("Create and register rootContext");
            
            AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
            rootContext.register(AppConfig.class);
    
            //  Manage the lifecycle of the root application context…
            
            sLogger.debug("Create and register ContextLoaderListener");
            
            //  Exception occurs here:
            inContainer.addListener(new ContextLoaderListener(rootContext));
    
            // Create the dispatcher servlet's Spring application context…
            
            sLogger.debug("Create and register dispatchContext");
            
            AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
            dispatcherContext.register(WebConfig.class);
    
            //  Register and map the dispatcher servlet…
            
            sLogger.debug("Create dispatcher");
            
            ServletRegistration.Dynamic dispatcher = inContainer.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
            dispatcher.setLoadOnStartup(2);
            dispatcher.addMapping("/");
            
            sLogger.debug("done");
        }
        
        @Configuration
        public
        static
        class
        AppConfig
        {
        }
        
        @EnableWebMvc
        @Configuration
        public
        static
        class
        WebConfig
        {
        }
    }
    The onStartup() completes execution, but even though the DispatcherServlet is registered, requests aren't handled. It does not appear to be loading my @Controller "ServiceController".

  6. #16
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Make sure you have no web.xml with ContextLoaderListener registered.

    The onStartup() completes execution, but even though the DispatcherServlet is registered, requests aren't handled. It does not appear to be loading my @Controller "ServiceController".
    As expected as there is no @ComponentScan and as such your controllers aren't picked up (none of your beans are). Also if you get an exception, as you mention, nothing will be started.

    See the sample @Configuration class I posted yesterday! The @ComponentScan for the root context should contain an exclusion filter for @Controller.

    Code:
    @Configuration
    @ComponentScan(basePackages = {"your.base.package", excludeFilters = Filter{type=ANNOTATION, value=org.springframework.stereotype.Controller.class}}
    public static class AppConfig {}
    
    @Configuration
    @EnableWebMvc 
    @ComponentScan(basePackages = {"your.base.package", useDefaultFilters="false", includeFilters = Filter{type=ANNOTATION, value=org.springframework.stereotype.Controller.class}}
    public static class WebConfig extends WebMvcConfigurationSupport {
    
      protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable(); // Needed because we map DispatcherServlet to /
      }
    }
    Also as mentioned in that same post I suggest using one of the convenience classes (AbstractAnnotationConfigDispatcherServletInitiali zer ) from Spring instead of implementing the interface yourself.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #17

    Default

    Quote Originally Posted by Marten Deinum View Post
    Make sure you have no web.xml with ContextLoaderListener registered.
    Yep there are no .xml files at all. This might be a bug in resin (maybe it's aggressively instantiating all ServletContextListener implementations it finds?); I've asked those guys to clarify.

    As expected as there is no @ComponentScan and as such your controllers aren't picked up (none of your beans are). Also if you get an exception, as you mention, nothing will be started.
    Ah, right. I keep thinking @EnableWebMvc does the scanning. Before, when I had this in .xml files, adding the component-scan caused issues. Is that because it wasn't filtering?

    Based on your example, I want to exclude @Controllers from the AppConfig, but include only @Controllers in the WebConfig. This seems a little cumbersome, but at least there's a solution.

    As an aside, wouldn't I just want to combine the Web and App contexts and configurations (and class scanning) into one thing?

    Also as mentioned in that same post I suggest using one of the convenience classes (AbstractAnnotationConfigDispatcherServletInitiali zer ) from Spring instead of implementing the interface yourself.
    Thanks for all your help so far, Marten. You did mention that, but the way I interpreted the docs, I thought I was missing out on something automatic if I did that. There really should be a new paragraph for that last line in that section.

    My new initializer class looks like this:

    Code:
    public
    class
    WebappInitializer extends org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
    {
        @Override
        public
        void
        onStartup(ServletContext inContainer)
            throws
                javax.servlet.ServletException
        {
            sLogger.debug("enter onStartup");
            super.onStartup(inContainer);
            sLogger.debug("done");
        }
        
        protected
        Class<?>[]
        getRootConfigClasses()
        {
            Class<?>[] classes = { AppConfig.class };
            return classes;
        }
        
        protected
        Class<?>[]
        getServletConfigClasses()
        {
            Class<?>[] classes = { WebConfig.class };
            return classes;
        }
        
        protected
        java.lang.String[]
        getServletMappings()
        {
            String[] mappings = { "/" };
            return mappings;
        }
        
        @Configuration
        public
        static
        class
        AppConfig
        {
        }
        
        @EnableWebMvc
        @Configuration
        public
        static
        class
        WebConfig
        {
        }
    }
    I'll add the @ComponentScan after I resolve the ContextLoaderListener issue (baby steps).

  8. #18

    Default

    Things are getting closer. I've added @ComponentScan, and according to the logging it's instantiating my controllers and wiring up my model objects and DAOs, but it's still not mapping requests. I still have to figure out how to properly instantiate the sessionFactory and set up the transaction stuff, but for now I just want to get the mapping to work.

    I see this in the logs:

    Code:
    03:03:59.233 DEBUG web.servlet.handler.AbstractDetectingUrlHandlerMapping (AbstractDetectingUrlHandlerMapping.java:71) Looking for URL mappings in application context: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Thu Dec 13 03:03:58 PST 2012]; parent: Root WebApplicationContext
    ...
    03:03:59.235 DEBUG web.servlet.handler.AbstractDetectingUrlHandlerMapping (AbstractDetectingUrlHandlerMapping.java:86) Rejected bean name 'mainController': no URL paths identified
    03:03:59.235 DEBUG web.servlet.handler.AbstractDetectingUrlHandlerMapping (AbstractDetectingUrlHandlerMapping.java:86) Rejected bean name 'serviceController': no URL paths identified
    ...
    even though a little earlier in the logs I have this:

    Code:
    ...
    03:03:59.174 INFO  web.servlet.handler.AbstractHandlerMethodMapping (AbstractHandlerMethodMapping.java:186) Mapped "{[/ || /Main],methods=[GET || HEAD],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.latencyzero.gamecenter.web.MainController.main()
    03:03:59.181 INFO  web.servlet.handler.AbstractHandlerMethodMapping (AbstractHandlerMethodMapping.java:186) Mapped "{[/service/],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json;charset=UTF-8],custom=[]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.latencyzero.gamecenter.web.ServiceController.getRoot() throws java.lang.Exception
    ...

  9. #19
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Which means that they are mapped...

    There are several HandlerMappings defined which try to detect mapping information, some apply others don't so there is mapping...

    Check the logs for what is happening which request is handled and why it isn't found. Probably the url doesn't match make sure that the servlet mapping is the same as you previously had in your web.xml...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  10. #20

    Default

    Quote Originally Posted by Marten Deinum View Post
    Check the logs for what is happening which request is handled and why it isn't found. Probably the url doesn't match make sure that the servlet mapping is the same as you previously had in your web.xml...
    Yeah, in my web.xml I had <url-pattern>/</url-pattern>, and you can see above I return a single mapping "/".

    By the way, what's the new @WebAppConfiguration and @ContextConfiguration for my test class (that will go through the annotation-based configuration)?

    Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •