Bit confused with #JsonAutoDetect, ObjectMapper() - spring

With reference to my previous linked in question I'm bit confused with the usability of #JsonAutoDetect.
I solved the problem by adding #Getter to FieldValues class and removed the #JsonAutoDetect.
So now it let me thinking, what would be the scenario where #JsonAutoDetect can be used, as I can achieve the same result without having it. What is the purpose of having #JsonAutoDetact annotation over having getter methods. Am I missing something.
Not able to write any comment for previous question so created a new one.

Here is an article that I think can help you. The url is https://www.baeldung.com/jackson-jsonmappingexception .
At my point, if you use jackson-databind jar, spring underlying use ObjectMapper to serialize JavaBean. If neither javaBean's field nor getter method is public, spring could not serialize JavaBean automaticlly. Annotation #JsonAutoDetect is used to custom your javaBean, by which way you can set field limits to any level (e.g. protected public private... so that you can serialize the javaBean successfully).
If I don't understand wrong, the #Getter is from lombok that automaticlly help you generate public getter method.

Related

Accessing Transient field of Entity through Service

Currently, I am learning Spring Boot. I got trouble with accessing the #Transient variable of Entity class from my #Service class.
Actually, I want to calculate the popularity of the book in my Service and want to assign it to a specific book.
#Transient
private Double popularity;
Any tips on solving this problem.
Let me know if you need more information.
Thank you in advance!
Transient properties are properties that do not have an appropriate column in the database table. But of course, they should have getters and setters, as any other property.
So after you calculate the popularity, just simply use the setter (setPopularity) as for any other class property.

Spring boot: #Valid not working with #RequestHeader

I'm really struggling to combine #Valid with #RequestHeader.
Might this be not supported or is there a way to enable it? I couldn't find useful information about that...
When I annotate the whole controller with #Validated it works, so it is not a big issue. However, I feel like it should work with #Valid as well, so I wanted to know if I'm missing something here.
Code example:
#GetMapping("/validationControllerHeader")
public String validationControllerHeader(#Valid #RequestHeader #Pattern(regexp = "[a-z]{3}[0-9]+") String someheader) {
return someheader;
}
I'm using #Valid in the same test controller for query parameters and body validation too and there it works, so the issue is only present with headers.
Using spring boot 2.3.1.RELEASE
You are definitely supposed to use #Validated in your controller class, as it indicates that the validation is meant to be performed in that class. From the documentation:
To be eligible for Spring-driven method validation, all target classes need to be annotated with Spring’s #Validated annotation, which can optionally also declare the validation groups to use.
And, as you are using #Pattern (which is a Bean Validation annotation), you don't need #Valid.

How to change Jackson to detect all fields in a POJO, other than only public ones?

When using Spring Boot for a project, Jackson came as default to serialize objects back and from Jsons. I realize that Jackson fails if you don't have public accessors, e.g., getters/setters, or public fields in your POJO.
The behavior is different when I switch to Gson. It detects all fields regardless of their visibility. For this reason, I ended up using Gson.
I felt a little uncomfortable about switching my POJO access rules; It would force some refactoring in the project structure.
So, no problems using Gson, but is there a way of change Jackson's behavior?
Jackson does support reading values from private member fields, but does not do it by default.
You can configure the behavior globally in the Spring Boot config like
jackson:
visibility.field: any
visibility.getter: none
visibility.setter: none
visibility.is-getter: none
(this config will only look for member fields and no longer check get, set and is methods)
You could also use the #JsonAutoDetect annotation to do the same setting for a specific class.
Try to set visibility at ObjectMapper level,
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

Update field annotated with #Value in runtime

Let's imagine we have such a component in Spring:
#Component
public class MyComponent {
#Value("${someProperty}")
private String text;
}
If we define the property placeholder:
<context:property-placeholder location="classpath:myProps.properties"/>
And myPropos.properties contains the value for someProperty the value will be injected to the text field when the context is initialized. That's quite simple and easy.
But let's say that I have a service that enables user to change the value of the someProperty:
public void changeProp(String name, String newValue);
Is there a chance I can re-inject the newValue to text field. I mean it should be quite straight forward.. Basically it's nothing different than the after-initialization injection. I can not imagine that Spring does not have support for this? Can I fire some event or something?
I could do this on my own basically, but I wander is it maybe something there already? If not does anyone know what Spring class is in fact handling the injections at the first place? I could probably reuse the code there do perform this on my own if a solution does not exists.
I expect spring does not have a support for this, because the normal injection is done while creating the bean, but not will it is put in service.
Anyway: in this blog entry "Reloadable Application Properties with Spring 3.1, Java 7 and Google Guava", you can find the idea for an solution.
The key idea is to use a post processor to build a list of all fields with property fields. And if the properties are changed on can use this list to update the fields.

Bean Validation for POST requisition in JAX-RS with Jersey implementation

I'm using the Jersey implementation for JAX-RS, and I was looking for an example where I can use the Bean Validation in POST requisitions. I have this operation, for example:
#POST
#Path("document/annotations/save")
#Produces("application/json")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Map<String, Object> saveAnnotation(
#FormParam("user") String userStr,
#FormParam("documentId") String documentId,
#FormParam("documentPage") Integer documentPage,
#FormParam("annotationContent") String annotationContent,
#FormParam("annotationId") Long annotationId,
#FormParam("isMobile") Boolean isMobile) { // the code... }
I wanna use validations constraints (#NotNull, #Pattern, etc) for each method param. I saw this doc where they're using the Seam Framework to do that.
Currently, I'm trying to use the javax.validation implementation to validate my requests, but it doesn't working.
Is there a way to use the JSR-303 specification with JAX-RS?
Tnks.
This is currently not possible using Jersey; one possible alternative is to write a customer resource filter and bind to the #NotNull, etc. annotations.
It would be simpler if it was encapsulated in a resource class because you could then bind to a #Valid annotation on your method and validate the bean in one shot.
Because JSR-303 is designed to deal with beans and not a collection of parameters then it ends up being very verbose when you try to bend it to your will.
IMHO it's better not to keep validation inside your class anyway and to either use the pipes and filters pattern, i.e. ContainerRequestFilter, or to use something like AspectJ as #Willy suggested.
It's possible. See docs for latest Jersey
https://jersey.java.net/documentation/latest/bean-validation.html#d0e9380
https://jersey.java.net/documentation/latest/bean-validation.html

Resources