json to collection (list) in SpringBoot - json

I'm trying to get a list of orders from another service(url) with #GetMapping.
I can't get the json objects and convert them to a list.I keep getting these and similar errors:
org.springframework.web.client.HttpServerErrorException$InternalServerError:
500 Server Error: [java.lang.IllegalStateException: Not a JSON Object: null at com.google.gson.JsonElement.getAsJsonObject(JsonElement.java:91)
What should I do? please help me for how many days i can't find the right solution.
#Autowired
private final RestTemplate restTemplate;
#Value("${baseUrl}")
private String baseUrl;
public OrdersController(OrdersService ordersService, TradesService tradesService, RestTemplate restTemplate) {
this.ordersService = ordersService;
this.tradesService = tradesService;
this.restTemplate = restTemplate;
}
#GetMapping (value ="/restDeneme", produces="application/json")
public List <Orders> getOrders(){
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<List<Orders>> response = restTemplate.exchange(
baseUrl , HttpMethod.GET,entity,
new ParameterizedTypeReference<List<Orders>>() {});
return response.getBody();
}

You should try to receive the data as a JSON object
for a JSON format like this;
{
"Kml": {
"bicak": "AWAKEN YOUR SENSES",
"jobsearch": "JOB SEARCH",
"contact": "CONTACT",
"video": "ENCHANTING BEACHSCAPES",
"createprofile": "CREATE PROFILE"
}
}
You can call it like this;
String loudScreaming = json.getJSONObject("Kml").getString("bicak");

Related

JsonFilter throws error "no FilterProvider configured for id"

In a webservice developed in Spring Boot framework, I am looking for a way to filter few sensitive fields in the response. I am trying with JsonFilter. Here is the code I tried so far:
#ApiModel (value = "Customer")
#JsonInclude (JsonInclude.Include.NON_NULL)
#JsonFilter("CustomerFilter")
public class Customer implements Serializable
{
...
}
Controller code that sends filtered response:
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(customer);
FilterProvider filters = new
SimpleFilterProvider().setFailOnUnknownId(false).addFilter("CustomerFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("customerId"));
mappingJacksonValue.setFilters(filters);
return ResponseEntity.status(HttpStatus.OK).body(mappingJacksonValue);
While invoking the request, the following exception is thrown.
com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'CustomerFilter'; no FilterProvider configured
Am I missing any configuration?
I was having the same issue this week, just resolved it now by creating a FilterConfiguration class in my config folder.
#JsonFilter("studentFilter")
public class Student {
String name;
String password;
public Student() {
this.name = "Steve";
this.password = "superSecretPassword";
}
}
#Configuration
public class FilterConfiguration {
public FilterConfiguration (ObjectMapper objectMapper) {
SimpleFilterProvider simpleFilterProvider = new SimpleFilterProvider().setFailOnUnknownId(true);
simpleFilterProvider.addFilter("studentFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name"));
objectMapper.setFilterProvider(simpleFilterProvider);
}
}
When I create a new Student, the password is filtered out.
Avoid using MappingJacksonValue as it fails in object chaining and provide error like ["data"]->org.springframework.http.converter.json.MappingJacksonValue["value"]->java.util.ArrayList[0])
Note : Use ObjectMapper and ObjectWriter instead of MappingJacksonValue
Try the below code snippet
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
FilterProvider filters = new SimpleFilterProvider().setFailOnUnknownId(false).addFilter("CustomerFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("customerId"));
ObjectWriter writer = mapper.writer(filters);
String writeValueAsString = writer.writeValueAsString(customer);
Customer resultCustomer = mapper.readValue(writeValueAsString, Customer.class);
return ResponseEntity.status(HttpStatus.OK).body(resultCustomer);

Spring API application/json is not working when getting text/json content type

I'm querying a PhraseApp API to get translations and setting the content type on the headers as appplication/json:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
But the API sends a response as attachment with content type text/json; charset=UTF-8. And Spring raises the error:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.String] and content type [text/json;charset=UTF-8]
The response I get is in the following form:
{
"some.key.a": "some translation for a",
"some.key.b": "some translation for b",
"some.key.c": "some translation for c"
...
}
I expected to assign the response to a String variable and parse it later.
Any idea on what is going wrong here ? Thank you.
according to the JSON-specification the content type of JSON should always be "application/json".
One possible fix would be to edit the request and set the correct content type.
Fortunately I am from the PhraseApp Team and could simply fix this on our side ;)
You should be able to use it with your original code now!
If you need further help, send me a PN or an email at vincent#phraseapp.com
I had to use the following steps to get it works:
Use /api/v2/projects/{projectId}/locales/{localeId}/download
Create a custom converter as follows:
public class PhraseTextJsonConverter extends MappingJackson2HttpMessageConverter {
public PhraseTextJsonConverter() {
setSupportedMediaTypes(initMediaTypes());
}
private List<MediaType> initMediaTypes() {
return Arrays.asList(new MediaType("text", "json", DEFAULT_CHARSET));
}
}
Add converters to the template:
protected static RestTemplate createRestTemplateWithConverter() {
final RestTemplate restTemplate = new RestTemplate();
final List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<>();
httpMessageConverters.add(new MappingJackson2HttpMessageConverter());
httpMessageConverters.add(new ByteArrayHttpMessageConverter());
restTemplate.setMessageConverters(httpMessageConverters);
return restTemplate;
}
and later a custom one:
private void addPhraseTextJsonConverter() {
restTemplate.getMessageConverters().add(new PhraseTextJsonConverter());
}
To be able to get all the translations as a Map, I had to use ParameterizedTypeReferenceas follows:
protected ResponseEntity<HashMap<String, String>> requestPhraseApp(final HttpEntity<Object> requestEntity, final URI uri) {
ParameterizedTypeReference<HashMap<String, String>> typeRef = new ParameterizedTypeReference<HashMap<String, String>>() {};
...
return restTemplate.exchange(uri, HttpMethod.GET, requestEntity, typeRef);
...
}
Do not forget to init the request parameters to get all the translations in a Map:
List urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("file_format", "simple_json"));
That's it.

Can pass my own object with RestTemplate PUT

I want to build a small RESTful Service, send a PUT request with an Object of a class I created (MyObject), and getting a response with only status.
My controler:
#RestController
public class MyControler {
#RequestMapping(path = "/blabla/{id}", method = RequestMethod.PUT)
#ResponseBody
public ResponseEntity<String> putMethod (#PathVariable("id") Long id,
#RequestBody MyObject t) {
/*todo*/
return new ResponseEntity<String>(HttpStatus.OK);
}
My Test App
#SpringBootApplication
public class App {
public String httpPut(String urlStr) {
MyObject myObject = new MyObject(p,p,....);
URI url = null;
HttpEntity<MyObject> requestEntity;
RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders headers = new HttpHeaders();
List<MediaType> list = new ArrayList<MediaType>();
list.add(MediaType.APPLICATION_JSON);
headers.setAccept(list);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Content-Type", "application/json");
requestEntity = new HttpEntity<Transaction>(t, headers);
ResponseEntity<String> response =
rest.exchange(url, HttpMethod.PUT, requestEntity, MyObject.class);
return response.getStatusCode().getValue();
}
Im getting an HttpClientErrorException: 400 Bad Request
Where is my mistake? What I want is for Spring to automaticly serialize the MyObject. MyObject class is implementing serializable.
What do I miss?
}
Maybe you're doing to much?
Did you try to put the object as json via postman or something similar? If so what is the response?
Nevertheless i created a minimal example for consuming a service via Springs RestTemplate.
This is all needed code for getting a custom object AND putting a custom object via RestTemplate
public void doTransfer(){
String url = "http://localhost:8090/greetings";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Greeting> greeting = restTemplate.getForEntity(url, Greeting.class);
LOGGER.info(greeting.getBody().getValue());
Greeting myGreeting = new Greeting();
myGreeting.setValue("Hey ho!");
HttpEntity<Greeting> entity = new HttpEntity<Greeting>(myGreeting);
restTemplate.exchange(url, HttpMethod.PUT, entity, Greeting.class);
}
I've provided a sample project with a sender (maybe not a good name .. it is the project with the greetings endpoint) and a receiver (the project which consumes the greetings endpoint) on Github
Try to do this:
ResponseEntity<MyObject> responseSerialized =
rest.exchange(url, HttpMethod.PUT, requestEntity, MyObject.class);

return ModelAndView when JSON is returned

Can we return JSON object from spring controller and write that JSON object on jsp page.
Below is my jsp page:
<script type="text/javascript">
dojo.require("dojox.grid.EnhancedGrid");
dojo.require("dojox.data.QueryReadStore");
dojo.ready(function(){
mystore=new dojo.data.ItemFileReadStore({url:"<%=request.getContextPath()%>/showData.htm"});
var layout= [
{field: 'ID', name: 'SID',formatter: hrefFormatter,datatype:"number" },
{field: 'SPREAD',name: 'SPREAD',autoComplete: true}
]
var grid = new dojox.grid.EnhancedGrid({
id: 'myGrid',
----
});
</script>
Controller:
#RequestMapping(value = "/showData", method = RequestMethod.GET)
public void getSTIDData(HttpServletRequest request,
HttpServletResponse response, #ModelAttribute VINDTO vinData,
BindingResult beException) throws IOException {
try {
......
......
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});
xstream.alias("items", com.loans.auto.DTO.VINRequestDTO.class);
String str = xstream.toXML(vinListCopy);
StringBuffer rowData = new StringBuffer();
rowData.append("{'numRows':").append(vinListCopy.size())
.append(",'items':").append(str).append("}");
PrintWriter out = response.getWriter();
out.print(rowData);
}
Instead of getSTIDData(..) returning void , i want this method to return ModelAndView object, but when i return ModelAndView object, in jsp page data is not getting loaded and it says "NO Data Found". Please suggest. Thanks.
Below is the exception generated when i used Gson
SyntaxError {stack: "SyntaxError: Unexpected identifier↵ at Object.d… at signalWaiting (/MYWebProject/dojo/Deferred.js:28:4)", message: "Unexpected identifier"}
message: "Unexpected identifier"
stack: "SyntaxError: Unexpected identifier↵ at Object.dojo.fromJson (/MYWebProject/dojo/_base/json.js:26:23)↵ at Object.dojo._contentHandlers.dojo.contentHandlers.json (/MYWebProject/dojo/_base/xhr.js:78:16)↵ at Object.dojo._contentHandlers.dojo.contentHandlers.json-comment-optional (/MYWebProject/dojo/_base/xhr.js:156:28)↵ at _deferredOk (/MYWebProject/dojo/_base/xhr.js:432:42)↵ at notify (/MYWebProject/dojo/_base/Deferred.js:187:23)↵ at complete (/MYWebProject/dojo/_base/Deferred.js:168:4)↵ at resolve.callback (/MYWebProject/dojo/_base/Deferred.js:248:4)↵ at eval (/MYWebProject/dojo/_base/xhr.js:627:8)↵ at signalListener (/MYWebProject/dojo/Deferred.js:37:21)↵ at signalWaiting (/MYWebProject/dojo/Deferred.js:28:4)"
__proto__: Error
yes you can return as JSON response.showing with the help of Gson API
#RequestMapping(value = "/showData", method = RequestMethod.GET)
public #ResponseBody String getUserHomePage(HttpServletRequest request,HttpServletResponse response, #ModelAttribute VINDTO vinData,BindingResult beException) throws IOException {
//you code stuff to create model object bean
Gson gson = new Gson();
return gson.toJson(objectBean);
}
Keep it clean and simple...
Here is a real life snippet of code ...
#RequestMapping(value = "/actions/getImplGroups", method = RequestMethod.POST)
public ResponseEntity<String> getImplGroups(HttpServletRequest request, HttpServletResponse response) {
List<String> groups = bpmClient.getAllGroups();
ObjectMapper mapper = new ObjectMapper();
String jsonString;
try {
jsonString = mapper.writeValueAsString(groups);
} catch (JsonGenerationException e) {
jsonString = "Error with json generation: " + e.getMessage();
} catch (JsonMappingException e) {
jsonString = "Error with json mapping: " + e.getMessage();
} catch (IOException e) {
jsonString = "Error with json: " + e.getMessage();
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>(jsonString, responseHeaders, HttpStatus.CREATED);
}
The important point to consider is sending the correct web header, so that your page expects to see json.
I the case above we used the Jackson library to create the json, but in truth you could format the json any way you like. Here is an example of a simple, manually formatted string...
#RequestMapping(value = "/actions/getTicketsNotUpdatedWithinShift", method = RequestMethod.POST)
public ResponseEntity<String> getTicketsNotUpdatedWithinShift(String center, String sections, String minutesInShift, Model model) {
String[] sectionArray = sections.split(",");
String json = "";
String rowsString = "";
for (String section : sectionArray) {
List<Map<String, String>> rows = service.getMinutesSinceLastTicketUpdate(center, section);
for (Map<String, String> row : rows) {
int minutesSinceUpdate = Integer.parseInt(row.get("minutes"));
if (minutesSinceUpdate > Integer.parseInt(minutesInShift)) {
String description = row.get("description");
rowsString = rowsString + "\"" + description + "\",";
}
}
}
// Build the json structure
if (!rowsString.isEmpty()) {
// Trim the trailing comma.
rowsString = rowsString.replaceAll(",$", "");
json = "[" + rowsString + "]";
} else {
json = "[]";
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>(json, responseHeaders, HttpStatus.CREATED);
}

spring mvc rest mongo dbobject response

i want to create a spring mvc rest call and the response should be the results from the mongo db (Basic)DBObject. the DBObject is, as far as i know, a JSON object. is it possible to return this objects or should i return the normal string content of them?
this is the solution i have so far:
#RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
public ResponseEntity<String> getContentByIdsAsJSON(#PathVariable("ids") String ids)
{
String content = null;
StringBuilder builder = new StringBuilder();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "text/html; charset=utf-8");
List<String> list = this.contentService.findContentByListingIdAsJSON(ids);
if (list.isEmpty())
{
content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><error>no data found</error>";
return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}
for (String json : list)
{
builder.append(json + "\n");
}
content = builder.toString();
return new ResponseEntity<String>(content, responseHeaders, HttpStatus.CREATED);
}
does anyone have a better solution for that requirement?
thx very much in advance.
simon
I'm see a strange thing in you code. Do you must return json or xml? If you must return json it's simple in your situation, #ResponseBody do the magic
#RequestMapping(value = "/content/json/{ids}", method = RequestMethod.GET)
#ResponseBody
public MyGreatContentObject getContentByIdsAsJSON(#PathVariable("ids") String ids) {
return this.contentService.findContentByListingId(ids);
}
in any way, i'm think you still must learn base concepts a little more