Jackson and Hibernate Validator - java

Are there any online tutorial available to use Hibernate validator with Jackson for validating JSON?
I am using Spring and Jackson now for JSON parsing.
With Spring, I use MappingJacksonHttpMessageConverter to automatically translate the incoming JSON payload to Java object.
I would like to add validator annotations to the Java class. For example, if I have the Person class with "name" as one of the fields, I like to validate the JSON payload if the "name" element appears 1 time. If it appears more than 1 time in the payload, then I like the validator to kick in to reject the request.
Right now what I observed is that if there are multiple names in the payload, Jackson simply ignores and picks up the last one.
The Java object is not bound to any XML schema and the like.
What is the best practice for validating JSON?

Spring has JSR-303 support built in, see this chapter in the reference manual.
If you are using Spring MVC, see here, you should just be able to annotate parameters to #RequestMapping methods with #Valid.

Related

How can you use Spring Boot validation annotations with Jackson Custom Deserialization?

So basically, I have JSON payload that I want to deserialize into an custom object. To do this I'm using JacksonDeserializer. I'm also using Spring Validation Annotations to validate fields. Is there a way I get to the Spring Validation inside the deserializer so I can return appropriate exceptions/errors.

Securing JSON-PATCH paths in Spring Boot Data Rest application

I'm using a pretty vanilla spring-boot-starter-data-rest setup and enabled the PATCH method. All is working, but I have a security concern and wonder what's the recommended way of mitigating it.
The problem is that PATCH paths allow reachable entities to be updated from a different endpoint. So, suppose I have a comments endpoint and an article endpoint. Each comment has a to-one association with its article. A user that has permission to edit a comment could then do something like this:
PATCH http://some.domain.foo/api/comments/1234
Content-Type: application/json-patch+json
[
{ "op": "replace", "path": "/article/title", "value": "foobar2" }
]
and thereby change the title of the article !!
Clearly this ain't good.
In this case, for other parts of the API the association to the "article" needs to be traversable. But it must be read-only.
So... how do I accomplish this in Spring?
Intercept the request?
Implement a handler method?
Write my own Controller from scratch ?
Thanks!
Seems that current implementation on spring-data-rest converts paths to SpEL to apply values directly on beans. See PatchOperation (v2.5.x).
Consider these options:
Instead of json-patch use json-merge PATCH request to send partial updates (with "application/json" or "application/merge-patch+json" content type). This will respect #JsonIgnore and other Jackson annotations and also treat associations differently.
You can disable "json-patch+json" completely, for example by adding a security filter
You can always create your custom json-patch implementation, if you still need it
Use application-level joining not relying on JPA, i.e. only exposing IDs of the linked entities and providing custom links in your ResourceProcessor.
Additionally, if you're using JPA and Comment.article is annotated with #ManyToOne make sure that there's no cascading on association. Even if the article object is modified with patch it won't be saved together with the comment.
There's been a recent fix in Spring Data Rest:
https://github.com/spring-projects/spring-data-rest/issues/2177
The commit that resolves this issue is:
https://github.com/spring-projects/spring-data-rest/commit/5d0687d1a1bb9a84264ecb4cd088907837c382d3
From a quick read this seems to be checking that when applying a JSON patch to an entity a check is done with Jackson that the path should be accessible (read/write).
This should prevent users from being able to specify paths in the JSON patch that aren't normally exposed through POST/GET requests that are mapped directly onto entities through Jackson. I think that if you had marked the article as readable from the comment and the title attribute as writeable then the new code should allow it. Or that's I think what org.springframework.data.rest.webmvc.json.patch.JsonPointerMapping#verify is trying to do.
So if you marked the article on the comment as not being readable through Jackson (#JsonIgnore on the getter) then JSON patch shouldn't allow the title of the article to be set through a comment. The association would still exist, just not be exposed through JSON serialization, I'm not sure if this would cause problems for your application.
The change is released in Spring Data Rest 4.0.0 which is part of Spring Data 2022.0.1 which is in Spring Boot 3.0.2.
https://github.com/spring-projects/spring-data-rest/releases/tag/4.0.0
https://github.com/spring-projects/spring-data-bom/releases/tag/2022.0.1
https://github.com/spring-projects/spring-boot/releases/tag/v3.0.2

Jersey MOXy JSON Case-Insensitive Unmarshalling

I'm trying to setup a REST-service with Jersey 2.x that consumes a JSON-Response by POST using MOXy.
Everything works fine as long as all the JSON-attributes are named exactly like the properties in my POJO. Is there any way to configure MOXy so that it allows case-insensitive unmarshalling? For example: Match JSON-attribute "testid" to "TestID" in my POJO.
The POJO-Field is camel case, but the incoming JSON-Attribute could be in any case and my sevice should be able to process it nonetheless.
Thank you for your help!
Without defining a custom unmarshaller (or parsing directly from the HttpServletRequest) you can only define the expected key name, as pointed out in the comment of rmlan, with the JAXB annotation #XmlElement(name="testid"). However this will not protect your service from a JSON input with a key like "TestID" or "TESTID".

Spring DataBinder equivalent for Json

I am currently working on a web project which is using Play Framework 2.1.0. Play supports a decent API for parsing form data and mapping that to the Model beans directly. Which looks something like,
Form<Employee> form = Form.form(Employee.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(template.render(form));
}
This API also does validations on the fly and is capable of handling binding failures, when say a String could not be converted to an Integer. The Form API keeps the collection of errors mapped to the name of the property. Underlying the Form API, Play is using DataBinder of Spring's validation framework which is actually doing all the magic.
I was wondering if there is similar binding API to convert from JSON to the bean directly, with support for handling binding failures?
Play 2.0 uses Jackson internally which fails when there are binding failures and simply throws an exception. I looked at the code and does not look easy to supress these errors.
Is there some framework that can satisfy my requirement out of the box?
Essentially, I need the framework to convert from JSON to Java Bean, which can handle binding failures gracefully.
It would be wonderful if it allows me to collect them somewhere so I can generate appropriate validation errors. I will run custom validations on the parsed object using javax.validation APIs to perform more specific validations once the JSON is parsed into the Bean.
I achieved this by adding custom deserializers in Jackson
SimpleDeserializers deserializers = new SimpleDeserializers();
deserializers.addDeserializer(Integer.class, new MyIntegerDeserializer(null));
deserializers.addDeserializer(Long.class, new MyLongDeserializer(null));
ObjectMapper mapper = new ObjectMapper().setDeserializerProvider(
new StdDeserializerProvider().withAdditionalDeserializers(deserializers));
MyModel value = mapper.treeToValue(node, MyModel.class);
MyIntegerDeserializer and MyLongDeserializer are custom deserializers for Integer and Long values respectively. These are in my case exact copy of the internal default corresponding deserializer classes with additional code to gracefully handle NumberFormatException

Spring and JSR303

I need to validate an XML coming from a vendor and saving it as XML type in oracle....
Now i need a process to trigger a validation engine... which is going to validate it and save the value in indicator as 'YES' or 'NO' example if the address in XML doesn't exist in our dB make the address indicator as 'NO' [which we correct in another process...]
I already used JSR303 in Spring 303, which is very effective and easy to use....but it uses a form backing object and #valid.....
Can I use it here in my design...
Or let me put it this way -
Is it possible for Spring's JSR-303 implementation to validate object fields that are not from form input?
I know its a very vague question...so please let me know if I need to explain more
Most of the work for object's validation performed by JSR-303 provider (hibernate-validator in most cases). Spring's role in this process is minimal -- it just parses user's data, binds it to the object and passes this object to validator. Also, during application startup, Spring creates Validator instance.
So, you can interfere in this proccess: create object, which will be validated, manually, get Validator instance and pass object to him. As result you will get a Set of ConstraintViolation which represents errors of each fields.
In this scheme main problem is that JSR-303 validator works with object, while you operates with XML document. You may deserialize XML document to object, validate it and, if it doesn't have errors, serialize it back to XML and writes to DB.
I recommend to read the following part of Hibernate Validator manual: 2.2. Validating constraints It describe Validator interface and a few useful methods: validate(), validateProperty() and validateValue().
One benefit from Spring here is that you won't need to create Validator by yourself with Validation.buildDefaultValidatorFactory().getValidator(): just #Autowire it as all other Spring beans:
#Autowired
private Validator validator;

Categories

Resources