简体   繁体   中英

Configuring exception handling in spring

Im using extdirectspring and spring in a java webapp.

I've recently been trying to set up exception handling basically following this tutorial .

I have a few context files. But upon adding the following setup to my module which includes the exception handler

One called server-context looks like this

<context:component-scan base-package="blah.eventsModule" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/errorPages/</value>
    </property>
</bean>

<mvc:annotation-driven />

This is the one I'd added the exception handling stuff to

Its supposed to be picking up this class:

@Component
public class ErrorReporter
{
    @Autowired
    private MyConfig _config;

    @ExceptionHandler(Throwable.class)
    public ModelAndView ShowErrorPage(Exception exception)
    {
        if (_config.debug())
            return new ModelAndView("ShowStackTrace.jsp", "exception", exception);

        return new ModelAndView("Whoops.jsp");
    }
}

I initially left out <mvc:annotation-driven /> to see if it was necessary. A break point in ShowErrorPage wasn't hit so I put it back in. Now I get the following error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'routerController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter ch.ralscha.extdirectspring.controller.RouterController.handlerAdapter; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter] is defined: expected single matching bean but found 2:

That's happening in extdirectspring (a third party library).

I've not created RequestMappingHandlerAdapter explicitely but obviously now I've got two of them. I don't care what extdirect is trying to do with this. So if there is a way of scoping what I'm doing then that would be good.

The only other thing I can think is that spring doesn't like there to be more than one

<mvc:annotation-driven />

declaration in a project.

Here are some bits of code that look suspicious:

public class LoggingHandlerExceptionResolver implements HandlerExceptionResolver, Ordered
{
    private final static Logger logger = LoggerFactory.getLogger(LoggingHandlerExceptionResolver.class);

    @Autowired
    private ErrorLogService errorLogService;

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
    ...

    // Returning null allows other HandlerExceptionResolvers to be called (e.g. to show an error page)
    return null;
}

The comment there isn't mine and I don't know whether it is true or not but it looks like its in the same ballpark and suggests that having multiple of these things is ok.

That class is in our 'core' module

As is this xml snippet:

<!-- Spring MVC configuration -->
<mvc:annotation-driven conversion-service="conversionService">

    <mvc:argument-resolvers>
        <!-- Resolve Spring Data pageable arguments -->
        <bean class="org.springframework.data.web.PageableArgumentResolver" />
    </mvc:argument-resolvers>

    <mvc:message-converters>
        <!-- Wire the custom object mapper into Spring MVC -->
        <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="objectMapper" />
        </bean>
    </mvc:message-converters>

</mvc:annotation-driven>

That doesn't seem to have anything to do with my stuff but it's the only other place mvc:annotation-driven crops up in the project.

Could anyone shed some light on whats going on?

I want to have the two seperate errorhandling methods separate - the new one I'm adding is for a new part of the project - we have 2 deployments - one which is thoroughly broken and is relying on several different components supressing errors. In the new one we aren't pushing exceptions under the rug. This is a bit of a follow up from another question I asked recently about getting sensible exception handling in a webapp .

We've got 2 separate application-contexts and the flaky application doesnt include the new file at the top. They are both using the core module though.

Update

If I hack the annotation driven snippet out of the core module then I no longer have the autowired issue but the new exception handling still doesn't get run.

It seems like once I figure out how to get that working then the problem will be how to merge 2 mvc configs?

Typical solution to a spring problem: I dont understand what happened but after copying something else I dont understand I now have something which works!

I'm not quite sure exactly when I stopped being a programmer and instead became someone who fiddles with config files. It's been a gradual death!

I have changed my error handler to follow the style of the other working one.

I'm now defining it as a bean in the application context

<bean class="blah.LoggingHandlerExceptionResolver"/>
<bean class="blah.ErrorReporter"/>

And it looks like this:

public class ErrorReporter implements HandlerExceptionResolver, Ordered
{
    @Autowired
    private MyConfig _config;

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception exception)
    {
        if (_config.debug())
            return new ModelAndView("ShowStackTrace.jsp", "exception", exception);

        return new ModelAndView("Whoops.jsp");
    }

    @Override
    public int getOrder()
    {
        return 0;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM