I was reading the Jersey docs about bean validation. The ParameterNameProvider example shows how to define parameter names for a method. However, the implementation looks like this will have to be done for each and every method which obviously doesn't scale. The example is basically useless as is.
Is there a smarter way to do this? Couldn't Jersey infer the name from #QueryParam or #PathParam annotations?
Take a look at the answer in my question here. It should do exactly what you want.
Can I change the property path in a ConstraintValidator for Method arguments?
If you copy my code and run it through a debugger you will see that it is only evaluated once for each method for which it is used. Then during normal running of your app the names will not need to be resolved again.
Related
I have a question about Reflection, but the motivation is from using Spring Framework.
Consider this project, which is a sort of Minimum Working Example version of a deployed project.
In the ProjectionResourceProcessorConfig class, I have an entityProjectionResourceProcessor method for every projection, and every entity in the database have a few projections. That's about 60 methods.
I don't want to keep this up because of the obvious maintenance disadvantage. I want to use Reflection in order to automatically register one bean for every projection class.
The postProcessBeanDefinitionRegistry method in the ProjectionResourceProcessorConfig class shows that I can get the list of classes I want to use to register one bean for each and shows how to register a bean programatically.
However, because I need to use the ProjectionResourceProcessor class, I need to override the getEntityClass method. I haven't been able to find a way to do that programatically. That's why I've declared the inner class. It shows the programatic bean registration working, but it falls in the same issue as requiring a piece of code for every bean.
Apart from reflection, I tried to use the setMethodOverrides method of the RootBeanDefinition class to override that method, but I couldn't manage to understand how to use that method. Google couldn't find any documentation or usage example (except for a vaguely related Chinese post with copies on several different websites).
I also tried to use the MethodReplacer class but I haven't found how to use it with annotation driven configuration.
I also tried to replace the getEntityClass method by a variable and replace the variable's value by reflection, but apparently when the variable is read the value that was set in the super class is the one that is retrieved.
To test the project, run the tests at DemoApplicationTests. It will print the projection of some entities. If they have links, it's working.
Is it possible to do what I want? If it is, how?
Thanks in advance.
Is it possible to insert a value stored in a configuration file (eg: application.properties) inside java annotation as follows :
#MyAnnotation(name="${application.prop1}")
and in application.properties I have:
application.prop1=foo
So that at runtime I have :
#MyAnnotation(name="foo")
Yeah, I don't think this is possible. Spring has no idea about your annotation and doesn't know what to do with it. Even if you try to use #Value(..) on top of your String name() default "" (inside of your annotation), Spring still won't make this happen as the annotation is not a bean. Trying to make your annotation a bean won't work either as far as I can tell. It sound like you are going to have to come up with some type of processor for this.
Perhaps looking into the following topics might help give you some ideas on how to put this together:
Auto Configuration: https://www.baeldung.com/spring-boot-custom-auto-configuration
SPeL: https://www.baeldung.com/spring-expression-language
Java Reflection: http://tutorials.jenkov.com/java-reflection/index.html
And of course, there's always the possibility that you might want to step back and consider why you want to do this? What are you trying to achieve that perhaps can be done a more "out of the box" way.
Yes, yse #Value annotation
#Value("property1")
In a Jersey class, Which is more appropriate of the two:
On an instance variable
#PathParam("service-id")
private String serviceId;
On a method argument
public Response subscribe(#PathParam("service-id") String serviceId){}
I'm using first one only because service-id is required by almost all my methods. However, a colleague of mine had a comment over this approach that ultimately Jersey classes are based on servlets and servlets should not have stateful variables.
I read about this in the JSR-311 java docs
Because injection occurs at object creation time, use of this
annotation on resource class fields and bean properties is only
supported for the default per-request resource class lifecycle.
Resource classes using other lifecycles should only use this
annotation on resource method parameters.
Since in a webapp, my Jersey class is going to follow per-request resource class lifecycle, I feel first approach is safe. Thoughts please :)
It is made safe by virtue of only allowing this annotation in request-scope (so that every request gets its own bean/resource instance and there is no shared state).
I'd probably give each method the full set of parameters, though, even if it is a bit repetitive. Makes it easier to see at a glance what is going on. That's a code style issue, though, and people can have different opinions here.
This is only coding styles issues since this code has exactly the same result.
I also prefer to define it in the method, instead of defining it in the instance.
Whatever, once compiled, the result is the same! :)
Let say I want to check condition[let say boundary values] on some of the method arguments.Instead of writing "if" condition to check [boundary condition] on every method, I want to annotate argument only. Let me know the Steps to understand it. Working code will be awesome.
You need to look into method interception. What you are wanting is an interceptor that can validate method arguments on invocation. I like the AOP Alliance interfaces for this, they work pretty well. It also integrates with Guice natively and I think Spring has support for it as well.
Steps:
Define an annotation
Create an interceptor to process the annotation
Bind the interceptor (manually or using some framework)
The Jasper Reports docs is silent on this issue and the JRDataSource interface is not explicitly allowing the access to the current bean. The current bean handle is very useful if you want to call some non property method.
The only solution I've found so far looking in the jasper reports sources is to use a _THIS field in the report and invoke the desired method on it:
${_THIS}.computeSomeValue()
Is there a better, more standard approach?
I usually use a custom_Scriptlet extending the JRDefaultScriptlet (if i ever need any other method calls pertaining to my bean). A better approach i think will be just to gather all data you will ever need (either in your bean as an instance variable with a setter/getter method or passed as a parameter when you fill your report).
This way you can leave the property bean methods take care of the rest.
Try:
$P{REPORT_DATA_SOURCE}.getData().get($V{REPORT_COUNT} - 1)