Announcement Announcement Module
Collapse
No announcement yet.
Question about SimpleMappingExceptionResolver Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Question about SimpleMappingExceptionResolver

    I have the following controller, xx-servlet.xml file. But resolver.resolveException is returning null. I don't why?

    <b>Here's the part of xxx-servlet.xml that has exceptionMapping</b>
    Code:
     <bean id="exceptionMapping" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="mappedHandlers">
                <set>
                    <ref bean="loginController" />
                </set>
            </property>
            <property name="exceptionMappings">
                <props>
                    <prop key="java.lang.Exception">genericErrorView</prop>
                </props>
            </property>
        </bean>
    <b>Here's the controller</b>

    Code:
    public class LoginController extends SimpleFormController 
    {
        
        private SimpleMappingExceptionResolver resolver;
        
         public LoginController() {
        
    		setCommandClass(LoginDetails.class);
                    setCommandName("loginDetails");
                    resolver = new SimpleMappingExceptionResolver();
    		
    	}
    
            protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command,BindException errors) throws Exception
    	{
    		ModelAndView mv = null;
    		try
                    {
    			LoginDetails ld = (LoginDetails)command;
                            String clientId = "a1";
                            Hashtable h = null;
                            h.put("Hello","hello");
    			mv = new ModelAndView(new RedirectView("CustomerOptions.htm"));
                            //mv.addObject("errors",errors.getModel());
                            return mv;
                    }
                    catch(Exception e)
                    {
                        mv = resolver.resolveException(request,response,"loginController",e);                   
                        
                        System.out.println("mv " + mv);
                        return mv;
                    }
                    
    	
    	}
    NOTE: Intentionally I tried to add something to hashtable without instantiating it. So, a Null Pointer Exception must be thrown. Actually in the controller, if I remove try catch then at runtime when the controller is executed it does redirect me to the error page I have configured. but, the moment i add try-catch and call resolver.resolveMethod(), ModelAndView is returned null. I don't why?
    Last edited by anjanks1981; Jun 28th, 2008, 05:09 PM. Reason: Adding code tags

  • #2
    First off al you shouldn't be using the ExceptionHandlerResolver that way, you should the dispatcher servlet handle that.

    However regarding your issue.

    Code:
    private SimpleMappingExceptionResolver resolver;
        
         public LoginController() {
        
    		setCommandClass(LoginDetails.class);
                    setCommandName("loginDetails");
                    resolver = new SimpleMappingExceptionResolver();
    		
    	}
    You don't want to create a new one (without any configuration) you want to use the one configured in your xml file.

    Comment


    • #3
      Can you explain as to what you mean by DIspatcher Servlet doing it? I did remove resolver= new Simple...Resolver(), but still it returns null.

      Can you please give me an example of how to do this?

      Comment


      • #4
        The DispatcherServlet uses the HandlerExceptionResolver, any exception thrown which bubbles up to the DispatcherServlet is handled by it. It delegates to HandlerExceptionResolvers.

        Also simply removing the new isn't going to do anything for you you will still have to dependency inject the resolver into your controller, how else is your controller going to get a reference to the resolver configured in your ApplicationContext.

        Comment


        • #5
          I am not clear how we can induce dependency. In the xml file I have added the controller name in "mappings" and added exceptions. The reality is that if I don't use try catch in my controller, the page gets redirected to the errorpage i have configured in xml file in the event of exception. What I need is to have redirection happening in try catch. Say in catch (in the controller) I want to call resolver.resolve() so that the xml file checks the exception mapping and get the view name and accordingly redirect. It is this redirection in try catch which is not working. How to make this work?

          Can you please help me with this?

          Comment


          • #6
            I explained it twice. I suggest you readup on inversion of control and dependency injection. Get your basics straight. Also read the javadocs of the classes involved that makes a stuff a lot clearer also.

            Controller (slightly modified there was an error in your catch clause)
            Code:
            public class LoginController extends SimpleFormController {
                
            	private HandlerExceptionResolver resolver;
                
            	public void setHandlerExceptionResolver(HandlerExceptionResolver resolver) {
            		this.resolver=resolver;
            	}
            	
                public LoginController() {    
            		setCommandClass(LoginDetails.class);
                    setCommandName("loginDetails");
            	}
            
                protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command,BindException errors) throws Exception {
            		ModelAndView mv = null;
            		try {
            			LoginDetails ld = (LoginDetails)command;
                        String clientId = "a1";
                        Hashtable h = null;
                        h.put("Hello","hello");
            			mv = new ModelAndView(new RedirectView("CustomerOptions.htm"));
                        //mv.addObject("errors",errors.getModel());
                    } catch(Exception e) {
                        mv = resolver.resolveException(request,response,this,e);                   
                        System.out.println("mv " + mv);
                    }
            		return mv;	
            	}
            }
            xml
            Code:
            <bean id="loginController" class="LoginController">
            	<property name="handlerExceptionResolver" ref="exceptionMapping" />
            	<!-- other properties -->
            </bean>
            
            <bean id="exceptionMapping" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            	<property name="mappedHandlers">
            		<set>
            			<ref bean="loginController" />
            		</set>
            	</property>
            	<property name="exceptionMappings">
            		<props>
            			<prop key="java.lang.Exception">genericErrorView</prop>
            		</props>
            	</property>
            </bean>
            The blue highlight, which is what you refer to, has nothing to do with expression dependencies. It only makes clear to the dispatcherservlet that this HandlerExceptionResolver handles exceptions from that controller. It doesn't make clear any further relationship NOR does it automagically inject it into the Controllers. (The javadoc is quite clear about that....).

            Also I still don't get it why you would want to do this in a try catch while you can have the DispatcherServlet do it for you (and you told yourself that that worked....).

            Comment


            • #7
              The intention to use try catch (without this works..true) is to log the exception (as this is needed for me) and then get it redirected to a JSP.
              I coded this way because the explanation given in "EXPERT SPRING MVC and Web Flow" book says this way. I am pasting the code of that book here as is

              Code:
              <beans>
              <bean id="exceptionMappingForSingleController"
              class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
              <property name="mappedHandlers">
              <set>
              <ref bean="someController" />
              </set>
              </property>
              <property name="exceptionMappings">
              <props>
              <prop key="ApplicationException">appErrorView</prop>
              <prop key="SomeOtherException">someErrorView</prop>
              <prop key="java.lang.Exception">genericErrorView</prop>
              </props>
              </property>
              </bean>
              If u note here in the ref bean it says a controller. So, I put in my controller so that any exceptions mentioned in "exceptionMappings" if occurs in that controller it will go to the View mentioned

              Also the book says the following...I am pasting in code tag just for clarity

              Code:
              Listing 5-24 contains sample code that programmatically illustrates what view name is resolved when an Exception exception is thrown.
              Listing 5-24.  Test Case
              
              ModelAndView mav = resolver.resolveException(req, res, handler,
              new Exception());
              
              Notice how, in Listing 5-24, the SimpleMappingExceptionResolver returned the vie
              I wonder why resolver.resolveException function is being called if everything is handled by DispatcherServlet. I tried to call this function in catch block just to see if the method returns the view name

              In Javadoc, I was reading only SimpleMappingExceptionResolver. All it says is that it maps exception class names to view names either for a given set of handlers or for all handlers in the Dispatcher Servlet.In Javadoc, I was reading only SimpleMappingExceptionResolver. All it says is that it maps exception class names to view names either for a given set of handlers or for all handlers in the Dispatcher Servlet. So, when we add a bean tag with SimpleMappingExceptionResolver (which is added even in my xml and that's why it is working), it means that internally (by default in the Spring framework) this SimpleMappingExceptionResolver is implemented and will call resolveException and then redirects to the error page configured. So, we do not have to call or handle this function.

              So, accordingly in my xml I mentioned the controller in the mappings and the exception in the exception list. It is behaving correctly. But, I want to log something in catch block and then redirect. How can this be done? If this is unwanted, then how can I log some info if I want.
              Last edited by anjanks1981; Jun 29th, 2008, 09:16 PM. Reason: Add some details

              Comment


              • #8
                The DispatcherServlet does the logging for you as well. So this can be as simple as you throwing exception in your code and having this bit of xml in your config xml file

                <bean class="org.springframework.web.servlet.handler.Sim pleMappingExceptionResolver">
                <property name="exceptionAttribute" value="error"/>
                <property name="defaultErrorView" value="genericErrorView"/>
                <property name="exceptionMappings">
                <props>
                <prop key="NullPointerException">genericErrorView</prop>
                </props>
                </property>
                </bean>


                The Application log will have trace of all that went wrong.

                Comment

                Working...
                X