Set value to the field using annotation - java

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.

Related

java/jersey/jackson - validate input JSON

I am writing a REST API with a Java/Jersey/Jackson stack. All JSON parsing and generating is done with Jackson. The REST layer is handled by Jersey. It will be embedded in a Grizzly container.
In my API, I accept JSON in my endpoints. For example:
#POST
public Response post(final SomeObject input) {
return ...;
}
What is the best way to validate the input? There are certain things I would like to validate:
input must be not null
certain fields of input must be not null
certain fields of input must follow a regular expression (text fields)
certain fields of input must be in a range (numeric fields)
...
If possible, I would like to change my code as less as possible. That is, I prefer to annotate my classes, methods and parameters to integrate the validation.
You can use a JSON Schema.
And since you use Jackson, you can use my library which does exactly that.
However this means you'd need to change your logic so that you receive the JSON (as a JsonNode) instead of the serialized POJO, and only then serialize to your POJO.
You can also BeanValidationApi (javax.validation.constraints) and then annotate your fields with #NotNull,#Pattern, etc. Jersey also provides Bean Validation Support

Binding empty values to numerical fields in Play Framework 2 (Java)

I have forms where I want to be able to leave some numerical fields empty, but I get "Invalid value" errors from Form.bindFromRequest(). This seems like a common requirement, but I can't find any documentation on this after hours of searching. I am still hoping I've missed something obvious, though!
I did some digging and found that Play uses Spring's DataBinder class to do the actual binding. That class is really sophisticated and would allow me to set custom binders for my fields, and if I was using Spring I could just add an #InitBinder method to my controller to set up the binder exactly the way I want using a CustomNumberEditor. However, it seems that Play Framework's Form object does not allow access to the DataBinder, apart from setting allowed fields. So, the binder tries to convert an empty string into a long, which gives a NumberFormatException:
Failed to convert property value of type 'java.lang.String' to required type 'long'
for property 'unitPriceExVAT';
nested exception is java.lang.NumberFormatException: For input string: ""
So, is there some other way of getting the binder to allow empty numerical fields?
Declare your fields as Long instead of the long primitive type and the empty values will be treated as null.

Is there a way to use static code analysis to determine if all fields of a certain type have an annotation?

I have some POJOs that are used to shuffle data around in my application and its webservices. We have just introduced an annotation to help us verify that String fields in those POJOs are of a certain length. This lets us validate the POJOs instead of waiting for the database layer to puke out an exception when it persists.
I would now like to do an analysis on those objects that will tell me what fields are Strings that do not have this new annotation. I want to do this so that I can get a list of fields that do not have this annotation so that it can be compared to its corresponding DB field and have the annotation added with the right length as its parameter.
No we cannot get a better correlation between our POJOs and our database objects.
No our database objects don't have this validation available. We really want this validation to happen on the POJOs as it is simpler to validate and report on invalid data at runtime.
Is there some static analysis tool that would help me with this task?
Sure.
Parse the Java code. Walk the AST. Find the fields of interest (may require that you also do name and type resolution ("symbol tables") so you can tell your fields from arbitary other fields) in the ASTs for your classes, and inspect the AST for the desired annotation.
You can do this with any Java AST parser (and name resolver). I think Eclipse can provide this. Our DMS Software Reengineering Toolkit can do this. ANTLR appears to have a Java parser, but I doubt if it has Java name and type resolution.
I opted to use annotations for the runtime validation needs and then crafted a unit test to verify that all fields were annotated. This was inspired by #c0mrade .
So the annotation is #Length and requires an integer parameter. At runtime the validator iterates over fields and looks for the #Length annotation and makes sure its applied on a String field. It then looks at the length of the Strings value and makes sure it is less than or equal to the parameter for the annotation.
In a unit test I load all of the classes for my POJOs by package. I then iterate over those classes, iterate over each classes fields, and finally check and see if the field is a String and has the #Length annotation assigned. If the field is a String and does not have #Length, it adds the class and field name to a list of Strings. The assertion for the test is that this list is empty.

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