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")
Related
I am getting the JSON from frontend angular to API and trying to convert array of string to list of string in controller :
GET : http://localhost:8080/rest/v1/health/getValues
{
"page" : 2,
"size" : 10,
"assignedTo" : [ "user1#example.com", "user2#example.com" ],
"status" : ["abc","def"]
}
I am trying to convert first into List in following way but unable to access it in #Rest:
public class SearchDTO {
#JsonProperty("page")
public int page;
#JsonProperty("size")
public int size;
#JsonFormat(shape = JsonFormat.Shape.ARRAY)
#Getter
#Setter
class AssignedTo {
private String assignedTo;
#JsonCreator
public AssignedTo(#JsonProperty("assignedTo") String assignedTo) {
this.assignedTo = assignedTo;
}
}
#JsonFormat(shape= JsonFormat.Shape.ARRAY)
#Getter
#Setter
class Status {
private String status;
#JsonCreator
public Status(#JsonProperty("status") String status) {
this.status = status;
}
}
#JsonFormat(shape= JsonFormat.Shape.ARRAY)
#Getter
#Setter
class LogType {
private String logType;
#JsonCreator
public LogType(#JsonProperty("logType") String logType) {
this.logType = logType;
}
}
}
I am unable to access same in the #RestController Class
#PostMapping(path = "getValue", consumes = "application/json", produces = "application/json")
public ResponseEntity<ListDTO> getAll(#RequestBody SearchDTO searchMapping ){
return ResponseEntity.ok(logPageSearchService.getLogs(searchMapping.page,
logSearchMapping.size,// other variables here
));
}
Use simple dto class remove json tag it will work
#RestController
class DemoController {
#PostMapping(path = "/getValue", consumes = "application/json", produces = "application/json")
public ResponseEntity<SearchDTO> getAll(#RequestBody SearchDTO searchMapping ){
return ResponseEntity.ok(searchMapping);
}
}
class SearchDTO {
public int page;
public int size;
public String[] assignedTo;
public String[] status;
// getters / setters
}
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?
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);
}
How to send array to spring rest? I tried the following but didn't work
javascript:
function postTopic(){
self.data.blogTopicsArr.push({
options: {
"title": self.title.value,
"details": self.topicDetails.value,
"username": "Guest user",
"userImage": "assets/img/spiritual-icon4.png",
"day_posted": new Date().toLocaleString()
}
});
$.ajax({
url: "/new_topic",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(self.data.blogTopicsArr),
success: function (res) {
},
error: function (err) {
}
});
}
Topic Bean class:
#Entity
#Table(name = "topics")
public class TopicBean implements Serializable {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "title")
private String title;
#Column(name = "details")
private String details;
#Column(name = "username")
private String username;
#Column(name = "userImage")
private String userImage;
#Column(name = "day_posted")
private Date day_posted;
//Getters and Setters
}
Spring rest:
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List[] topics) throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.add("success", "topic added");
return new ResponseEntity(headers, HttpStatus.OK);
}
I get error: {"statusCode":400,"body":{"timestamp":1484506636823,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Required request body is missing: public org.springframework.http.ResponseEntity seconds47.restAPI.Topics.new_topic(java.util.List[]) throws java.lang.Exception","path":"/new_topic"}}}
How do I solve this?
Update: added topic bean class above with fields I am using in that class
Try using
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List<HashMap<String, Object>> topics) throws Exception
And print out any input from topics. If you do get any values, you need to replace it with
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List<Topic> topics) throws Exception
with the relevant structure of the Topic class.
public class Topic{
OptionsBean options;
...
//getters and setters
...
}
public class OptionsBean{
String title;
String details;
String username;
String userImage;
String day_posted;
...
//getters and setters
...
}
function postTopic(){
var topic = {
"title": self.title.value,
"details": self.topicDetails.value,
"username": "Guest user",
"userImage": "assets/img/spiritual-icon4.png",
"day_posted": new Date().toLocaleString()
};
$.ajax({
url: "/new_topic",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: topic,
success: function (res) {
},
error: function (err) {
}
});
}
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody TopicBean topic) throws Exception {
//... do whatever with the new topic
HttpHeaders headers = new HttpHeaders();
headers.add("success", "topic added");
return new ResponseEntity(headers, HttpStatus.OK);
}
topic and TopicBean must have the same members and must be of same type.
I am having a problem marshalling a RequestBody when the parent class has a namespace.
Class:
#XmlRootElement(name = "blah")
public class Test {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
XML:
<blah>
<id>23333</id>
</blah>
Code:
#RequestMapping( value = "/blah", method = RequestMethod.POST, consumes = { MediaType.TEXT_XML_VALUE }, produces = { MediaType.TEXT_XML_VALUE})
public String getBlah( #RequestBody Test request ) throws Exception
{
assert(null != request.getId());
return "blah";
}
This works fine. However, if I use #XmlRootElement(name = "blah", namespace="home") on the class, and <blah xmlns="home"> in the request, the Test class constructs, but it's ID value is never set.
I'm at a loss.
Before public void setId method add annotation #XmlElement