How does Spring MVC convert #RequestParam values? - java

I'm new to the Spring Framework, and as a symptom, I want to keep my adoption of its Web MVC portions as simple as possible, so I'm using the annotation functions to work with Spring. In the past, I've used:
int value = Integer.valueOf(request.getParameter("numberValue")) to pull values from parameters - explicitly converting the String returned by getParameter(). Helpfully, I've noticed that when I use Spring's terminology:#RequestParameter("numberValue") int numVal
the conversion is handled automatically. This is nice, but a "black box" to me. I tried looking at questions on here or in the Spring documentation, but all that information deals with custom conversions (like Converter) for objects or formatting issues. All I want to know is how Spring handles primitive type conversions for #RequestParam by default.

I've noticed that when I use Spring's terminology:
#RequestParameter("numberValue") int numVal the conversion is handled
automatically.
Here you are looking for Type Conversion
As per spring documentation given on this link
String-based values extracted from the request including request
parameters, path variables, request headers, and cookie values may
need to be converted to the target type of the method parameter or
field (e.g., binding a request parameter to a field in an
#ModelAttribute parameter) they’re bound to. If the target type is not
String, Spring automatically converts to the appropriate type. All
simple types such as int, long, Date, etc. are supported.

Related

Set value to the field using annotation

I have an application which convert values from one one format to another. This conversion is required at the time of receiving an input or sending an output. I want to use annotations for this purpose.
The requirement is to create a custom annotation that can reset the value of the field, the annotation is linked to, after conversion based on some value, e.g.
#Convert(value = "butter")
String meal;
So, if meal = "bread" when it is received in the request, it should be converted to "bread n butter" and then passed on for further processing.
I did try to search it on google but did not find anything useful. Though I have worked on custom annotations for validation but that doesn't suit the requirement here. I am looking for a way to program such a custom annotation and not aware of any interface, similar to one when we write custom validation annotations, that could be implemented for this purpose.

BigDecimal as a parameter of REST API

such a simple question,
Can a BigDecimal field used as a parameter for a REST API in my WebObject?
As BigDecimal should be instantiated using constructor, will that happen if I send the parameter
{
"input" : 5
}
Will this parameter instantiated to BigDecimal automatically?
It all depends as what API framework you using. With Spring Boot which uses Jackson API to deserialize, this will be converted correctly.
Directly using BigDecimal in front transfer object might not give you correct scaling & precision so I recommend to take String input and customize your BigDecimal creation as per need.

Overflow protection for numbers jax-rs

With #Path variables it is possible to stop overflow conversions (from string to number).
For example if a parameter is an integer (int) then a path expression like {number : \d{1,5}} is a breaker before doing a number conversion.
What about handling query parameters in a similar fashion? The syntax for path variables isn't usable in the #QueryParam annotation (#QueryParam("big : \d{1,5}") big...).
Introduction: The path parameters guide the request to the correct method, and therefore a big flexibility is needed for that. The request parameters (GET/POST/...) on the other side need to be validated, i.e if a request contain invalid parameter value, you should take care of that.
Solution:
Beginning with JAX-RS 2.0 (published in May 2013 with the reference implementation Jersey 2.0) you have support for validation. Check this examples.
Before JAX-RS 2.0 (probably your situation) you should do the validation manually, e.g by injecting an int or long and checking its limits.

Get value from #RequestParam without specified name

I know that if a parameter looks like this:
#RequestParam("userId") String userId
I can get the value by calling this:
requestParam.value()
But if I don't specify a name, Spring automatically uses the variable name. Like this:
#RequestParam String userId
If the param name isn't specified, how can I access it? I know its possible because Spring does it somehow, but requestParam.value() is blank in this case.
Spring doesn't populate the request based on the #RequestParam. Rather it populates the method argument annotated with #RequestParam (in a method annotated with #RequestMapping). The parameter given to the #RequestParam annotation tells Spring the name of the request parameter you want it to use as that argument. If you don't provide one, Spring defaults to using the name of the argument (so the 2 examples you give in your question are equivalent).
If you are trying to access a request parameter, you need to know the name of it, regardless of the framework you are using.
Recommend you not to do it that way.Spring use asm
to analysis the java bytecode file,and extract parameter name of a method.But some time this does not work,because some .class file does not comprise parameter name,just parameter types,it depends on compiler options.
In case of Java 8, Spring uses StandardReflectionParameterNameDiscoverer, which relies on Java 8 Parameters API.
For details how to set up parameters option and use it via reflection see this answer.
Just call userId, as in doSomething(userId). Spring binds everything up for you.

Validate Numbers in Spring

I have a basic doubt in how to proceed in my application. I have a form and I need to validate that all the inputs which are numbers. I have a problem in deciding the type of the attributes of the bean asociated with the form. I don't know if setting them to String or to double and here are the reasons:
If I set them to double: If I enter in the input something which is not a number when spring populates the inputs into the bean I get an Exception in the JSP that it could not convert it into double.
If I set them to String: I have a good validation although I have to change them later to double. But my problem here is that this bean is stored in a database with hibernate and the annotation #column would store it as a text and I would like to store it as if it were a double. Is there any posibility to change the column type to the double deferred type?
Does anyone can give me any idea in how to preceed in this case?
Thanks.
I suggest you always work with your domain types and not use String just because that's the way HTTP sends params. If a field has type double, you will use it as such in your code and also store it as such in the database. Let Spring convert the request params to your needed type.
Data binding is useful for allowing user input to be dynamically bound to the domain model of an application (or whatever objects you use to process user input). Spring provides the so-called DataBinder class to do exactly that.
You can register those in the initBinder method of your controllers and will allow you to transform the Strings from your request into the desired type. See for example the CustomNumberEditor class used to parse user-entered number strings into Number properties of beans. You can then combine this with the Validator interface for more complex checks.
EDIT: Spring binding uses typeMismatch error codes for binding errors when a conversion fails (required code if you specify a field as required but you don’t supply it). In your case it defaults to showing the exception message. To change the message to a more friendly one, you must supply a bundle key in your property file using the typeMismatch prefix.
This is specified by the DataBinder.setMessageCodesResolver and defaults to org.springframework.validation.DefaultMessageCodesResolver. In the javadoc of DefaultMessageCodesResolver you can see complete examples, but basically, you just have to add an entry like this in your properties file:
typeMismatch.yourField=Your user friendly error message goes here
You can map the exception to the custom message if you have an entry in the following form in your message.properties (or the equivalent message bundle that you are using).
typeMismatch.fieldName, where fieldName would be the name of the field you are validating.
If you are using Spring 3.0
have a look at the Overriding Defaults with Annotations part of
Spring 3 Type Conversion and Validation
If you are using Spring 2.x+ you can achieve this by registering Custom PropertyEditor as mentioned in above post

Categories