Exclude 0 from JSON response in Jackson Spring boot - spring-boot

I have a POJO like this.
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Test {
private int a;
private String b;
}
I want to exclude the property 'a' if it has 0 value. String b is excluded with
#JsonInclude(JsonInclude.Include.NON_NULL)
Only way I could thing of is convert the int data type to Integer Object and set the value to NULL in the setter explicitly if it is 0.
Any other suggestions or correct solution will be appreciated

Option 1:
Do what you said: Change int to Integer and use #JsonInclude(Include.NON_NULL). Because primitive types have default values and their values cannot be compared to null you have to wrap the int to Integer. See Primitive Data Types. imho this is the cleaner way.
Option 2:
Use the way described in this answer and use #JsonInclude(Include.NON_DEFAULT) instead (see Jackson-annotations API), so that default values (and so also null values for objects) will be ignored.
Note:
If you only want to exclude the specific field (in your case the int/Integer - a - field) when it has a null-/default value and the other fields (in your case the String - b - field) should be included when they have null-/default values, put the annotation on field level.

Related

Initialize non existing keys to empty array list

I have a class :
class Con {
private List<Ind> inds;
}
I am using Gson in the usual way to convert a JSON string to this class object. so in case, the JSON doesn't have the key inds present this variable inds is assigned a null value. Is there a way to assign inds an empty ArrayList instead?
My Thoughts:
One straightforward way could be once the Gson object is built. Go over all the null objects and assign them to the new ArrayList<>(). Is there a better approach?
public List<Ind> getInds() {
return inds;
}
Currently I am using the above getter in a code like : con.getInds().stream() which is causing NullPointerException.
I am not sure what would be a good way to resolve this. Instead of List Should I return an Optional or Should I modify this getter like
public List<Ind> getInds() {
inds==null?new ArrayList<>():inds;
}
The above will also resolve the NullPointerException. Not sure if there are pros and cons to using this approach. Although now there is no way to identify if the Json has a key with name inds or not. For the current code that I am writing this may not be required. But there is a meaning loss here certainly.
One solution to this would be to assign default values to the fields, for example:
class Con {
private List<Ind> inds = new ArrayList<>();
}
Gson will keep this default value; only if the field is present in the JSON data it will reassign the field value.
There are however a few things to keep in mind:
Your class needs a no-args constructor (implicit or explicit); otherwise Gson might create instances without invoking the initializer blocks of the class, and therefore the field will be null
If the field is present in JSON but has a JSON null value, then Gson will still set that as value
You cannot tell afterwards whether the field was present in JSON but had an empty JSON array as value, or whether it was missing

Validate at least 1 of a set of args is present in Kotlin class constructor

Scenario
I need to create a Kotlin class that can receive up to 4 arguments for its constructor, but only requires at least 1 out of a set of 3 (the fourth being entirely optional). To illustrate:
class Pie {
// Completely optional, the constructor should use it if present, otherwise it may be null.
var topping: String?
// Of these three [fillingA, fillingB, fillingC] 1 or more must be present.
var fillingA: String?
var fillingB: String?
var fillingC: String?
}
Thoughts
I've attempted to use Kotlin init{} blocks for validation, or telescoping constructors, but it gets ugly fast and I've yet to solve the issue. I have not found anything in the kotlinlang.org docs on primary/secondary constructors that is more elegant, though. My preference would be to find something similar to the #Size or #NotNull annotations, but I have failed to locate anything close.
It is important to note that I am using this class as a model for an API response.
Question
What is the most concise way to validate that a Kotlin class has at least 1 of a set of arguments passed to its constructor?
Are this fillings interchangeable? You could assume that fillingA is always required and the other ones are optional, something like this:
class Pie constructor(
val fillingA: String,
val fillingB: String? = null,
val fillingC: String? = null,
val topping: String? = null
){...}

Spring Boot validation takes float value in integer field

I'm trying to implement a POST service with request validation.
My Controller method looks something like below
public void updateScore(#Valid ScoreRequest)
ScoreRequest looks like below
import javax.validation.constraints.*;
import lombok.Data;
#Data
public class ScoreRequest {
#Min(0)
#Max(100)
#Digits(fraction = 0, integer = 3)
private Integer score;
...
}
It all works fine till I pass integer values for score, however If I pass fraction part as well, request goes through and Spring somehow truncates the fraction and uses the integer part in the request.
I was expecting it to throw a validation error since datatype of score doesn't match.
It works with followling request, and uses 10 as the score value in the request object. I'm expecting it to throw an error, what am I doing wrong?
{"score": 10.234234}
Spring Boot version: 2.0.3.RELEASE
I was trying to debug Spring Boot's validation classes to find what was happening, but after looking at the comment by #M.Denium I searched for Jackson issues and found a related SO entry.
Java Jackson - prevent float to int conversion when deserializing
I'm using answer by #Jichao Zhang, however Just to confirm answer by #Eduardo Sanchez-Ros works as well. This is what works for me.
ObjectMapper.configure(DESERIALIZATION_FEATURE.ACCEPT_FLOAT_AS_INT, false);
Don't use this annotation: #Digits(fraction = 0, integer = 3 with Integer since it is useless to set fractions for Integer.
Why don't you do:
#Min(0)
#Max(100)
#Digits(fraction = 0, integer = 3)
private BigDecimal score;
If you closely look at the definition of the #digits annotation,
#Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
So this annotation can be applied to methods also.
If you read the docs, it says this annotation can be applied to the following types
BigDecimal
BigInteger
CharSequence
byte (or Byte)
short (or Short)
int (or Integer)
long (or Long)
the integer field of the annotation checks for the number of integral digits while the fraction field of the annotation checks for the number of fractional digits.
Since, you declared your field to be an Integer value. It casts the value to an integer and truncates the fractional part.
This does not fail validations as both the fields satisfy the validation.
This annotation is ideally to be only used with BigDecimal type.

How to ask protoc to use a value instead of a pointer as the value side of a map with Go?

I am using protocol buffers defined like this:
message Index {
message albums {
repeated string name = 1;
}
map<string, albums> artists_albums= 1;
map<int32, albums> year_albums = 2;
}
It generates go code like this:
type Index struct {
ArtistsAlbums map[string]*IndexAlbums
YearAlbums map[int32]*IndexAlbums
}
How can I make it generate map values of type IndexAlbums instead of *IndexAlbums?
If you use gogoprotobuf then there is an extension that will allow that
map<string, albums> artists_albums = 1 [(gogoproto.nullable) = false];
With regular goprotobuf I don't believe there is a way.
nullable, if false, a field is generated without a pointer (see warning below).
Warning about nullable: According to the Protocol
Buffer specification, you should be able to tell whether a field is
set or unset. With the option nullable=false this feature is lost,
since your non-nullable fields will always be set. It can be seen as a
layer on top of Protocol Buffers, where before and after marshalling
all non-nullable fields are set and they cannot be unset.

GroupSequence and order of evaluation in JSR 303

I have a field of type String in a command bean which has to be validated in the following order.
Must contain a value (not empty).
Must have exactly 6 characters.
Must confirm this regexp - [0-9, a-f, A-F]+
When any of them is violated, the rest must not be performed. I have tried to achieve this using #GroupSequence as follows.
#GroupSequence({TempBean.ValidationGroupNotEmpty.class, TempBean.ValidationGroupColourHexLength.class, TempBean.ValidationGroup.class, TempBean.class})
public final class TempBean
{
#NotEmpty(groups={ValidationGroupNotEmpty.class}, message="Must enter a valid colour code.")
#Length(min=6, max=6, groups={ValidationGroupColourHexLength.class}, message="Requires exactly 6 characters.")
#Pattern(groups={ValidationGroup.class}, regexp="[0-9, a-f, A-F]+", message="Invalid colour code.")
private String stringValue;
public interface ValidationGroup{}
public interface ValidationGroupNotEmpty{}
public interface ValidationGroupColourHexLength{}
// Getters and setters.
}
When the text-field is intentionally left blank, only #NotEmpty is performed but when I enter a value that violates the #Length and the #Pattern constraints, I'm getting both the messages as specified meaning they both are evaluated. This shouldn't happen. Only one of them should be performed at a time in the defined order. How can this be done?
I'm using Spring 3.2.0 and Hibernate Validator 4.3.1.
You code looks fine and I even tested it against HV 4.3.1. It works as expected. You are evaluating the Default group right? Have you tried to debug?

Resources