I want to produce json from JPA @Entity, I have
@Entity
@JsonAutoDetect
public class Bar implements Serializable {
@Id
@GeneratedValue
private Integer id;
private String title;
//omitting other stuff
}
my controller is
@RestController
public class BarController {
@Autowired
private BarService barService;
@RequestMapping(value = "/", method = RequestMethod.GET, headers = "Accept=application/json", produces={"application/json"})
public List<Bar> list() {
return barService.findAllBars());
}
}
I'm having this error in browser
and in Postman Postman Malformed JSON
what is wrong with it.
-
Are you serializing your list to JSON before returning it?legendofawesomeness– legendofawesomeness2015年10月04日 03:58:36 +00:00Commented Oct 4, 2015 at 3:58
-
I don't know how you're configuring Spring, but this often means you don't have JSON converters installed. I use Spring Boot, which does that for me.chrylis -cautiouslyoptimistic-– chrylis -cautiouslyoptimistic-2015年10月04日 05:05:23 +00:00Commented Oct 4, 2015 at 5:05
-
1@chrylis Spring Boot is not the choice then??Arshad Ali– Arshad Ali2015年10月04日 05:15:00 +00:00Commented Oct 4, 2015 at 5:15
-
Spring Boot is the choice. A plain Boot setup wouldn't have this issue.chrylis -cautiouslyoptimistic-– chrylis -cautiouslyoptimistic-2015年10月04日 05:16:47 +00:00Commented Oct 4, 2015 at 5:16
4 Answers 4
The "Malformed JSON" message is from the "Pretty" printing. Click "Raw" to see the actual response.
The actual response is a 406 Not Acceptable error (says so on your screen) with a payload of HTML (hence the unexpected < from "Pretty") that says the request has been rejected by the server.
Remove the headers = "Accept=application/json" from the @RequestMapping. The produces={"application/json"} is already telling Spring to only call this method if application/json is an acceptable response, which it likely is, but the header might say *.*, or something more complex like text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, both of which will allow application/json.
Of course, since this is likely an AJAX call that is expecting JSON, it should have listed only application/json in the accept value. Check the code executing the AJAX call if that is not the case.
Comments
I caught up one fatal mistake which is you are getting list of Bars barService.findAllBars(), you may need to convert that list to json adding the method as
public static String toJSON(Object object)
{
if ( object == null ){
return "{}";
}
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
catch (Exception e) {
e.printStackTrace();
}
return "{}";
}
Now make change as
@RequestMapping(value = "/", method = RequestMethod.GET, produces={"application/json"})
public String list() {
return toJSON(barService.findAllBars());
}
hope this works, if any issues feel free to query in comments session.
8 Comments
@ManyToMany(cascade = {CascadeType.MERGE}) @JoinTable(name = "foos_bars", joinColumns = @JoinColumn(name = "foos_id"), inverseJoinColumns = @JoinColumn(name = "bars_id")) private List<Foos> foos; i get >org.codehaus.jackson.map.JsonMappingException: failed to lazily initialize a collection of role: pkj.Bar.foos, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->pkj.entity.Bar["foos"]), how to solve this oneI suspect there is something amiss with your accept header in your get request. Try setting the header to
"Accept=*/*"
and see what you get back.
Comments
Use JsonFormatter https://jsonformatter.curiousconcept.com/ to test the JSON before proceeding further. Its a very good tool that validates JSON and shows you possible errors with line number.