Spring MVC property/field binding exception - java

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.

Related

DMN - matching a Java enum by a FEEL expression

I have a Java enum as an input in a DMN decision table. The DMN call is embedded directly in the Java app. So take some enum:
public enum Foo {
ONE, TWO
}
I pass an instance of this enum as an input - dmnContext.set("Foo", foo);
I hoped to be able to set a decision table input for foo of type string, and have a rule that matched "ONE". However, this doesn't work, because there is no POJO-String conversion. In the Java code, I could store foo as a String and validate it against the enumerated values (i.e. check foo is in the set ["ONE", "TWO"]), but this will complicate other parts of the application.
How can I achieve this while still using an enum type?
Please refer to this existing JIRA record comment section, for the explanation about:
why you are experiencing that behaviour
and why you should convert your Java-enum to the expected DMN type (which I guess) is a FEEL:string , and not an enum
You can use Jackson to achieve this, instead of resorting to custom code or DMN model modification.
Don't hesitate to Subscribe to the JIRA linked above, as we're hoping of making that work out-of-the-box; but is not trivial since the DMN RTF is thinking about introducing Enumerations directly in DMN eventually, so we need to take into account today what might happen tomorrow.
Since you are linking to Red Hat Product documentation, a reminder that you are strongly encouraged to open a Customer Portal ticket at https://access.redhat.com/support/cases/#/ if you have a Subscription.
I will appreciate your feedback following there references/pointers and I hope those helps

How can I use ConstraintValidator directly?

I have an unusual use case.
In my left hand, I have a String value (say, "5001"). In my right hand I have an Annotation literal with some interesting information. It basically defines a named "slot" for which (in this example) "5001" is an appropriate value.
Let us now also say that I have some javax.validation.constraints Annotation (like Digits) in my...other hand. Note that I do not have any reference to any field or method or any other AnnotatedElement—just the javax.validation.constraints Annotation literal itself. This is the weird part, but take it as fact.
Armed with these bits, I can almost use ConstraintValidator to see if "5001" is a valid value for the "slot" defined by my annotation literal. But not quite, as I cannot acquire a ConstraintValidatorContext for use in the isValid() method.
(I have read this question on the subject, which suggests that I'm out of luck.)
I also cannot simply use the Validator API as I am not validating a bean instance but instead merely a value that, if everything goes well, may be used indirectly in an XSLT file, if you must know. :-) It's the determining if everything is going to go well part that I'd like to use javax.validation for here. But, as mentioned, I don't have a bean instance with an annotated element to validate—I just have the value that would go into that annotated element.
Is there a way forward here?

Java / Spring - Securing a Parameter ( Pathvariable )

Is there a common way to secure a pathvariable?
#RequestMapping("/image/{id}")
public String getArticleImageUrl(#PathVariable String id) {
....
I mean remove unusual content e.g. javascript or other security issue related things to prevent "hacking" or abusive use?
What is secure depends on what you want to use the input for. Bottom line: You should take the same care with these kinds of parameters as any other parameter you would accept from the outside into the system, e.g.:
Take appropriate action to prevent SQL injection (i.e. PreparedStatements)
Take care when rendering stuff on your web site that was received as user input (i.e. make sure to HTML encode stuff - most frameworks would take care of this for you).
etc.
"Washing" the input from unwanted characters is possible but, as always: tricky and depending on what the data will be used for.
Nvm.
I used a regex to check if this String is alphanumeric. ( ^[\\pL\\pN]+$ )
Should be enough.

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

Using GPB, how do I make my wrapper classes stop accepting binary messages that aren't meant for them?

I'm using Google Protocol Buffers to serialize some of my business objects (in a Java app). As recommended in the tutorials, I wrap the message builder in a class of my own that implements getter and setter methods to access the message's properties. Also, I declared all message fields optional, again following their recommendations.
Now, I can give any of the wrapper classes any of the encoded messages and they will always parse and accept them. This leads to wrapper objects that represent a message type which they don't actually contain and a lot of bogus happens.
When loading the binary content of a message into a wrapper class, how can I make it throw an error if it has been passed the wrong type?
The solution I'm currently thinking of would have all messages extend a base message with a required type field (and maybe a version field). This would have the generated builder class throw an exception if those fields are missing, and if they are there, I can check in my own code. However, I'm not yet done evaluating what repercussions this has for my code, and I'm not sure this is going to be easy.
If the data you pass to MyMessage.parseFrom() does not represent a message of that type, you will get a InvalidProtocolBufferException. Isn't that enough for you?
PB messages are not self-describing, so need to know (by some means) which message you are trying to parse. Of course, you can try to parse them and catch InvalidProtocolBufferException, but that isn't very nice. Instead, I think most people are using the approach you are describing: use a base message class with a type field (usually an enum) and a number of optional fields, one for each possible sub-type. This allows you to parse the message, and then switch on the message type to extract the actual "payload" of the message.
This seems to be what other people do, too, and it works fine for me:
message TypedMessage {
required string type = 1;
required bytes payload = 2;
}
The actual message goes into the payload field in serialized form and the type is used to get the proper builder and wrapper class. The field could also be an enum, I'm currently using Java class names, which I will likely replace by a different system later, since this means refactoring breaks backwards compatibility of the parser.

Categories