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.
Related
I would like to imbue my API with the ability to set values on a range of objects in a single call. A seemingly logical solution is for the user to define in the ranges in the URI and set the desired new values in the request body. For example the URI would be:
/api/horses/?color=brown
In the request body, the key/value pair would be
key: color
value: red
This will turn all of our brown horses red.
The problem is that getting parameters from the HttpServletRequest object does not let you determine if the parameters were set in the URI or the body.
Perhaps there are two questions here:
If there is different, generally accepted RESTful way to set values on a range of objects in a single call, what is it?
If using both URI and request body parameters is ok, how do you differentiate between those in the HttpServletRequest object?
Update: The accepted answer addresses how to differentiate (the second of the enumerated questions). To address the general challenge for updating a range of values, I decided that this can be best accomplished by limiting to only one updated field and specifying the field in the path. Like so:
PUT /api/horses/color?from=brown&to=red
So your problem is that you have a name clash between parameters encoded in the request line and parameters encoded in the POST body.
You can always differentiate by calling:
HttpServletRequest.getQueryString()
HttpServletRequest.getInputStream()
obviously you then have to use a URL library for parsing the query string (the encoded/decoder in the JDK is ok) and library for the form data, depending on the encoding (I recall some Apache project called commons-codec for this).
I'd go the simplest route of not having name clashes - for example by prefixing URL parameters with filter- but there's no standard rule for this.
We are facing issue related with making a path parameter optional.
original URL /expire/{token}
What we are trying to do is have the same service work for the URL's below.
1. /expire/{token}
2. /expire
Ex:- #Path("/expire/{token}")
We have already applied other solutions from SO,but no luck so far.
What about adding another method annotated with only:
#Path("/expire")
And let this method pass a null value into the original method.
Logically, it doesn't seem to make sense to have it optional. Your URI should handle the type of request it's supposed to do. But, I came across a post to make the #PathParam to be optional with a small hack using regular expressions.
http://www.nakov.com/blog/2009/07/15/jax-rs-path-pathparam-and-optional-parameters/
I would go with having separate endpoint method in Controller where it can pass the call to your services with optional parameter.
We can use regular expressions,
"#Path("/add/{a:([0-9.]*)}/{b:([0-9.]*)}{p:/?}{c:([0-9.]*)}")"
here path can be
add/2/3
add/2/3/4
my case I am using regular expressions for allowing only numbers
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.
I am using Spring MVC 2.5 and for my model/bean class, at the moment, I use server side validation. One of the validation I wanted to do is check if some of the inputs are not numeric (0-9). The user may input non-numeric characters like "abcd" instead of '1234'.
I have a #Pattern which only accepts positive BigDecimal (it represents dollar amount).
public class OfferSettingBean implements Serializable {
private static final String NUMBER_WITH_DECIMAL_PLACES_ONLY="^\\d+([.]\\d+)?$";
//org.hibernate.validator.pattern
#Pattern(regex = NUMBER_WITH_DECIMAL_PLACES_ONLY, message = "invalid.amount")
private BigDecimal offerSize;
//the rest of the code goes here including setter and getter methods
}
jsp page
<input type="text" name="offerSize" id="offerSize" value="${offerSetting.offerSize}" placeholder="$" />
The problem with my code is, if the user enters a non number character like "asdfsd" it doesnt even reach to the point where it should check the pattern.
Failed to convert property value of type [java.lang.String] to required type [java.math.BigDecimal] for property offerSize; nested exception is java.lang.NumberFormatException
I think the problem is before checking the pattern it binds the string value to BigDecimal which makes it fail.
One ugly solution might be in the offerSize setter method I can check the coming value and do something if it is not a number. But I dont like that one.
What is a better way to deal with such kind of binding problems?
FYI: I know I am going to do client side validation (using JQuery) latter on. Now, I assume the user by passes the client side validation in some way.
The error message is self-explainable.
#Pattern can be used for validation of String arguments. Numbers (int, double, BigDecimal etc) are parsed automatically and do not need special validation.
So, just remove your pattern or make your field String and parse it yourself. (The second solution is bad).
BTW are you sure you indeed need BigDecimal to operate with money? Do you know how double big is? I think that it is big enough to hold total amount of money that have been ever printed in whole world during latest 5 thousand years.
I think the problem is before checking the pattern it binds the string value to BigDecimal which makes it fail.
Yep!
What is a better way to deal with such kind of binding problems?
Not sure what you mean here. There was an error. The error was caught. All seems well. What behavior would you prefer?
FYI: I know I am going to do client side validation (using JQuery) latter on. Now, I assume the user by passes the client side validation in some way.
Even later, one is better off validating both client-side and server-side, IMO. There are many ways client-side validation can fail, both innocent and malicious, and even if that weren't the case, it is nice to be able to reuse server-side code without worrying about all the validation being gone because it was located in client-side Java script.
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