spring #RequestBody validation fails - spring

I have a very simple question related to the following line of code:
public void reject(#PathVariable int x, #Valid #NotEmpty #RequestBody String comments)
While debugging, the comments field has "" value and should fail.
Shall this work?
I know if I wrap comments in a object it will work but I am wondering why it is not working in this case.

i think, in you case, you have to use #NoBlank.
public void reject(#PathVariable int x, #Valid #NotBlank #RequestBody String comments)
See the difference here:
#NotNull: Checks whether the value is not null, disregarding the
content
#NotEmpty: Checks whether the value is not null nor empty. If it has
just empty spaces, it will allow it as not empty
#NotBlank: Checks whether the value is not null nor empty, trimming
the value first. It means that, it won’t allow just empty spaces
Source.

Related

How to make Gson read value as String?

My JSON objects look like this
{"phoneNbr":"123456789","firstName":"Mark","previousNames":[{"previous1":"Peter","previous2":"Steve"}]}
{"phoneNbr":"234567891","firstName":"Hank","previousNames":null}
The previousNames values can be anything. I want it to be treated a STRING always. However when I try to parse it, GSON complaints because it expects array.
PersonJsonDAO class looks like this
private String phoneNbr;
private String firstName;
private String previousNames;
I try to parse it but GSON says Expected a string but was BEGIN_ARRAY
PersonJsonDAO personJsonDAO= new Gson().fromJson(jsonString, PersonJsonDAO.class);
How can I force GSON to accept previousNames as String?
GSON is treating it as an array, because it is indeed an array :)
I can think of 4 different alternatives to meet your desired behavior:
A preprocessing step of turning everything after '"previousNames":' into a string, by searching for the first occurance of '"previousNames":[', inserting there a '"', backspacing all the double quotes, till the occurrence of ']', before which I would add another double quote.
a much easier solution, if you don't mind the slight computational overhead, which in your case is probably tiny, just parse into a JSON as a first step, like you did, but declaring previousNames as an array of Strings, and then calling:
personJsonDAO.getString("previousNames");
However, this will leave you with previousNames field as an array of Strings.
Another option is to leave it as a JSonObject in the deserilization process, like this:
class PersonJsonDAO {
....
#SerializedName("previousNames")
JsonObject previousNames;
....
}
If the above alternatives are not enough, and you insist on having the previousNames field as a String, then the most comprehensive and correct approach would be to override the desiarilzation process of GSON, calling super for all behaviours, except when meeting the previousNames culprit, which you would return as a String.

how to detect missing primitive in request instead of defaulting the actual value to 0 in springboot?

I have a rest controller that receives a Json request which is wrapped in a DTO. In that DTO I have this field.
#NotNull(message = "value is mandatory.")
private double value;
The problem is that when I send a request missing this value, I dont get a validation error because maybe the value defaults to 0.
How can I make sure that I notify the caller if this value is actually missing in the payload and not default to 0 automatically in spring?
Used #M.Deinum's suggestion and it worked okay. Involves avoiding using primitives
#NotNull(message = "value is mandatory.")
private Double value;
I have a suggestion you can add one more annotation which helps you to avoid using zero like this
#Min(1)
#NotNull(message = "value is mandatory.")
private double value;
Now it will take min value 1 so maybe it will work

Can't compare Strings

I am not able to compare the String returned from student.getUsername() to the hardcoded string(it is alway false even for correct values)
but when I use a normal string and not the one returned from student.getUsername() it is able to execute if block and return "login Success". I think the value returned from student.getUsername() is not comparable to String I even tried .toString() but no luck Please help.
#PostMapping()
public String setUser(#Valid #ModelAttribute("Student")Student student, Errors errors,
ModelMap model) {
String user = "das";
String pass = "12345";
if((student.getUsername()==user)&&(student.getPassword()==pass))return "loginSuccess";
else return "loginFailure"
You should use equals() method to compare the CONTENT of strings.
== operator in Java compares addresses of objects not theirs content :<

Spring MVC - Throws exception when the int value of ModelAttribute is null

I'm building an web application using Spring 3.0 MVC.
I have a method which has prototype below.
#RequestMapping(value = "/blahblah/blah.do", method=RequestMethod.GET)
public void searchData(#RequestParam(value="uniqOid", required=false) String uniqOid, #ModelAttribute("MasterVo") MasterVo searchVo,
ModelMap model, HttpServletResponse response, HttpServletRequest request)
The problem is that, the view (jsp) contains inputs that matches to searchVo(ModelAttribute).
When the int or long value of searchVo didn't come from the jsp, the server throws 404 page not found exception.
If the type of value is "String", it has no problem.
In my opinion, it is the problem of type casting.
How could I solve this problem, and which part of the server code that I have to check?
Thanks in advance.
I will go ahead and assume a few things about your problem.
It is not a type-cast problem. Spring has default converters that can easily convert from a String to some primitive type.
Now what you are facing is I think a null assigment to primitive type problem. Suppose the name of the property that's causing the problem is named primitiveProperty. Now, the request-paramters could include a parameter named primitiveProperty with an empty-String value, or some value that cannot be converted to a number. If the type of the primitiveProperty is String, it can assign the value of that parameter to it without any problem.
If the type of the primitiveProperty is int, long or some other primitive type that cannot have a null value, a problem occurs. When Spring converts the empty-string or a non-numeric string valued request-param named primitiveProperty, it cannot do so since that string can't be converted to a valid int or long value. So it is converted to null. Now, when Spring tries to assign that null value to a property that cannot have a null value (any primitve type), you get an Exception. If you are getting an empty-string as your request-param, you can replace the troublesome property in your domain object with its equivalent wrapper class (int with Integer, long with Long and so on). If you are getting a non-numeric value from your view, well, make sure that you don't get a non-numeric value.
You need to check the setter of the fields that are giving the typecast problem, in your case MasterVo .
The Spring will call the setter of the property to bind the value, where i presume you will see the error coming.
Just add a debug point to this setter and you will see the problem.

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