I understand, in Java we have parameters validation solution. I believe JAX-RS has various annotations both for validation and data extraction. My question is, if I want to implement my own parameter validation class for a standalone Java application, how would I make sure that a method is executed only when its parameters have been validated? I am using Reflection to spot parameters with #LowerCaseCheck and then performing validation on it, but not sure where to place this validation code.
public void print(#LowerCaseCheck String lowerCaseString) {
....
}
You need to change the byte code of the method to perform the check (or call a method which performs the check) The simplest way to do this might be to use an Aspect orientated library like AspectJ.
Look at gag for an example of a library that does what you're looking for. It uses the asm bytecode manipulation library to insert validation checks at the start of annotated methods.
Cant'you use Bean Validation (JSR-303) to solve your problem ?
the #Pattern(regexp) annotation seems to do just what you need.
public void print(#Pattern(regexp = "^[a-z]*$") String lowerCaseString) {
....
}
Related
I have created a custom annotation
annotation class UserControl(
val userIdentifier: String
)
I wan to apply this annotation on query parameters, and path variables in different controllers.
fun userWithMobile(
#UserControl("PhoneNumber")
#RequestParam mobile: String
): RegisteredUser {
return userManager.getUserWithPhoneNumber(mobile))
}
How can i check if the query parameters have the UserControl annotation or not, and do some processing on that. Is there standard way to write a global handler , or a processor for that?
Would appreciate any help
AspectJ can directly match parameter annotations, but not bind them to advice method values like class or method annotations. So if you only want to match them, a simple pointcut is enough. If you want to access the annotations and maybe their parameter values, you need a little bit of reflection magic. I have answered related questions many times already, which is why I am going to close this one as a duplicate. But first, here are the resources you want to read. They all related to your question, showing examples of how to handle different specific situations:
https://stackoverflow.com/a/38162279/1082681
https://stackoverflow.com/a/10595712/1082681
https://stackoverflow.com/a/50540489/1082681
https://stackoverflow.com/a/49872132/1082681
https://stackoverflow.com/a/61284425/1082681
https://stackoverflow.com/a/16624766/1082681
Basically, the pointcut you want the following or some variation of it:
execution(* *(.., #my.package.UserControl (*), ..))
The naive, less efficient approach without matching the parameter in the pointcut, using only relfection:
https://stackoverflow.com/a/27784714/1082681
https://stackoverflow.com/a/42561014/1082681
Background
We are currently implementing an application using hexagonal architecture. Our REST API DTOs are mapped to our entities via MapStruct. This works fine. (Though, it would be much nicer if MapStruct would have support for hierarchical structures.)
Problem
However, we are facing a problem which is best described by the following example:
Consider you have an entity Person that stores the date of birth. Now, this
entity has a method which might be called int calculateAge().
The REST API's PersonDto will get an attribute int age.
Now, we want MapStruct to generate this mapping for us. Our approach was to try to configure #Mapping(target = "age", ...) to use the int calculateAge() method as source, but we did not succeed.
Believing this might be a straightforward application of MapStruct, we were quite disappointed to not come up with a clean solution after searching on this topic for hours.
Solutions
We found two solution approaches that work, but are (in our opinion) not really maintainable:
Use #Mapping(expression = "java(...)")
Use #AfterMapping to post process the constructed DTO and implement the required mappings in the annotated method
Question
Is there a cleaner way to achieve our goal, something which might look like this #Mapping(sourceMethod = "calculateAge", target = "age)?
Is there a cleaner way to achieve our goal, something which might look like this...
No, there isn't as of the MapStruct latest stable version (1.4.1.Final) of time of writing this answer. You have basically two choices which heavily depends what exactly and how you want to map the fields. I describe shortly in what case each solution is suitable for:
The first solution using expression introduces the problem the methods are hardcoded in the annotation. I prefer this solution only in the case of simple format conversions or calculations without calling a custom method (only from the existing Java API). Anyway, even with your proposed solution it would be still hardcoded. The syntax is the only thing that changes. There is effectively no difference in terms of maintainability:
#Mapping(target = "age", expression = "java(...)") // current API
#Mapping(sourceMethod = "calculateAge", target = "age") // hypothetical
Feel free to request for such feature. This solution in any case also requires imports within the mapper (#Mapper(imports = Another.class)) as well as the "hypothetical" one.
The annotation #AfterMapping is useful in case of more complex transformations and calculations. It's not as clean as a single annotation call and in fact you still write the mapping manually, however, it brings more control over the called methods which the IDE highlights before the compilation (at least you don't need an additional IDE-specific plugin). I'd go for this solution in case I need to call my custom methods and logics.
From what I've seen, Mapstruct relies on standard getters and setters. If you want to use a specific method then Mapstruct does work with #qualifiers, but I don't think the method can be in the entity. From my experience the best solution is to use #AfterMapping, as you mentioned.
In my application I need to use dynamic localization, so I cannot use Constants interface. I did use Constants for a while, but now I need texts to be changed without compiling so I had to find some other way.
So I am using Dictionary now. The thing is, when I now want to use text in UiBinder, I can only use methods without arguments. So I created class "StringIdentifiers" where I have the same methods I previously had in MyConstants, but I have to specify a body here for every method to return the specified String.
So for example I have:
Dictionary locale = Dictionary.getDictionary("myJsObjectWithStrings");
//and then the methods for returning the actual strings from the JS object
String loading(){
return locale.get("loading");
}
I would like the method to only be
String loading();
since the rest is always the same with the name of the method appearing as String parameter in the get() method. Possibly even returning some default value when the String is missing in the JS object. But I do not know how to do that. I checked the Constants interface, but I do not really understand the code there. Can someone please give me an example how to implement such a thing?
There is no standard feature in GWT to do this, but you could create one yourself. It's a bit of a stretch, but it should work by using the GWT generator mechanisch. In global terms it should work as follows:
Create an interface (say MyMessages) with a the method names.
To use it use MyMessages message = GWT.create(MyMessages.class). Where you need the text message.loading().
Create a generator that generates an class implementing the interface. This class will created at compile time and should contain the implementation of the interface methods, like in your example.
Add a generate-with tag in your gwt.xml file to make it work.
This is a bit of a brief explanation, but I hope it helps. For more background information about generators see: What is the use GWT generator? or http://blog.arcbees.com/2015/05/26/how-to-write-gwt-generators-efficiently/
You could even reuse some of GWT's annotation's of the i18n to add for example default texts. Add the annotation to your interface and in the generator scan the annotation and use it in the code generation part.
do you know if there is anyway that I can populate a javabean but i don't want to use reflection.
For example I have this xml template to pouplate it
Sample XML File
<property name = "card" value = "cdd"/>
public class Customer {
private String card;
public void setCard(String card) {
this.card = card;
}
public String getCard() {
}
}
I want to call setCard on the Java bean but I don't want to use reflection
since I've used it before and it's quite slow,
Are there any alternatives? How does Hibernate do it for example?
Thanks
Carlo
The only faster way (i.e. faster than using reflection) to populate a JavaBean from XML is to either write or generate some binding code that calls the setters with values extracted from the XML (in this case, from the XML attributes).
Hand writing the binding code is the simplest approach ... provided you don't have much to write.
Code could be generated as source code and compiled.
Code could be generated using a bytecode generation technology such as BCEL or ASM.
There may some existing XML-to-JavaBean binding generator, though existing bindings may well use reflection rather than code generation.
However, it is not clear this is worth going to the bother of avoiding reflection. While reflection is relatively expensive, XML is probably significantly more expensive. I'd recommend doing some profiling before you decide to use a more complicated implementation approach.
I'm pretty sure Hibernate uses reflection APIs deep under the hood. Groovy also has some nice support for automatically generating and using bean getters/setters which also ultimately use reflection under the hood as well.
Now there is an option where you could hard code your parser to read the xml and call the appropriate setter given the name attribute, but you run into the problem of your parser becoming brittle (when your model changes if that makes sense).
If the Bean is your's you may implement an interface like this:
/** Tries to set the property named key with the value given and returns true for success or false otherwise. */
boolean set(String key, Object value);
Then simply cast to that interface and try to use that method to set the properties. It sure needs some work in the bean - but avoids reflection.
Can I use a Java custom annotation to add some code to a set or get method on a bean property to cleanse the property from bad html being input by my users? I've been looking for examples but I've not seen something that I feel I can extend.
You could define a custom annotation to add a validator to your setter, but is there a reason why you don't want to just embed validation into your bean without an annotation? The annotation mechanism might be difficult for others to understand if they ever need to work with your code.
I would do it this way: Rather than have your property be a String, define your own HtmlString (assuming an equivalent class doesn't already exist in a standard library) which can only be instantiated with valid HTML. Then, have your bean property be of that type. This would solve the validation problem in your component.
Define validation methods in the HtmlString to fit your requirements, so that every HtmlString instance is valid HTML; then, simply define a toString method. This method would likely be much easier for others to follow.