Return JSON string from spring controller - json

I have written a service which query through an AJAX call from solr and return search results as json. I want to return this json from my controller to AJAX.
public class SearchServiceImpl implements SearchService {
private String getSearchResults(String url) throws ClientProtocolException,
IOException {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response = client.execute(get);
//logger.info("Response: " + response.getEntity().getContent());
BufferedReader rd = new BufferedReader(new InputStreamReader(response
.getEntity().getContent()));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = rd.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
public String performSearch(String term) {
String result = "";
try {
result = getSearchResults(getSolrURL(term)); // getSolrURL() prepares the solr url
} catch (ClientProtocolException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
}
return result;
}
}
This is handleRequest() method in my controller -
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("Perform search view");
String term = request.getParameter("term");
String result = searchService.performSearch(term);
// Here I need to return result which is a json
ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
// mav.addObject("key1", "value1");
// mav.addObject("key2", "value2");
return mav;
}

The best thing to do is to let Jackson automatically do all the serialization. So your controller would look like this
#RequestMapping(value = "/payment/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody Payment get(#PathVariable Long id) {
return paymentService.getById(id);
}
The Payment class has all it's getters and setters for Jackson
package net.isban.example.vo;
public class Payment {
private Long id;
private String sort;
private String account;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
#Override
public String toString() {
return "Payment [id=" + id + ", sort=" + sort + ", account="
+ account + "]";
}
}
And make sure you include Jackson in the classpath
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
This assumes you are using Spring, if not you can still use Jackson to generate json:
String json = new ObjectMapper().writeValueAsString(payment);

Related

Spring Batch picking old values from csv file

I have Spring Batch application that reads osm-billers.csv file. When I run the application , it is processing the records available in csv file. Then I changed the content of the file and saved it. But, it still reads the old contents. It was reading the file earlier without problem, now giving issue as if there is caching problem. My csv file contains only 3 or 4 records.
BillerOrderId
1001289463281044
1001289073251049
1000819614021112
000000002
public class BatchConfiguration {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
#Autowired
private CsvFileToDatabaseJobConfig csvFileToDatabaseJobConfig;
#Autowired
private DatabaseToCsvFileJobConfig databaseToCsvFileJobConfig;
#Bean
public FlatFileItemReader<Biller> reader(){
try {
FlatFileItemReader<Biller> itemReader = csvFileToDatabaseJobConfig.csvFileItemReader();
return itemReader ;
} catch (UnexpectedInputException e) {
throw new OrderBatchException("Invalid Input..." + e.getMessage());
} catch (ParseException e) {
throw new OrderBatchException("Parsing error..." + e.getMessage());
} catch (NonTransientResourceException e) {
throw new OrderBatchException("NonTransientReasource error..." + e.getMessage());
} catch (Exception e) {
throw new OrderBatchException("Unknown Read error..." + e.getMessage());
}
}
#Bean
public OrderProcessor processor() {
return new OrderProcessor();
}
#Bean
public ItemWriter<Biller> writer() {
try {
ItemWriter<Biller> itemWriter = databaseToCsvFileJobConfig.databaseCsvItemWriter();
return itemWriter;
} catch (Exception e) {
throw new OrderBatchException("Unknown Write error..." + e.getMessage());
}
}
#Bean
public Job importJobOrder(JobCompletionNotificationListner listener, Step step1) {
return jobBuilderFactory.get("importJobOrder")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
#Bean
public Step step1(ItemWriter<Biller> writer) {
return stepBuilderFactory.get("step1")
.<Biller, Biller> chunk(10)
.reader((ItemReader<? extends Biller>) reader())
.processor(processor())
.writer(writer)
.build();
}
}
public class CsvFileToDatabaseJobConfig {
#Bean
FlatFileItemReader<Biller> csvFileItemReader() {
FlatFileItemReader<Biller> csvFileReader = new FlatFileItemReader<>();
csvFileReader.setResource(new ClassPathResource("osm-billers.csv"));
csvFileReader.setLinesToSkip(1);
LineMapper<Biller> billerLineMapper = createBillerLineMapper();
csvFileReader.setLineMapper(billerLineMapper);
return csvFileReader;
}
private LineMapper<Biller> createBillerLineMapper() {
DefaultLineMapper<Biller> billerLineMapper = new DefaultLineMapper<>();
LineTokenizer billerLineTokenizer = createBillerLineTokenizer();
billerLineMapper.setLineTokenizer(billerLineTokenizer);
FieldSetMapper<Biller> billerInformationMapper = createBillerInformationMapper();
billerLineMapper.setFieldSetMapper(billerInformationMapper);
return billerLineMapper;
}
private FieldSetMapper<Biller> createBillerInformationMapper() {
BeanWrapperFieldSetMapper<Biller> billerInformationMapper = new BeanWrapperFieldSetMapper<>();
billerInformationMapper.setTargetType(Biller.class);
return billerInformationMapper;
}
private LineTokenizer createBillerLineTokenizer() {
DelimitedLineTokenizer billerLineTokenizer = new DelimitedLineTokenizer();
billerLineTokenizer.setNames(new String[] {"billerOrderId"});
return billerLineTokenizer;
}
}
public class OrderReader implements ItemReader<OrderResponse>{
private static final Logger log = LoggerFactory.getLogger(OrderReader.class);
private final String apiUrl;
private final RestTemplate restTemplate;
private OrderResponse orderResponse;
#Autowired
private OrderRequest orderRequest;
private String userName;
private String password;
public OrderReader(String apiUrl, String userName, String password, RestTemplate restTemplate, OrderRequest orderRequest) {
this.apiUrl = apiUrl;
this.restTemplate = restTemplate;
this.orderRequest = orderRequest;
this.userName = userName;
this.password = password;
}
private boolean orderisNotInitialized() {
return this.orderResponse == null;
}
private OrderResponse fetchOrderDataFromApi(OrderRequest orderRequest) {
log.debug("OrderRequest = " + orderRequest.getOrder().getBillerOrderId());
log.debug("apiUrl = " + apiUrl);
log.debug("userName = " + userName);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setBasicAuth(userName, password);
HttpEntity<OrderRequest> requestEntity =
new HttpEntity<OrderRequest>(orderRequest, headers);
ResponseEntity<OrderResponse> response =
restTemplate.exchange(apiUrl,HttpMethod.POST, requestEntity,OrderResponse.class);
log.debug("response = " + response);
OrderResponse orderResponse = response.getBody();
return orderResponse;
}
#Override
public OrderResponse read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if (orderisNotInitialized()) {
orderResponse = fetchOrderDataFromApi(orderRequest);
}
return orderResponse;
}
}
public class OrderProcessor implements ItemProcessor<Biller, Biller>{
#Value("${osm.service.url}")
private String orderUrl;
#Value("${osm.service.username}")
private String userName;
#Value("${osm.service.password}")
private String password;
#Autowired
RestTemplate restTemplate;
#Override
public Biller process(Biller biller) throws Exception {
OrderRequest orderRequest = new OrderRequest();
Order order = new Order();
order.setBillerOrderId(biller.getBillerOrderId());
orderRequest.setOrder(order);
OrderReader osmReader = new OrderReader(orderUrl, userName, password, restTemplate, orderRequest);
OrderResponse orderResponse = osmReader.read();
if (orderResponse.getResult().equals("SUCCESS") ) {
return null;
} else {
//Failed transactions
return biller;
}
}
}
For testing purpose, I made BillerOrderId as 4 digits and picks up immediately but when I change to 16 digits , it takes time to execute updated 16 digit BillerOrderId. It works after 4 or 5 attempts. I tried to see the duration it picks up updated records. But, i didn't see any consistency.
Thanks,
Bandita Pradhan

How to parse below json response using jackson 2.X? The bracket [ after the result is causing issue

I am struggling to parse the below json using jackson libraries
{"result":[{"userID":"xyz","firstName":"abc","lastName":"def","vFlag":"false","URL":"xyz://abc.com/cti.do?sysparm_caller=abc%20def&sysparm_caller_phone=+1 800 123 456"}]}
the square bracket after the "result" seems to be causing the issue.
I already have UNWRAP_ROOT_VALUE set in my code.
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
If i remove the [] then the json to pojo works fine. Is their any annotation i can use without fiddling around with string manipulations ?
POJO class
package com.parse.input;
import com.fasterxml.jackson.annotation.JsonRootName;
#JsonRootName(value = "result")
public class Employee {
private String userID = null;
private String firstName = null;
private String lastName = null;
private String vFlag = null;
private String uRl = null;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getVFlag() {
return vFlag;
}
public void setVFlag(String vipFlag) {
this.vFlag = vipFlag;
}
public String getURL() {
return uRl;
}
public void setURL(String ctiURL) {
this.uRl = ctiURL;
}
}
======And the Code to invoke REST API and parse the response======
Client restClient = Client.create();
WebResource webResource = restClient.resource(wURL);
ClientResponse resp = webResource.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Basic " + authStringEnc)
.header("EXT_URL", sURL + inputParameter)
.get(ClientResponse.class);
String output = resp.getEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
try {
System.out.println("Starting to parse the employee response");
Employee employee = mapper.readValue(ouput.toString(), Employee.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I was able to get around it like this.
try{
JSONObject j=new JSONObject(output.toString());
extractedJsonEmployee = j.getJSONArray("result").get(0).toString();
} catch (JSONException e) {
e.printStackTrace();
}
//Commented out the UNWRAP_ROOT_VALUE, since i am already taking out the root
Employee employee = mapper.readValue(extractedJsonEmployee, Employee.class);

Jackson JSON Can not construct instance of "About" : deserialize issue

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);
}

How to replace null fields (nested at all levels) from JSON response using Jackson ObjectMapper serialization?

I am using the below code to receive Tweets from Twitter4j Search API in the form of JSON response. I am receiving the result in the form of List as specified in Twitter4j search API in the line
List<Status> tweets = result.getTweets();
The problem is that the tweets returned as List where one Status entry is having non-empty and non-null GeoLocation whereas another Status entry is having a null or empty GeoLocation. Since to retrieve the relevant fields from each Status entry (i.e. Tweet), I iterate over the List and call getters which is throwing me null for the Status entries where the GeoLocation field is null.
The approach I tried to follow:
I created a POJO TweetJSON_2 (defined at the bottom of the post) with the relevant fields and their getters and setters. I am using Jackson ObjectMapper to handle null values like below:
JsonGenerator generator = new JsonFactory().createGenerator(os);
generator.setPrettyPrinter(new DefaultPrettyPrinter());
TweetJSON_2 rawJSON;
ObjectMapper mapper = new ObjectMapper();
//mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
// ... rawJSON is populated ...
mapper.writeValue(generator, rawJSON);
However, when I am trying to get the geoLocation field from Status, using the below line which is marked with **
List<Status> tweets = result.getTweets();
I am getting the Java NullPointerException as follows:
[Mon Apr 20 11:32:47 IST 2015]{"statuses":[{"retweeted_status":{"contributors":null,"text":"<my text>",**"geo":null**,"retweeted":false,"in_reply_to_screen_name":null,"truncated":false,"lang":"en","entities":{"symbols":[],"urls":[],"hashtags": ... &include_entities=1","since_id_str":"0","completed_in":0.029}}
**Exception in thread "main" java.lang.NullPointerException
at analytics.search.twitter.SearchFieldsTweetsJSON_2.main(SearchFieldsTweetsJSON_2.java:78)**
For example: If I input a json String as
String s = "{\"first\": 123, \"second\": [{\"second_first\":null, \"second_second\":null}, {\"second_third\":null}, null], \"third\": 789, \"fourth\":null}";
The output should be like
"{\"first\": 123, \"third\": 789}";
What I want, is to replace all null elements from JSONArrays and all null key-value pairs from JSONObjects no matter at whatever level they are nested in my JSON response.
Object vs Tree Model Approach
I tried the Object Model parsing mechanism which is a javax.json.stream.JsonParser.Event based method but would need multiple times of access and object replacement on the JSON String depending on at what level the null is nested making this approach very complicated. At the same time if I use Tree Model mechanism, the entire JSON response would have to be stored as a Tree which may overflow my JVM heap memory because the JSON size can be pretty large based on my query parameters. I need to find a workable solution to overcome this problem. Any suggestions on solving the above discussed problem will be highly appreciated.
The code is as follows:
public class SearchFieldsTweetsJSON_2 {
/* Searches specific fields from Tweets in JSON format */
public static void main(String[] args) throws FileNotFoundException, IOException {
if (args.length < 2) {
System.out.println("java twitter4j.examples.search.SearchTweets [query][outputJSONFile]");
System.exit(-1);
}
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthAccessToken("NNNNNNNNN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setJSONStoreEnabled(true);
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
Query query = new Query(args[0]);
QueryResult result;
File jsonFile = new File(args[1]);
System.out.println("File Path : " + jsonFile.getAbsolutePath());
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(jsonFile));
JsonGenerator generator = new JsonFactory().createGenerator(os);
generator.setPrettyPrinter(new DefaultPrettyPrinter());
TweetJSON_2 rawJSON;
ObjectMapper mapper = new ObjectMapper();
//mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
do {
result = twitter.search(query);
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
rawJSON = new TweetJSON_2();
rawJSON.setStatusId(Long.toString(tweet.getId()));
rawJSON.setUserId(Long.toString(tweet.getUser().getId()));
rawJSON.setUserName(tweet.getUser().getScreenName());
rawJSON.setStatusText(tweet.getText());
rawJSON.setGeoLocation(tweet.getGeoLocation().toString()); **<< Giving error at tweet.getGeoLocation() since GeoLocation is null**
mapper.writeValue(generator, rawJSON);
System.out.println(rawJSON.toString());
}
} while ((query = result.nextQuery()) != null);
generator.close();
System.out.println(os.toString());
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets : " + te.getMessage());
System.exit(-1);
}
}
}
I have defined my TweetJSON_2 Java object as follows:
public class TweetJSON_2 {
public String statusId;
public String statusText;
public String userId;
public String userName;
public String geoLocation;
public String getStatusId() {
return statusId;
}
public void setStatusId(String statusId) {
this.statusId = statusId;
}
public String getStatusText() {
return statusText;
}
public void setStatusText(String statusText) {
this.statusText = statusText;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGeoLocation() {
return geoLocation;
}
public void setGeoLocation(String geoLocation) {
this.geoLocation = geoLocation;
}
#Override
public String toString() {
return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
}
}
I have tried with reconfiguring my POJO in the below way and it successfully replaced all the nulls as specified in the setter methods. Didn't need to follow either Tree or Event-based model parsing of JSON string. HTH
The modified TweetJSON_2 POJO:
public class TweetJSON_2 {
public Long statusId = null;
public String statusText = null;
public Long userId = null;
public String userName = null;
public GeoLocation geoLocation = null;
public Long getStatusId() {
if (this.statusId==null)
return new Long(0L);
return statusId;
}
public void setStatusId(Long statusId) {
if (statusId==null)
this.statusId = new Long(0L);
else
this.statusId = statusId;
}
public String getStatusText() {
if (this.statusText==null)
return new String("");
return statusText;
}
public void setStatusText(String statusText) {
if (statusText==null)
this.statusText = new String("");
else
this.statusText = statusText;
}
public Long getUserId() {
if (this.userId==null)
return new Long(0L);
return userId;
}
public void setUserId(Long userId) {
if (userId==null)
this.userId = new Long(0L);
else
this.userId = userId;
}
public String getUserName() {
if (this.userName==null)
return new String("");
return userName;
}
public void setUserName(String userName) {
if (userName==null)
this.userName = new String("");
else
this.userName = userName;
}
public GeoLocation getGeoLocation() {
if (this.geoLocation==null)
return new GeoLocation(0.0,0.0);
return geoLocation;
}
public void setGeoLocation(GeoLocation geoLocation) {
if (geoLocation==null)
this.geoLocation = new GeoLocation(0.0,0.0);
else
this.geoLocation = geoLocation;
}
#Override
public String toString() {
return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
}
}

org.codehaus.jackson.JsonGenerationException: Can not write number, expecting field name

Hi i am working on a spring mvc application well i need to Serialize an object in order to pass it with an ajax Post.
my bean class :
#JsonSerialize(using = AgentSer.class)
public class AgentCust implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long personneID;
private String nom;
private String prenom;
private String matriculation;
private String marche;
private String compte;
private String phone, mail, chat;
public String getMarche() {
return marche;
}
public void setMarche(String marche) {
this.marche = marche;
}
public String getCompte() {
return compte;
}
public void setCompte(String compte) {
this.compte = compte;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getChat() {
return chat;
}
public void setChat(String chat) {
this.chat = chat;
}
public Long getPersonneID() {
return personneID;
}
public void setPersonneID(Long personneID) {
this.personneID = personneID;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getMatriculation() {
return matriculation;
}
public void setMatriculation(String matriculation) {
this.matriculation = matriculation;
}
}
and the class that will serialize my bean :
public class AgentSer extends JsonSerializer<AgentCust> {
#Override
public void serialize(AgentCust value, JsonGenerator jgen, SerializerProvider arg2) throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
jgen.writeStartObject();
jgen.writeNumber(value.getPersonneID());
jgen.writeString(value.getMatriculation());
jgen.writeString(value.getNom());
jgen.writeString(value.getPrenom());
jgen.writeString(value.getCompte());
jgen.writeString(value.getMarche());
jgen.writeString(value.getChat());
jgen.writeString(value.getMail());
jgen.writeString(value.getPhone());
jgen.writeEndObject();
}
}
in my controller i use my class like that:
AgentCust ags ;
// i set values here .
ObjectMapper mapper = new ObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(ags);
} catch (Exception e) {
System.out.println(e);
}
but at the end i get that :
org.codehaus.jackson.JsonGenerationException: Can not write number, expecting field name
any help please.
Why are you using a custom serializer(which is wrong as it doesn't include the field names). You are really complicating your life.
You can set the serialization options like this (you can also set them in a static block):
final ObjectMapper mapper = new ObjectMapper();
/*
you can set them globally in a static block and reuse the mapper...
performance gain
*/
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
mapper.setSerializationInclusion(Include.NON_NULL);
The rest of the code is the same(just add a constructor in your AgentCust.class to avoid some mapping errors):
AgentCust ags = new AgentCust();
ags.setChat("chat1");
ags.setCompte("compte1");
ags.setMail("mail1");
ags.setMarche("marche1");
ags.setMatriculation("matriculation1");
ags.setNom("nom1");
ags.setPersonneID(123456L);
ags.setPhone("phone1");
ags.setPrenom("prenom1");
String json = "";
try {
json = mapper.writeValueAsString(ags);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(json);
Another strange thing is that you're serializing the pojo as String. Why not JsonNode or ObjectNode?
public static ObjectNode convObjToONode(Object o) {
StringWriter stringify = new StringWriter();
ObjectNode objToONode = null;
try {
mapper.writeValue(stringify, o);
objToONode = (ObjectNode) mapper.readTree(stringify.toString());
} catch (JsonMappingException e) {
Logger.error("ERROR MAPPING JSON from object!", e);
} catch (JsonGenerationException e) {
Logger.error("ERROR GENERATING JSON from object!", e);
} catch (IOException e) {
Logger.error("ERROR IO when writing JSON from object!", e);
}
Logger.debug("Object as ObjectNode : " + objToONode);
return objToONode;
}