Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch parameter parsing exception in Spring 3.0 WebMVC

I use Spring WebMVC to provide a REST API. I use methods like

@RequestMapping("/path({id}") void getById(@PathVariable("id") int id) {} methods.

When the client incorrectly put a string instead of an integer id into the query, I get a NumberFormatException like:

java.lang.NumberFormatException: For input string: "dojo"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:410)
    at java.lang.Long.valueOf(Long.java:525)
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:158)
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:59)
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:1)
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:420)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:135)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:104)
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.java:47)
    at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:526)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolvePathVariable(HandlerMethodInvoker.java:602)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:289)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:163)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)

My Question is now, how can I elegantly catch it? I know that Spring provides @ExeptionHandler annotations but I don't want to catch the NFE in general. I want to be able to catch all parsing exception in order to present a nice error message to the client.

Any ideas?

Cheers,

Jan

like image 679
Jan Avatar asked Feb 07 '11 17:02

Jan


People also ask

How does Spring MVC handle 404 error?

The 404 error code is configured properly, but it will caused the “. htm” extension handling conflict between the “servlet container” and Spring's “DispatcherServlet“. To solve it, try change the 404. htm to other file extension, for example 404.

How do you handle the exception in spring?

Spring MVC Framework provides following ways to help us achieving robust exception handling. Controller Based - We can define exception handler methods in our controller classes. All we need is to annotate these methods with @ExceptionHandler annotation. This annotation takes Exception class as argument.

How do you handle an exception in spring boot using annotations?

The @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.

How exceptions are handled in MVC Spring?

Spring MVC provides exception handling for your web application to make sure you are sending your own exception page instead of the server-generated exception to the user. The @ExceptionHandler annotation is used to detect certain runtime exceptions and send responses according to the exception.


2 Answers

Is that the actual exception? (it doesn't match your code example) Normally one would expect that to be wrapped in org.springframework.beans.TypeMismatchException which is probably specific enough that you could write an @ExceptionHandler method for it.

If that's not specific enough, you will need to forgo the Spring-Magic and just change the parameter type to String + parse it yourself. Then you can handle it any way you like.

like image 192
Affe Avatar answered Oct 03 '22 18:10

Affe


I have found solution for your problem here http://www.coderanch.com/t/625951/Spring/REST-request-mapping-parameter-type

Just try

@RequestMapping("/path({id:[\\d]+}") void getById(@PathVariable("id") int id) {} methods.

And then not valid usage will cause 404. I'm not sure if version 3.0 supports this.

like image 28
Paweł Kaczorowski Avatar answered Oct 03 '22 17:10

Paweł Kaczorowski