im receiving this json as response from an rest server:
{
"externalOrderId":"5cb9bc46-aaa3-43ff-bb1a-6b17443f63ea",
"shortId":null,
"createdAt":1442255497402,
"updatedAt":1442255497402,
"cart":{
"id":"gy4ectxb3db84epljzhisqrf"
}
}
Then, when i try to parse this json using gson.fromJson, i got the error:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 201 path $.createdAt
here is the how im doing it:
public Order getOrder(String externalOrderId) throws Exception {
HttpRequest request = new HttpRequestBuilder()
.setUrl(new URI(baseURL + "/order/" + externalOrderId))
.build();
return gson.fromJson(HttpResource.getInstance().get(request).getBody(), new TypeToken<Order>(){}.getType());
}
The Order object:
private String externalOrderId;
private Long shortId;
private Date createdAt;
private Date updatedAt;
Thanks in advance.
Your createdAt and updatedAt fields are Date objects, whereas the JSON data has numbers. To be able to match against the numbers, you'll need to have createdAt and updatedAt also be Longs and the convert them to Date objects later.
Try This (See toString and longToDate metods in Order.java) -
Cart.java
public class Cart {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Override
public String toString() {
return "Cart [id=" + id + "]";
}
}
Order.java
import java.util.Date;
public class Order {
private String externalOrderId;
private Long shortId;
private Long createdAt;
private Long updatedAt;
private Cart cart;
public String getExternalOrderId() {
return externalOrderId;
}
public void setExternalOrderId(String externalOrderId) {
this.externalOrderId = externalOrderId;
}
public Long getShortId() {
return shortId;
}
public void setShortId(Long shortId) {
this.shortId = shortId;
}
public Long getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Long createdAt) {
this.createdAt = createdAt;
}
public Long getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Long updatedAt) {
this.updatedAt = updatedAt;
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
private Date longToDate(Long dt) {
return new Date(dt);
}
#Override
public String toString() {
return "Order [externalOrderId=" + externalOrderId + ", shortId="
+ shortId + ", createdAt=" + longToDate(createdAt) + ", updatedAt="
+ longToDate(updatedAt) + ", cart=" + cart + "]";
}
}
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Order;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
public static void main(String[] args) {
String j = "{\"externalOrderId\":\"5cb9bc46-aaa3-43ff-bb1a-6b17443f63ea\",\"shortId\":null,\"createdAt\":1442255497402,\"updatedAt\":1442255497402,\"cart\":{\"id\":\"gy4ectxb3db84epljzhisqrf\"}}";
Order r = gson.fromJson(j, Order.class);
System.out.println(r);
}
}
Result
Order [externalOrderId=5cb9bc46-aaa3-43ff-bb1a-6b17443f63ea, shortId=null, createdAt=Tue Sep 15 00:01:37 IST 2015, updatedAt=Tue Sep 15 00:01:37 IST 2015, cart=Cart [id=gy4ectxb3db84epljzhisqrf]]
Related
im getting this error idk why
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='client'. Error count: 1
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'client' on field 'image': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile#42df4d2d]; codes [typeMismatch.client.image,typeMismatch.image,typeMismatch.[B,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [client.image,image]; arguments []; default message [image]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte[]' for property 'image'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte' for property 'image[0]': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned inappropriate value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile']
Entity :
#Entity
#Table(name = "Client")
public class Client implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="idClient")
private Long idClient;
#Column(name="nom")
private String nomClient;
#Column(name="prenom")
private String prenomClient;
#Column(name="datedenaissance")
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date datedenaissanceClient;
#Column(name="typepiece")
private String typepieceClient;
#Column(name="numeropiece")
private int numeropieceClient;
#Column(name="numerotel")
private Long numerotelClient;
#Column(name="email")
private String emailClient;
#Column(name="adresse")
private String adresseClient;
#Column(name="rendezvous")
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date rendezvous;
#Column(name="temps")
#DateTimeFormat(pattern = "hh:mm")
#Temporal(TemporalType.TIME)
private Date temps;
#Column(name="tempsfin")
#DateTimeFormat(pattern = "hh:mm")
#Temporal(TemporalType.TIME)
private Date tempsfin;
#OneToMany(cascade = CascadeType.ALL, mappedBy="clients")
private List<Compte> comptes;
#Lob
#Column(name="image")
private byte[] image;
public static long getSerialversionuid() {
return serialVersionUID;
}
public Long getIdClient() {
return idClient;
}
public void setIdClient(Long idClient) {
this.idClient = idClient;
}
public String getNomClient() {
return nomClient;
}
public void setNomClient(String nomClient) {
this.nomClient = nomClient;
}
public String getPrenomClient() {
return prenomClient;
}
public void setPrenomClient(String prenomClient) {
this.prenomClient = prenomClient;
}
public Date getDatedenaissanceClient() {
return datedenaissanceClient;
}
public void setDatedenaissanceClient(Date datedenaissanceClient) {
this.datedenaissanceClient = datedenaissanceClient;
}
public String getTypepieceClient() {
return typepieceClient;
}
public void setTypepieceClient(String typepieceClient) {
this.typepieceClient = typepieceClient;
}
public Date getTempsfin() {
return tempsfin;
}
public void setTempsfin(Date tempsfin) {
this.tempsfin = tempsfin;
}
public int getNumeropieceClient() {
return numeropieceClient;
}
public void setNumeropieceClient(int numeropieceClient) {
this.numeropieceClient = numeropieceClient;
}
public Long getNumerotelClient() {
return numerotelClient;
}
public void setNumerotelClient(Long numerotelClient) {
this.numerotelClient = numerotelClient;
}
public String getEmailClient() {
return emailClient;
}
public void setEmailClient(String emailClient) {
this.emailClient = emailClient;
}
public String getAdresseClient() {
return adresseClient;
}
public void setAdresseClient(String adresseClient) {
this.adresseClient = adresseClient;
}
public Date getRendezvous() {
return rendezvous;
}
public void setRendezvous(Date rendezvous) {
this.rendezvous = rendezvous;
}
public Date getTemps() {
return temps;
}
public void setTemps(Date temps) {
this.temps = temps;
}
public List<Compte> getComptes() {
return comptes;
}
public void setComptes(List<Compte> comptes) {
this.comptes = comptes;
}
public Client(Long idClient, String nomClient, String prenomClient, Date datedenaissanceClient,
String typepieceClient, int numeropieceClient, Long numerotelClient, String emailClient,
String adresseClient, Date rendezvous, Date temps, Date tempsfin, List<Compte> comptes, byte[] image) {
super();
this.idClient = idClient;
this.nomClient = nomClient;
this.prenomClient = prenomClient;
this.datedenaissanceClient = datedenaissanceClient;
this.typepieceClient = typepieceClient;
this.numeropieceClient = numeropieceClient;
this.numerotelClient = numerotelClient;
this.emailClient = emailClient;
this.adresseClient = adresseClient;
this.rendezvous = rendezvous;
this.temps = temps;
this.tempsfin = tempsfin;
this.comptes = comptes;
this.image = image;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
#Override
public String toString() {
return "Client [idClient=" + idClient + ", nomClient=" + nomClient + ", prenomClient=" +
prenomClient
+ ", datedenaissanceClient=" + datedenaissanceClient + ", typepieceClient=" +
typepieceClient
+ ", numeropieceClient=" + numeropieceClient + ", numerotelClient=" + numerotelClient +
", emailClient="
+ emailClient + ", adresseClient=" + adresseClient + ", rendezvous=" + rendezvous + ",
temps=" + temps
+ ", tempsfin=" + tempsfin + ", comptes=" + comptes + ", image=" + Arrays.toString(image)
+ "]";
}
public Client() {
super();
// TODO Auto-generated constructor stub
}
public Client(Long idClient, String nomClient, String prenomClient, Date datedenaissanceClient,
String typepieceClient, int numeropieceClient, Long numerotelClient, String emailClient,
String adresseClient, Date rendezvous, Date temps, List<Compte> comptes) {
super();
this.idClient = idClient;
this.nomClient = nomClient;
this.prenomClient = prenomClient;
this.datedenaissanceClient = datedenaissanceClient;
this.typepieceClient = typepieceClient;
this.numeropieceClient = numeropieceClient;
this.numerotelClient = numerotelClient;
this.emailClient = emailClient;
this.adresseClient = adresseClient;
this.rendezvous = rendezvous;
this.temps = temps;
this.comptes = comptes;
}
}
Service :
#Override
public void addClient(Client client){
// TODO Auto-generated method stub
this.clientRepository.save(client);
}
Controller :
#RequestMapping(value = { "/saveClient" }, method = RequestMethod.POST, consumes = {"multipart/form-data"})
public String saveClient(#ModelAttribute("client") Client client,Model model,#ModelAttribute("compte") Compte compte,#ModelAttribute("carte") Carte carte,
#ModelAttribute("agence") Agence agence,MultipartHttpServletRequest request,final #RequestParam("image") MultipartFile file) throws IOException {
compte.setClients(client);
String uploadDirectory = request.getServletContext().getRealPath(uploadFolder);
log.info("uploadDirectory:: " + uploadDirectory);
String fileName = file.getOriginalFilename();
String filePath = Paths.get(uploadDirectory, fileName).toString();
log.info("FileName: " + file.getOriginalFilename());
if (fileName == null || fileName.contains("..")) {
model.addAttribute("invalid", "Sorry! Filename contains invalid path sequence \" + fileName");
}
try {
File dir = new File(uploadDirectory);
if (!dir.exists()) {
log.info("Folder Created");
dir.mkdirs();
}
// Save the file locally
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
stream.write(file.getBytes());
stream.close();
} catch (Exception e) {
log.info("in catch");
e.printStackTrace();
}
byte[] imageData = file.getBytes();
client.setImage(imageData);
Date v = client.getTemps();
//Date dNow = new Date( ); // Instantiate a Date object
Calendar cal = Calendar.getInstance();
cal.setTime(v);
cal.add(Calendar.AM_PM, 0);
cal.add(Calendar.MINUTE, 30);
v = cal.getTime();
client.setTempsfin(v);
clientMetier.addClient(client);
compteMetier.addCompte(compte);
agence.setCompteagence(compte);
compte.setAgencecompte(agence);
agenceMetier.addAgence(agence);
model.addAttribute("compte",compte);
model.addAttribute("agence",agence);
return "compte";
}
HTML:
<form th:action="#{/saveClient}" method="POST"
th:object="${client}" enctype="multipart/form-data">
<div class="p-col-12">
<label class="p1">Image</label>
<input type="file" class="form-control" placeholder="" name="image" id="image" th:field="*{image}">
You should not directly use your entity as the form object as you need to use different types for the image.
Create a separate ClientFormData object to use in the controller that has all the fields of Client, but for image uses MultipartFile:
public class ClientFormData {
// other fields here
private MultipartFile image;
public static ClientFormData fromClient(Client client) {
// copy over fields
}
}
In the controller, get the bytes from the MultipartFile and copy those into your Client entity.
I have a controller like this:
#ResponseBody
#RequestMapping(value = "/getLayersOfCategory/{categoryId}", method = RequestMethod.GET)
public LayersResult GetLayersOfCategory(#PathVariable("categoryId") Integer categoryId,#RequestHeader("secret") String secret) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
DataServicesModel dataServicesModel=new DataServicesModel();
LocalDateTime now = LocalDateTime.now();
CategoriesEntity categoriesEntity=new CategoriesEntity();
categoriesEntity.setId(categoryId);
List<Object[]> layersCategoriesEntityList=layersCategoriesRepository.findAllByCategoryId(categoryId);
List<String> stringList=new ArrayList<>();
for (Object[] row:layersCategoriesEntityList){
stringList.add(row[2].toString());
}
LayersResult layersResult=this.GetPoints(stringList);
**** return layersResult;
}
at **** when I Evaluate "layersResult" expression it shows a json like this:
but when I call the controller by postman
I get something like this:
as you see the iconUrl key has different. I do not know wher the result change at the end of the controller without any line of code tha could change the final result.
thanks in advance for replying.
And this a DataLayerModel:
package org.rajman.lbs.neshan.business.data.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParseException;
import jdk.nashorn.internal.ir.annotations.Ignore;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import javax.persistence.*;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class DataLayerModel {
private Integer id;
private String title;
private String type;
private String iconUrl="kdjjfhskdjfh";
private String webUrl="http://map.tabr*.ir";
#JsonIgnore
public String getStyle() { return style;
}
public void setStyle(String style) {
this.style = style;
}
private String style="{\"icon\":\"dt.png\"}";
#Value("${url.webUrl:#{null}}")
#JsonIgnore
public String getWebUrl() {
return webUrl;
}
public void setWebUrl(String webUrl) {
this.webUrl = webUrl;
}
public DataLayerModel() {
}
public DataLayerModel(Integer id, String title, String type, String style) {
this.id = id;
this.title = title;
this.type = type.equals("ST_Polygon") || type.equals("polygon") ? "polygon" : "point";
this.style=style;
//this.iconUrl = getIconUrl();
}
public String getIconUrl() {
Object icon;
String url="";
JSONObject jsonObject;
try {
url=this.style;
jsonObject = new JSONObject(this.style);
icon=jsonObject.get("icon");
url=this.getWebUrl()+"/images/"+icon.toString();
}
catch (Exception e){
System.out.println(e);
}
return url;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Assuming iconUrl is a String. i.e. serialization is straight forward.
The only thing, I can guess that would go wrong is getIconUrl() method.
Please try to evaluate, layers.get(0).getIconUrl() at the same debug point.
To get data from json I used RestTemplate and it works for getting all my data and displaying it on the localhost. The arrayList I got, I want to filter now to get only some data and put it in a new arrayList, but when I try to run it, it gives me "java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to model.Artists"
Should I get the Json data in other way, or the filtering function needs some casting?
The model class
package model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Artists {
private String ArtistName;
private String Stage;
private String Day;
private String Hour;
public Artists(){
}
public String getArtistName() {
return ArtistName;
}
public void setArtistName(String artistName) {
ArtistName = artistName;
}
public String getStage() {
return Stage;
}
public void setStage(String stage) {
Stage = stage;
}
public String getDay() {
return Day;
}
public void setDay(String day) {
Day = day;
}
public String getHour() {
return Hour;
}
public void setHour(String hour) {
Hour = hour;
}
#Override
public String toString() {
return "Artists [ArtistName=" + ArtistName + ", Stage=" + Stage + ", Day=" + Day + ", Hour=" + Hour + "]";
}
}
The service class
#Service
public class ArtistsWrapper {
private List<Artists> artists;
private final String url ="some_random_website";
/**
* #return the artists
*/
public List<Artists> getArtists() {
RestTemplate restTemplate=new RestTemplate();
this.artists=restTemplate.getForObject(url, List.class);
return artists;
}
public List<Artists> getArtistsByStage(String stage)
{
System.out.println(artists.toString());
List<Artists> result = new ArrayList<Artists>();
for(Artists a: artists)
{
if(stage.equals(a.getStage()))
System.out.println(a.toString()+"\n");
result.add(a);
}
return result;
}
The controller class
#RestController
#RequestMapping("/api")
public class ArtistsController {
#Autowired
ArtistsWrapper aw;
/*#RequestMapping("/artists")
public List<Artists> artists() {
return aw.getArtists();
}
*/
#RequestMapping("/artists")
public List<Artists> artistsByStage(#RequestParam(value="stage", defaultValue="Main") String name) {
return aw.getArtistsByStage(name);
}
}
I've make HttpsURLConnection to receive some information about my server.
The result of response is :
{"about":{"title":"NiFi","version":"1.1.0","uri":"https://localhost:443/api/","contentViewerUrl":"/nifi-content-viewer/","timezone":"CET"}}
How is possible to extract all attributes and key/value ?
About.class file
public class About {
private List<AboutObject> about;
public About()
{
// this.about = about;
}
public List<AboutObject> getAbout() {
return this.about;
}
public void setAbout(List<AboutObject> about) {
this.about = about;
}
}
AboutObject.class
public class AboutObject {
private String title;
private String uri;
private String contentViewerUrl;
private String timezone;
public String getTitle()
{
return this.title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getUri()
{
return this.uri;
}
public void setUri(String uri)
{
this.uri = uri;
}
public String getContentViewerUrl()
{
return this.contentViewerUrl;
}
public void setContentViewerUrl(String contentViewerUrl)
{
this.contentViewerUrl = contentViewerUrl;
}
public String getTimeZone()
{
return this.timezone;
}
public void setTimeZone(String timezone)
{
this.timezone = timezone;
}
}
Main.class
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
System.out.println("Contenu de in = " + in.toString());
ObjectMapper mapper = new ObjectMapper();
//Staff objStaff = new Staff();
System.out.println("Object to JSON in file");
mapper.writeValue(new File("output/file.json"), response);
System.out.println("Convert JSON string from file to Object");
//String about = mapper.readValue(new File("output/file.json"), String.class);
About about = mapper.readValue(new File("output/file.json"), About.class);
Error
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of About: no String-argument constructor/factory method to deserialize from String value ('{"about":{"title":"NiFi","version":"1.1.0","uri":"https://localhost:443/api/","contentViewerUrl":"/nifi-content-viewer/","timezone":"CET"}}') at [Source: output/file.json; line: 1, column: 1]
Thanks for you help
The test json you show doesn't have the array wrapper used in your About object. You're also missing the version field in your AboutObject and the timezone field uses the wrong case.
Your example worked when I updated your objects:
public class About {
private AboutObject about;
public AboutObject getAbout() {
return about;
}
public void setAbout(AboutObject about) {
this.about = about;
}
}
public class AboutObject {
private String title;
private String uri;
private String contentViewerUrl;
private String timezone;
private String version;
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUri() {
return this.uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getContentViewerUrl() {
return this.contentViewerUrl;
}
public void setContentViewerUrl(String contentViewerUrl) {
this.contentViewerUrl = contentViewerUrl;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
Test:
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String obj = "{\"about\":{\"title\":\"NiFi\",\"version\":\"1.1.0\",\"uri\":\"https://localhost:443/api/\",\"contentViewerUrl\":\"/nifi-content-viewer/\",\"timezone\":\"CET\"}}";
About about = mapper.readValue(obj, About.class);
}
I am a bit lost here,
I have a JSON string like this:
{
"type":"fuu",
"message":"bar",
"data":{
"5":{
"post":"foo",
"type":"bar",
},
"0":{
"post":"foo",
"type":"bar",
},
"1":{
"post":"foo",
"type":"bar",
},
// and so on...
}
}
Please how do I parse it into POJOs using Gson? (I need to get the list of objects)
I am a bit confused by the number in front of the elements of the list of objects....
Try this -
Pojo.java
import java.util.Map;
public class Pojo {
private String type;
private String message;
private Map<Integer, InnerPojo> data;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Map<Integer, InnerPojo> getData() {
return data;
}
public void setData(Map<Integer, InnerPojo> data) {
this.data = data;
}
#Override
public String toString() {
return "Pojo [type=" + type + ", message=" + message + ", data=" + data
+ "]";
}
}
InnerPojo.java
public class InnerPojo {
private String type;
private String post;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
#Override
public String toString() {
return "InnerPojo [type=" + type + ", post=" + post + "]";
}
}
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.Pojo;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
public static void main(String[] args) {
String j = "{\"type\": \"fuu\", \"message\": \"bar\", \"data\":{ \"0\":{\"post\": \"foo\", \"type\": \"bar\"}, \"1\":{\"post\": \"foo\", \"type\": \"bar\"}, \"5\":{\"post\": \"foo\", \"type\": \"bar\"}}}";
Pojo p = gson.fromJson(j, Pojo.class);
System.out.println(p);
}
}
And Result is -
Pojo [type=fuu, message=bar, data={0=InnerPojo [type=bar, post=foo], 1=InnerPojo [type=bar, post=foo], 5=InnerPojo [type=bar, post=foo]}]
For the "data" part, I'd try to parse it into a Map<Integer, TypedPost> structure, see this thread for instructions.