I have a #restController type controller, when I access a resource for a request I get a json as a response, the problem is that all attributes appear to me and it does not respect the constructors I have generated.
However, all the attributes of the class always appear to me:
{
"code":0,
"message":"ERROR",
"details":null
}
And I would like the answer to be like this:
{
"code":0,
"message":"ERROR"
}
I appreciate your help
#RestController
#RequestMapping("/api")
public class WsController implements WsInterface{
#Override
#PostMapping("/add")
public Response add(#RequestBody Person person) {
Response r= =null;
if(person.getName().equals("A")){
r= new Response(1,"OK","Details of person");
}else{
r= new Response (0,"ERROR");
}
return r;
}
}
public class Response{
private int code;
private String message;
private String details;
public Response() {
}
public Response(int code, String message, String details) {
this.code = code;
this.message = message;
this.details = details;
}
public Response(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
If you want to use same object in both cases with null details and without. You can try to configure json serialization accordingly.Spring by default use Jackson and you can configure object mapper directly or use annotation #JsonInclude(Include.NOT_NULL) on model class to include only not null values.
Related
I have an API method implemented in spring boot for Courses. It fetches the course by topic Id. The Course class is implemented as:
#Entity
public class Course {
#Id
private String id;
private String name;
private String description;
#ManyToOne
private Topic topic;
public Course() {
}
public Course(String id, String name, String description, String topicId) {
super();
this.id = id;
this.name = name;
this.description = description;
this.topic = new Topic(topicId, "", "");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setTopic(Topic t) {
this.topic = t;
}
}
And the API method is implemented as:
#RequestMapping(method=RequestMethod.GET, value="/topics/{topicId}/courses")
public RestMessage getAllCourses(#PathVariable String topicId) {
try {
List<Course> course = courseService.getAllCourses(topicId);
message = new RestMessage(course,StatusCodeEnum.OK);
return message;
} catch (Exception e) {
message = new RestMessage(e.getMessage(),StatusCodeEnum.INTERNAL_SERVER_ERROR);
message.setException(e);
return message;
}
}
The method implementation is simple, it tries to get all the courses based on the topic id and return it as a RestMessage Object. I'm using postman for the testing and in the response I am getting the list of Course but the Topic entity data is discarded.
The api response is as:
{
"data": [
{
"id": "java-streams",
"name": "Java Streams",
"description": "Java Stream learning"
}
],
"httpStatus": "OK",
"statusCode": 200,
"exception": null
}
And the RestMessage Class is defined as:
public class RestMessage {
private Object data;
private StatusCodeEnum httpStatus;
private int statusCode;
private Exception ex;
public RestMessage() {
}
public RestMessage(Object d, StatusCodeEnum c) {
data = d;
httpStatus = c;
statusCode = c.val();
}
public void setData(Object d) {
data =d;
}
public void setHttpStatus(StatusCodeEnum c) {
httpStatus = c;
}
public void setStatusCode(int c) {
statusCode = c;
}
public void setException(Exception e) {
ex = e;
}
public void setStatusCode(StatusCodeEnum c) {
httpStatus = c;
}
public Object getData() {
return data;
}
public StatusCodeEnum getHttpStatus() {
return httpStatus;
}
public Exception getException() {
return ex;
}
public int getStatusCode() {
return statusCode;
}
}
However, I have tried to debug the API endpoint and before returning the RestMessage object I have data in the required shape but after getting the json response the Topic object is truncated for all the courses.
The debug data image is attached:
I wonder what I am doing wrong in this case?
The field topic from Course doesn't have a getter, that's why is ignored by JSON serializer.
You can use Lombok annotation to automatically generate getters and setters.
Just add #Dataon class definition and you will have generated getters and setters, constructor without parameters. You will have everything for what you can said that is POJO class.
Check this link: Project lombok
Currently I have this model class to collect data from firebase database. To show the data I am using firebaserecycleradapter.
News.class
public class News {
private String message, author, thumb_author, type;
private Long timestamp;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getThumb_author() {
return thumb_author;
}
public void setThumb_author(String thumb_author) {
this.thumb_author = thumb_author;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}
But the problem is there is another child named images that consist of pushId and an Object. This is how it looks
news {
message:"value"
author:"value"
thumb_author:"value"
type:"value"
timestamp:"value"
images {
pushId01:"value"
pushId02:"value"
pushId03:"value"
pushId04:"value"
pushId05:"value"
}
}
So my question is how can I add the image child to the news.class or is there any possible solution for this? My possible solution for this is to get the image child data inside the onBindViewHolder using databasereference.
Add a property to represent the images node. Since these are simple string key/value pairs, you can represent it with a Map<String,String>. So:
public class News {
private String message, author, thumb_author, type;
private Long timestamp;
public Map<String,String> images; // this is a new field for the images
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
...
Iam trying to get Status and message tag info using java 1.7
Please any guide me ,
Thanks in advance
<API version="0.0">
<response>
<operation name="ADD">
<result>
<statuscode>200</statuscode>
<status>Success</status>
<message> successfully</message>
</result>
<Details type="ADD"/>
</operation>
</response>
</API>
This is not a JSON response that you are getting, it's an XML response,
you just need to convert the XML response to POJO class and use the POJO class instead.
Here is how the POJO class will look like
public class MyPojo{
private API API;
public API getAPI() {
return API;
}
public void setAPI(API API) {
this.API = API;
}
}
now MyPojo will contain another class named API
public class API {
private Response response;
private String version;
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
now the API class contains another class called Response
public class Response {
private Operation operation;
public Operation getOperation() {
return operation;
}
public void setOperation(Operation operation) {
this.operation = operation;
}
}
Now the Response class is containing another class called Operation
public class Operation {
private Result result;
private Details Details;
private String name;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
public Details getDetails() {
return Details;
}
public void setDetails(Details Details) {
this.Details = Details;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now you guessed it the Operation class is containing two classes Details and Result
Here is the Result class that is containing the status and message you want to access
public class Result {
private String message;
private String status;
private int statuscode;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getStatuscode() {
return statuscode;
}
public void setStatuscode(int statuscode) {
this.statuscode = statuscode;
}
}
Here is the Details class
public class Details {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
finally, you can access the status and message by creating an object from MyPojo class like this:
String message = myPojo.getAPI().getResponse().getOperation().getResult().getMessage();
String status = myPojo.getAPI().getResponse().getOperation().getResult().getStatus();
you can use this online converter to convert XML/JSON to POJO.
I hope my answer was helpful :)
I am using Jackson in Java to return a JSON response from a REST endpoint. This is an example response that is generated:
{"StatusCode":{"#statusCode":"OK"},"SomeElements":null}
Questions:
Why is Jackson adding the # in?
How can I stop it from adding it?
Note: This question is different from this in the sense that I want to know WHY Jackson is adding it and also how to prevent it from doing so as it can cause issues in the systems it is passing the response to.
EDIT:
Here's the sanitized code:
public enum StatusCodeType {
OK, WARNING, ERROR
}
#XmlType(name = "StatusResponse", namespace = "http://www.w3.org/2001/XMLSchema/<obfuscated>", propOrder = {"statusCode", "message"})
#XmlAccessorType(XmlAccessType.FIELD)
public class StatusResponse {
#XmlAttribute(name = "statusCode", required = true)
private StatusCodeType statusCode;
#XmlAttribute(name = "message")
private String message;
public StatusResponse(final StatusCodeType statusCode, final String message) {
this.statusCode = statusCode;
this.message = message;
}
public StatusResponse(final StatusCodeType statusCode) {
this.statusCode = statusCode;
}
public StatusResponse() {
}
public StatusCodeType getStatusCode() {
return statusCode;
}
public void setStatusCode(StatusCodeType statusCode) {
this.statusCode = statusCode;
}
public void setMessage(String message) {
this.message = message;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
public abstract class SomeResponse {
#XmlElement(name = "StatusCode", required = true)
private StatusResponse statusResponse;
public StatusResponse getStatusResponse() {
return statusResponse;
}
public void setStatusResponse(StatusResponse statusResponse) {
this.statusResponse = statusResponse;
}
}
#XmlRootElement(name = "XmlResponse", namespace = "http://www.w3.org/2001/XMLSchema/<obfuscated>")
public class XmlResponse extends SomeResponse {
#XmlElement(name = "SomeElement")
#XmlElementWrapper(name = "SomeElements", required = true)
private List<SomeElement> someElements;
public List<SomeElement> getSomeElements() {
return someElements;
}
public void setSomeElements(List<SomeElement> someElements) {
this.someElements = someElements;
}
}
#Path("/getAll")
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getAll(#QueryParam("firstParam") String firstParam, #QueryParam("secondParam") String secondParam) {
...
final XmlResponse resp = processToXmlResponse(someObject);
return Response.ok().entity(resp).build();
}
You probably have jettison on your classpath and it's provider is used for serialization instead of jackson.
By default Jettison will prefix properties mapped to attributes with '#'.
See https://github.com/FasterXML/jackson-core/issues/114.
Here is my JAXB class,
#XmlRootElement
public class Status {
private int code;
private String message;
public Status() {
}
public Status(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
I dont want the 'code' to be marshalled to XML. Here are the things I tried, but it always marshalled to XML.
Annotate #XMLElement to only getMessage() method
Make 'code' as transient
No hopes yet. The XMLAccessorType.NONE can be applied to class level. Not in element level. Please help.
Add #XmlTransient annotation before the getter methods of the attributes you don't want to be marshalled.
Ex:
#XmlTransient
public int getCode() {
return code;
}