How to display class as a JSON response in Java? - java

Currently I'm working on spring project and I want to display class as a JSON response. Following is the class template and other related details.
public class Country {
#Column(name = "name")
private String name;
#Id
#Column(name = "code")
private String Code;
//Getters & Setters ...
}
current response :
[{"name":"Andorra","code":"AD"},{"name":"United Arab Emirates","code":"AE"}]
Expected response :
[ { "countries" : [{"name":"Andorra","code":"AD"},{"name":"United Arab Emirates","code":"AE"}], "status" : "ok", "message":"success", etc..etc...}]
instead of status and message, it could be some array list too.

You need create class contain list and use ResponseEntity.
public class Foo {
private List<Country> countries;
// get/set...
}
#Controller
public class MyController {
#ResponseBody
#RequestMapping(value = "/foo", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public ResponseEntity<Foo> foo() {
Foo foo = new Foo();
Country country = new Country();
foo.getCountries().add(country);
return ResponseEntity.ok(foo);
}
}

You should create another object, e.g. called Countries as shown below:
public class Countries {
private List<Country> countries;
// getters & setters
}
or:
public class Countries {
private Country[] countries;
// getters & setters
}
The list or array of Country objects will map to your expected {"countries" : [{"name":"Andorra","code":"AD"},{"name":"United Arab Emirates","code":"AE"}]}, because the JSON {} refers to some object and [] refers to list/array in Java code.

Actually you can also achieve using jackson library.
//Create obj of ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//Get the Json string value from the mapper
String json = mapper.writeValueAsString(obj)
And then return this json string in your controller method.
The advantage of using this is that, you can also ignore certain fields in the POJO for JSON conversion using #JsonIgnore annotation (Put this annotation before the getter of the field that you want to ignore) (Not sure if you can do the same from Spring ResponseEntity.
Note: Please correct me if I am wrong anywhere.

Related

Why #JsonInclude(JsonInclude.Include.NON_EMPTY) is not working?

I am trying to set null values to database of empty values from JSON payload. This problem caused beacause I have unique constraints on social entity fields.
I have request DTO that looks like:
#Value
#With
#Builder
#Jacksonized
public class AccountCreateRequest {
#NotBlank
String firstName;
String phone;
#Password
#NotBlank
String password;
#Email(message = "Email is not valid.")
#NotBlank
String email;
#NotBlank
String role;
SocialDto social;
}
Nested social DTO looks like
#Value
#Builder
#Jacksonized
public class SocialDto {
#JsonInclude(JsonInclude.Include.NON_EMPTY)
String telegramId;
#JsonInclude(JsonInclude.Include.NON_EMPTY)
String linkedinLink;
#JsonInclude(JsonInclude.Include.NON_EMPTY)
String githubLink;
}
Json example:
{
...fields...,
social: {
telegramId: "",
githubLink: "",
...
}
}
This JSON object is deserialized with social empty strings and doesn't ignore that values.
Moving annotation to the class level - didn't help for me.
How could I fix this problem?
#JsonInclude(JsonInclude.Include.NON_EMPTY) does not work for the intended purpose of treating empty strings as null on object deserialization. This annotation is for including fields in Object to JSON serialization.
You need to add a custom Deserializer like so: How to deserialize a blank JSON string value to null for java.lang.String?
In order to combine this with #Jacksonized, which already registers a #JsonDeserialize(using = x.class) on the class level, you can do the following:
public class JsonStringDeserializer extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.readValueAsTree();
String nodeText = node.asText();
// todo: isBlank or isEmpty depending on your needs
if (nodeText.isBlank()) {
return null;
}
return nodeText;
}
}
and parse the JSON object with the following code:
SimpleModule stringModule = new SimpleModule();
stringModule.addDeserializer(String.class, new JsonStringDeserializer());
ObjectMapper jsonObjectMapper = new ObjectMapper();
jsonObjectMapper.registerModule(stringModule);
jsonObjectMapper.readValue(input, modelClass);
Or you can add #JsonDeserialize(using = JsonStringDeserializer.class) on every String field that needs it if you don't control the ObjectMapper.

Convert Java object list to entity list

I have multiple objects in my array using . If I then send this to my Spring Boot backend with axios and output the FormData beforehand, I get the following image. That fits. In the backend, however, I need this list of objects as an entity. In this case, of type List. Do I do that?
Frontend code:
let data = new FormData();
...
data.append("zugeordnet", JSON.stringify(personNamen));
await axios.post("/neuerEintrag", data,...)
React:
Backend:
#PostMapping("/neuerEintrag")
public String neuerEintrag(HttpServletRequest req,#RequestParam("zugeordnet") List<?> zugeordnet,..) {
List<User> userListe = (List<User>) zugeordnet;
for(User inListe : userListe) //ERROR here
{
System.out.println("USER :" + inListe);
}
...
}
java.lang.ClassCastException: class java.lang.String cannot be cast to class com.home.calendar.User.User
UPDATE
For completeness, here is the user entity and the complete method for a new entry.
#PostMapping("/neuerEintrag")
public String neuerEintrag(HttpServletRequest req, #RequestParam("beschreibung") String beschreibung,
#RequestParam("datum") Date datum, #RequestBody List<User> zugeordnet,
#RequestBody List<Freunde> kontaktAuswahl, #RequestParam("neuAlt") String neuAlt,
#RequestParam("kalenderId") int kalenderId) { }
The User Entity:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
#JsonIgnoreProperties("user")
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "user")
private List<Kalender> kalenderEinträge;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, List<Kalender> kalenderEinträge) {
super();
this.name = name;
this.kalenderEinträge = kalenderEinträge;
}
public List<Kalender> getKalenderEinträge() {
return kalenderEinträge;
}
[getter/setter]
Spring can't parse an unknown object.
To get it work, I suggest a new class for the "request".
#Data // lombok - this generates getter/setters/equals/hashcode for you
public class NeuerEintragRequest {
private List<User> zugeordnet;
private String beschreibung;
private int kalendarId;
// and your others fields
}
The controller can now use very type-safe objects.
#PostMapping("/neuerEintrag")
public String neuerEintrag(#RequestBody NeuerEintragRequest request) {
for(User user : request.getUserlist()) {
// a logging framework is a lot better. Try to use log4j or slf4j.
log.info("USER: {}", user);
}
...
}
Typescript
Let axios handle the typing and serializing. See this tutorial: https://masteringjs.io/tutorials/axios/post-json
To post all the needed data, you can create a new object.
// no formdata - just send the object
const data = { zugeordnet: personNamen, kalendarId: 123, beschreibung: 'abc' };
await axios.post("/neuerEintrag", data);
You can also create a interface in typescript, but this is going to much for a stackoverflow-answer. Try to learn more about spring and typescript.
Based on question & comments ,
your front end call data.append("zugeordnet", JSON.stringify(personNamen)); is converting your object to List<String> instead of List<User>.
So you can transform this List<String> to List<User> in your postMapping:
#PostMapping("/neuerEintrag")
public String neuerEintrag(HttpServletRequest req,#RequestParam("zugeordnet") List<?> zugeordnet,..) {
ObjectMapper mapper=new ObjectMapper();
for(String str:zugeordnet){
System.out.println(mapper.readValue(str, User.class));
}
...
}

Ignore json POJO fields not mapped in object in spring boot

I have pojo which has many fields. I have set value some field. But when i create json, whole pojo create a json . here is the code i have used:
Pojo
public class BasicInfoModel {
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
Repository code
public BasicInfoModel getBasicInfo() {
BasicInfoModel lm = new BasicInfoModel();
lm.setFather_name("Enamul Haque");
return lm;
}
Controller code
#RequestMapping(value = "/get_donar_basic_info", method = RequestMethod.POST, produces ="application/json")
public #ResponseBody BasicInfoModel getBasicinfo(){
return repository.getBasicInfo();
}
But my json is resposne like bellow:
{
"client_id": "",
"father_name": "Enamul Haque",
"mother_name": "",
"gendar": ""
}
I have set value to father_name but i have seen that i have found all the value of pojo fields. I want get only set value of father_name and ignor other value which is not set in repository.
My json look like bellow: I will display only father_name.how to display bellow like json from above code?
{
"father_name": "Enamul Haque"
}
Please help me..
Json include non null values to ignore null fields when serializing a java class
#JsonInclude(Include.NON_NULL)
Jackson allows controlling this behavior at either the class level:
#JsonInclude(Include.NON_NULL)
public class BasicInfoModel { ... }
at the field level:
public class BasicInfoModel {
private String client_id="";
#JsonInclude(Include.NON_NULL)
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
from jackson 2.0 use here use
#JsonInclude(JsonInclude.Include.NON_NULL)
You can also ignore the empty values
#JsonInclude(JsonInclude.Include.NON_EMPTY)
Add the #JsonIgnoreProperties("fieldname") annotation to your POJO.
Or you can use #JsonIgnore before the name of the field you want to ignore while deserializing JSON. Example:
#JsonIgnore
#JsonProperty(value = "client_id")
#RequestMapping(value = "/get_donar_basic_info", method = RequestMethod.POST, produces ="application/json")
public #ResponseBody BasicInfoModel getBasicinfo(){
return repository.getBasicInfo();
}
You can ignore field at class level by using #JsonIgnoreProperties annotation and specifying the fields by name:
#JsonIgnoreProperties(value = { "client_id" })
public class BasicInfoModel {
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
Or you can use #JsonIgnore annotation directly on the field.
public class BasicInfoModel {
#JsonIgnore
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
You can read here more about this.

Trouble reading JSON from URL to java objects / storing in mysql db

I'm a newbie coder having just finished a 6 month coding crash-course. I'm working on a java webapp to demonstrate my skills, and the project idea I had involves retrieving JSON data from an API, something we didn't learn about in class. I made POJOs to match the JSON, and I'm trying to parse the JSON into java objects to store in a database, however my database tables are never filled with data when I run through the app. I suspect the problem is somewhere with my method to convert the JSON but any feedback is greatly appreciated. Here's all my code I think is relevant, sorry if its TMI. I also apologize if my code is ugly, I'm a beginner... Thanks!
API returns JSON like this:
{
"result":{
"status":1,
"num_results":1,
"total_results":500,
"results_remaining":499,
"matches":[{
"match_id":3188095188,
"match_seq_num":2784956606,
"start_time":1495079320,
"lobby_type":7,
"radiant_team_id":0,
"dire_team_id":0,
"players":[{
"account_id":86920222,
"player_slot":0,
"hero_id":18
},{
"account_id":61122568,
"player_slot":1,
"hero_id":85
},{
"account_id":10208661,
"player_slot":2,
"hero_id":13
},{
"account_id":106083675,
"player_slot":132,
"hero_id":50
}]
}]
}
}
My POJOs:
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Result {
#JsonIgnore
#Id
#GeneratedValue
private int id;
#JsonProperty("status")
private int status;
#JsonProperty("num_results")
private int num_results;
#JsonProperty("total_results")
private int total_results;
#JsonProperty("results_remaining")
private int results_remaining;
#OneToMany
#JoinColumn(name = "result_id")
#ElementCollection(targetClass=Matches.class)
#JsonProperty("matches")
private List<Matches> matches;
// getters and setters
}
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Matches {
#Id
#JsonProperty("match_id")
private int match_id;
#JsonIgnore
#ManyToOne
private Result result;
#JsonProperty("match_seq_num")
private int match_seq_num;
#JsonProperty("start_time")
private int start_time;
#JsonProperty("lobby_type")
private int lobby_type;
#JsonProperty("radiant_team_id")
private int radiant_team_id;
#JsonProperty("dire_team_id")
private int dire_team_id;
#OneToMany
#JoinColumn(name = "Matches_id")
#ElementCollection(targetClass=Players.class)
#JsonProperty("players")
private List<Players> players;
// getters and setters
}
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Players {
#JsonIgnore
#Id
#GeneratedValue
private int id;
#JsonIgnore
#ManyToOne
private Matches matches;
#JsonProperty("account_id")
private int account_id;
#JsonProperty("player_slot")
private int player_slot;
#JsonProperty("hero_id")
private int hero_id;
// getters and setters
}
Services method to read and convert the JSON to objects (url is censored, don't want my API key to be public)
public class SteamService {
public static Result getMatchHistory(String steamid){
Result result = new Result();
String MatchHistoryUrl = "https:**URL**="+steamid;
RestTemplate restTemplate = new RestTemplate();
Result jsonresult = restTemplate.getForObject(MatchHistoryUrl, Result.class);
return jsonresult;
}
}
Controller
#Controller
#RequestMapping("")
public class HomeController {
#Autowired
private ResultsDao resultsDao;
#RequestMapping(value = "", method = RequestMethod.GET)
public String index(Model model){
model.addAttribute("title", "Welcome");
return "home/home";
}
#RequestMapping(value = "", method = RequestMethod.POST)
public String processSteamIdField(#RequestParam("steamid")String steamid, Model model) {
Result newresult = getMatchHistory(steamid);
resultsDao.save(newresult);
return "redirect:results";
}
}
DAO
#Repository
#Transactional
public interface ResultsDao extends CrudRepository<Result, Integer>{
}
Maybe my approach is a bit naive, but... If you want to store the JSON as string in the database, then I would use an object mapper for this:
new ObjectMapper().writeValueAsString(myObject);
and for reading a JSON and parsing it to a class I would do:
new ObjectMapper().readValue(JSON_STRING_HERE, "utf-8"), MyPOJO.class);
Also, if you already are using Spring, then your controller may look like this (for a POST, for example)
#RequestMapping(value = "/", method = RequestMethod.POST)
public MyPojo myController(#RequestBody MyPojo myBody) {
myRepository.save(myBody);
}
So, the parsing of the JSON that the client is sending to your app and your controller is already handled by Spring

Parsing json object into a string

I have a question regarding a web-application I'm building where I have a REST service receiving a json string.
The Json string is something like:
{
"string" : "value",
"string" : "value",
"object" : {
"string" : "value",
"string" : "value",
....
}
}
I'm using resteasy to parse the json string which uses jackson underneath. I have a jaxb annotated class and I want to parse the "object" entirely into a String variable. The reason I want to do this is to be able to parse the json later using the correct parser (it depends on the application that sends the request so it is impossible to know in advance).
My jaxb annotated class looks like this:
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
public class Test{
#XmlElement(type = String.class)
private String object;
//getter and setter
...
}
When I execute the rest call and let jackson parse this code I get an
Can not deserialize instance of java.lang.String out of START_OBJECT token
error. So actually I'm trying to parse a piece of a json string, which is a json object, into a String. I can't seem to find someone with a similar problem.
Thanks in advance for any response.
java.lang.String out of START_OBJECT token
this means that expected character after "object" is quotes ", but not brackets {.
Expected json
"object" : "my object"
Actual json
"object" : { ...
=======
If you want parse json like in your example, then change your class. E.g.
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
public class Test{
#XmlElement
private InnerTest object;
//getter and setter
...
}
#XmlAccessorType(XmlAccessType.PROPERTY)
public class InnerTest{
#XmlElement
private String string;
//getter and setter
...
}
If I understand this question you just want a mechnanism, that converts a Java-Object into a JSON-String and the other way.
I needed this as well, while I was using a WebSocket Client-Server communication where a JSON String has been passed around.
For this I used GSON (see GSON). There you got the possibility to create a complete JSON-String.
Here some example:
// Converts a object into a JSON-String
public String convertMyClassObjectToJsonFormat() {
MyClass myObject = new MyClass();
Gson gson = new Gson();
return gson.toJson(myObject);
}
//Converts a JSON-String into a Java-Class-Object
public MyClass convertJsonToMyClassObject(
CharBuffer jsonMessage) {
Gson gson = new Gson();
return gson.fromJson(jsonMessage.toString(),
MyClass.class);
}
What you need is, that you your Class-Attributes-setter and JSON-Attribute-names are equivalent. E.g.
{
"info":[
{
"name": "Adam",
"address": "Park Street"
}
]
}
Your Class should look like this:
public class Info{
private String name;
private String address;
public void setName(String name){
this.name = name;
}
public void setAddress(String address){
this.address = address;
}
}
#KwintenP Try using the json smart library.
You can then simply retrieve the JSON object first using:
JSONObject test = (JSONObject) JSONValue.parse(yourJSONObject);
String TestString = test.toString();
What's more, you can retrieve a specific object inside a JSON object may it be another object, an array and convert it to a String or manipulate the way you want.
you also can do something like this ;
public class LeaderboardView
{
#NotEmpty
#JsonProperty
private String appId;
#NotEmpty
#JsonProperty
private String userId;
#JsonProperty
private String name = "";
#JsonProperty
private String imagePath = "";
#NotEmpty
#JsonIgnore
private String rank = "";
#NotEmpty
#JsonProperty
private String score;
public LeaderboardView()
{
// Jackson deserialization
}
}

Categories

Resources