Java Integer null turns into 0 - java

When calling a REST service to save an Integer I've noticed that null value is turned into 0 and I don't know why this is happening. This is my class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "CompanyPreference") public class CompanyPreference {
public CompanyPreference() {
super();
}
#XmlElement
private Integer preferenceValueNumber;
public void setPreferenceValueNumber(Integer preferenceValueNumber) {
this.preferenceValueNumber = preferenceValueNumber;
}
public Integer getPreferenceValueNumber() {
return preferenceValueNumber;
}
}
and this is my web service
#POST
#SecureIt
#Consumes(value = { MediaType.APPLICATION_JSON })
#Produces(value = { MediaType.APPLICATION_JSON })
#Path("/{companyCode}/{companyType}/preferences/update")
#ApiOperation(value = "Update Company Preferences", response = DefaultResponse.class, authorizations = { #Authorization(value="Bearer") })
public Response savePreferences(#ApiParam(value = "Company Code", required = true) #PathParam("companyCode") String companyCode,
#ApiParam(value = "Company Type", required = true) #PathParam("companyType") String companyType,
#ApiParam(value = "Array of Company Preference objects", required = true) CompanyPreference[] companyPreferences,
#Context ContainerRequestContext crc) throws ResponseError {
for(int i = 0; i < companyPreferences.length; i++) {
System.out.println(companyPreferences[i].getPreferenceValueNumber());
}
}
Even though preferenceValueNumber is an Integer not a primitive int, it still gets turned into 0 when my request looks like this...
[
{ preferenceValueNumber: "" }, //this returns 0
{ preferenceValueNumber: 30 } //this returns 30 as it should
]
How can I keep the original value, null?

Related

boolean is set to false if it's not present in #RequestBody

I've stumbled upon interesting case and I'm not sure how to resolve it. It's probably related to JSON Post request for boolean field sends false by default but advices from that article didn't help.
Let's say I have this class:
public class ReqBody {
#NotNull
#Pattern(regexp = "^[0-9]{10}$")
private String phone;
//other fields
#NotNull
#JsonProperty(value = "create_anonymous_account")
private Boolean createAnonymousAccount = null;
//constructors, getters and setters
public Boolean getCreateAnonymousAccount() {
return createAnonymousAccount;
}
public void setCreateAnonymousAccount(Boolean createAnonymousAccount) {
this.createAnonymousAccount = createAnonymousAccount;
}
}
I also have endpoint:
#PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<MyOutput> test(
#ApiParam(value = "information", required = true) #RequestBody ReqBody input
) {
//do something
}
problem is when I send my request body as:
{
"phone": "0000000006",
"create_anonymous_account": null
}
or just like
{
"phone": "0000000006"
}
it sets createAnonymousAccount to false.
I have checked, and it correctly recognises "create_anonymous_account": true
Is there any way to "force" null value in boolean field?
I really need to know if it was sent or no, and not to have default value.
You can use Jackson annotation to ignore the null fields. If the Caller doesn't send createAnonymousAccount then it will be null.
#JsonInclude(JsonInclude.Include.NON_NULL)
public class ReqBody {
#NotNull
#Pattern(regexp = "^[0-9]{10}$")
private String phone;
//other fields
#JsonProperty(value = "create_anonymous_account")
private Boolean createAnonymousAccount ;
}

How to insert JSON object into database using spring boot and angularjs?

I am new to Spring boot so the question may sound silly. I want to insert a json object into database. But it is giving me an error like:
"Failed to evaluate Jackson deserialization for type".
On console, I am getting an error like:
Http 415 Unsupported Media type error with JSON
Here is my POJO class:
#Entity
#Table(name = "academics")
public class Academics {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#Column(name = "adhaarcard")
private String adhaarCard;
#Column(name = "grade")
private List grades;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAdhaarCard() {
return adhaarCard;
}
public void setAdhaarCard(String adhaarCard) {
this.adhaarCard = adhaarCard;
}
public List getGrades() {
return grades;
}
public void setGrades(List grades) {
this.grades = grades;
}
}
My controller function:
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> saveAvademics(#RequestBody Academics academics) {
academicsService.save(academics);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
.buildAndExpand(academics.getId()).toUri();
return ResponseEntity.created(location).build();
}
Angularjs Code:
$scope.saveAcademics = function() {
var adhaar = sessionStorage.getItem("emp-key");
var _data = {
"adhaarCard":adhaar,
"grades": {
"graduation":
{ "ssc": "SSC", "hsc": "HSC", "quOne": $scope.qone
},
"specialization":
{ 'ssc': "N.A", 'hsc': $scope.hscSpl, 'qoneSpl': $scope.qoneSpl},
"grade":
{ 'ssc': $scope.sscGrade, 'hsc': $scope.hscGrade, 'qoneGrade': $scope.qoneGrade},
"university":
{ 'ssc': $scope.sscUni, 'hsc': $scope.hscUni, 'qoneUni': $scope.qoneUni},
"year":
{ 'ssc': $scope.sscYear, 'hsc': $scope.hscYear, 'qoneYear': $scope.qoneYear}
}
};
console.log(_data);
$http({
url: 'saveacademics',
method: "POST",
data: JSON.stringify(_data)
})
.then(function(response) {
alert("Success");
},
function(response) { // optional
alert("Error Occoured.");
});
}
Try MediaType.APPLICATION_JSON instead on MediaType.APPLICATION_JSON_VALUE
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON)
MediaType.APPLICATION_JSON is a "public constant media type for application/json", whereas MediaType.APPLICATION_JSON_VALUE is a "String equivalent of MediaType.APPLICATION_JSON".
Json that you generate from angular js and your Java pojo are not matching.
Better you can reformat json as below
{ adhaarCard: "12", grades : [
{ university: "univ name", specialization: "sadd", grade: 83, graduation:"SSC", year: 2007 },
{ university: "univ name", specialization: "sadd", grade: 67, graduation:"HSC", year: 2009 }
]
}
And mapping PoJo class as
#Column(name = "adhaarcard")
private String adhaarCard;
#Column(name = "grade")
private List<Grades> grades ;
Grades.java
private String university;
private String specialization;
private int grade;
private Sting graduation;
private int year;
Add Column mapping and getter, setters.
Tip:
Instead of #RequestMapping you can use #PostMapping which is a shorthand. So you wont get confused with media type, it take application/json as default type.
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
replace with
#PostMapping("saveacademics")

using Swagger #ApiResponse responseContainer not working when code is 400

In Swagger Java API, when I use a responsecontainer="List" (Or "Set") with a code=400, I am not getting the model of the response on Swagger-GUI. I am just getting Array[Object].
Here is the concrete case:
#CrossOrigin
#RestController
#RequestMapping(value = "/api")
#Loggable(prepend = true, trim = false)
public class ConfigResource {
private final ConfigResourceDelegate delegate;
#Inject
public ConfigResource(final ConfigResourceDelegate delegate) {
this.delegate = delegate;
}
#RequestMapping(
value = "/v1/config",
method = PUT,
consumes = APPLICATION_JSON_UTF8_VALUE,
produces = APPLICATION_JSON_UTF8_VALUE
)
#ApiResponses(value = {#ApiResponse(code=202,message = "ACCEPTED" ),
#ApiResponse(code=200,response = Rejection.class, responseContainer
= "Set", message = "BAD_REQUEST"),
#ApiResponse(code=500, message = "INTERNAL_SERVER_ERROR")})
public ResponseEntity<?> putConfig(final #RequestBody ConfigDto
configDto){
return delegate.putConfig(riskConfigDto);
}
}
Here is the Rejection Class:
public class Rejection {
private Long id;
private RejectionDTO rejection;
private String originMessage;
public Rejection() {
}
public Long getId() {
return id;
}
public RejectionDTO getRejection() {
return rejection;
}
public String getOriginMessage() {
return originMessage;
}
public void setId(Long id) {
this.id = id;
}
public void setRejection(RejectionDTO rejection) {
this.rejection = rejection;
}
public void setOriginMessage(String originMessage) {
this.originMessage = originMessage;
}
}
So normally i'am supposed to have this model between [] in the swagger UI. However, I am getting Array[Object]:
See screen capture
To make your example work, you need to change your return value from wildcard, ResponseEntity<?>, to a concrete class, ResponseEntity<List<Rejection>>. Also, you need to change responseContainer to a List from Set.
#RequestMapping(
value = "/v1/config",
method = PUT,
consumes = APPLICATION_JSON_UTF8_VALUE,
produces = APPLICATION_JSON_UTF8_VALUE
)
#ApiResponses(value = {#ApiResponse(code=202,message = "ACCEPTED" ),
#ApiResponse(code=200,response = Rejection.class, responseContainer
= "List", message = "BAD_REQUEST"),
#ApiResponse(code=500, message = "INTERNAL_SERVER_ERROR")})
public ResponseEntity<List<Rejection>> putConfig(final #RequestBody ConfigDto
configDto){
return delegate.putConfig(riskConfigDto);
}

Correctly posting JSON data to restful webservice netbeans

I have created a restful webservice using the "generate web services from database option" in netbeans.
I have deployed this in wildfly and noticed that while GET requests work, POST requests do not.
Here is the part of my java code which accepts the POST connections:
#POST
#Override
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void create(XtgpsActivity entity) {
super.create(entity);
}
The create method takes a parameter of type XtgpsActivity. This is the XtgpsActivity class:
//packages and imports list removed
#Entity
#Table(name = "xtgps_Activity")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "XtgpsActivity.findAll", query = "SELECT x FROM XtgpsActivity x"),
#NamedQuery(name = "XtgpsActivity.findById", query = "SELECT x FROM XtgpsActivity x WHERE x.id = :id")})
public class XtgpsActivity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "Id")
private Integer id;
#JoinColumn(name = "BaseItemId", referencedColumnName = "Id")
#ManyToOne
private XtgpsBaseItem baseItemId;
#OneToMany(mappedBy = "activityId")
private Collection<XtgpsNearByActivity> xtgpsNearByActivityCollection;
public XtgpsActivity() {
}
public XtgpsActivity(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public XtgpsBaseItem getBaseItemId() {
return baseItemId;
}
public void setBaseItemId(XtgpsBaseItem baseItemId) {
this.baseItemId = baseItemId;
}
#XmlTransient
public Collection<XtgpsNearByActivity> getXtgpsNearByActivityCollection() {
return xtgpsNearByActivityCollection;
}
public void setXtgpsNearByActivityCollection(Collection<XtgpsNearByActivity> xtgpsNearByActivityCollection) {
this.xtgpsNearByActivityCollection = xtgpsNearByActivityCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof XtgpsActivity)) {
return false;
}
XtgpsActivity other = (XtgpsActivity) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "au.com.xitech.XtgpsActivity[ id=" + id + " ]";
}
}
This is the create method in the superclass:
public void create(T entity) {
getEntityManager().persist(entity);
}
Since the related table only has two columns id and baseitemid, and id is a primary key, I am sending my POST JSON data as this:
{"baseitemid":"2"}
However, when i post data in this format, I get an error:
http://localhost:8089/xxx/api/activity/ 400 (Bad Request)
I believe this is because of an issue with the JSON data I send. What is the correct way to create a JSON array for the post request?
PS: I have also attached my ajax call below. Note I did this after enabling CORS in the browser.
$('#submit_it').click(function(e) {
//console.log("submit button has been clicked");
e.preventDefault(); //cancel form submit
var jsObj = $post_example.serializeObject()
, ajaxObj = {};
//console.log(jsObj);
alert(JSON.stringify(jsObj));
ajaxObj = {
type: "POST",
url: "http://localhost:8089/xxx/api/activity/",
data: JSON.stringify(jsObj),
contentType:"application/json",
success: function(data) {
//console.log(data);
if(data[0].HTTP_CODE == 200) {
$('#div_ajaxResponse').text( data[0].MSG );
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Error " + jqXHR.getAllResponseHeaders() + " " + errorThrown);
},
complete: function(XMLHttpRequest) {
//console.log( XMLHttpRequest.getAllResponseHeaders() );
},
dataType: "json" //request JSON
};
$.ajax(ajaxObj);
});
The value passed in json is parsed as a numeric value, so sending as (without quotes for the value)
{
"baseitemid":2
}
worked.

How to define swagger annotation for json payload

how to define swagger annotation for this example post API.TenantConfiguration is getting as a json payload.
#Consumes({ "application/json", "application/xml" })
#POST
public Message configureSettings(TenantConfiguration configuration)
throws AndroidAgentException {
.....................
}
I found a solution to annotate json consuming Jax-rs Apis.It's working properly.
#POST
#ApiOperation(
consumes = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Configuring Android Platform Settings",
notes = "Configure the Android platform settings using this REST API"
)
#ApiResponses(value = {
#ApiResponse(code = 201, message = "Android platform configuration saved successfully"),
#ApiResponse(code = 500, message = "Internal Server Error")
})
Message configureSettings(#ApiParam(name = "configuration", value = "AndroidPlatformConfiguration")
TenantConfiguration configuration) throws AndroidAgentException;
Mapping class for the JSON object.
#XmlRootElement(
name = "tenantConfiguration"
)
#XmlAccessorType(XmlAccessType.NONE)
#ApiModel(
value = "TenantConfiguration",description = "This class carries all
information related to a Tenant configuration"
)
public class TenantConfiguration implements Serializable {
#XmlElement(
name = "type"
)
#ApiModelProperty(
name = "type",
value = "type of device",
required = true
)
private String type;
#ApiModelProperty(
name = "configuration",
value = "List of Configuration Entries",
required = true
)
#XmlElement(
name = "configuration"
)
private List<ConfigurationEntry> configuration;
public TenantConfiguration() {
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public List<ConfigurationEntry> getConfiguration() {
return this.configuration;
}
public void setConfiguration(List<ConfigurationEntry> configuration) {
this.configuration = configuration;
}
}

Categories

Resources