I need to get the list of all the films.
i am in this situation and i dont know how to manage it.
My project is divided in two smaller project. Back-end project and front-end project.
Back-end part that produce a Json that contains a list of films.
The service has this pattern
#GET
#Produce(json) // here is a particular library and it funcion correctly.
List<Film> getAllFilms
The output calling this service has this pattern:
[{"title:abc","time": 5486448}, {....}, {....}]
At the Front-end project i am using Resteasy .
I have create a class service to call the back-end and to manage the response
List<Film> film= new ArrayList<>();
try{
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://localhost:8080/film");
Response response = target.request().get();
film= List<Film>) response.readEntity(Film.class);
I have an exception of this type:
javax.ws.rs.ProcessingException: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of FILM out of START_ARRAY token
Now i am trying to understand something but there is full of material and i am loosing around.
How can i unmarshall an array to a list ?
You can use readValue method of jackson to convert it to List
public List<Film> convert(String jsonString) throws JsonParseException, JsonMappingException,
IOException {
ObjectMapper objectMapper = new ObjectMapper();
List<Film> filmList = objectMapper.readValue(
jsonString,
objectMapper.getTypeFactory().constructCollectionType(
List.class, Film.class));
return filmList;
}
Related
I tried to create a generic method to read the response json but I don't like to have a generic object with many hashmaps... I don't want to specify the type. I want to get the content for Country, City, etc...
AwsProxyResponse response = get("/countries");
List<Country> countryList = (List<Country>) jsonStringToObject(response.getBody()).get("countries"); // doesn't work
protected Object jsonStringToObject(String jsonString) throws IOException {
JsonObject jsonData = new JsonObject(jsonString);
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonData.toString().getBytes(), Object.class);
}
What is the proper way to get the Response data and then fetch what I need (e.g. content, totalElements, etc...)
I'm trying to add the principal id to every incoming request as part of the body. This is the code I am using:
InputStream in = containerRequestContext.getEntityStream();
String jsonRequestString = IOUtils.toString(in, encoding);
ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getFactory();
JsonParser parser = factory.createParser(jsonRequestString);
JsonNode jsonNode = mapper.readTree(parser);
((ObjectNode) jsonNode).put(PRINCIPAL_ID, containerRequestContext.getSecurityContext().getUserPrincipal().getName());
containerRequestContext
.setEntityStream(IOUtils.toInputStream(mapper.writeValueAsString(jsonNode), encoding));
This is my resource:
#POST
#Path("/service")
#RolesAllowed(USER_ROLE)
#Produces(MediaType.APPLICATION_JSON)
public Response myService(String principalId, String input){
// do stuff
}
When request hits the resource, I can see the new json string being bind on principalId argument e.g.
principalId = {"principalId": "id", "input":"input"}
is there a way to bind each property to the respective argument?
You have two options here:
write interceptor (with AspectJ, for instance) which handle all your endpoints and populates principalId to your method's parameter or POJO.
write a servlet filter. This option is required to read the same request twice. The first read will occur in the filter with your following preprocessing and the second one in the Spring servlet.
I am using Jersey service and sending a json response from a service call. Now my service will be used from cross domain as well. so i want to implement CORS in my code. I saw few examples in internet but all are returning response object. But in my code i am returning as ObjectWritter. in this case how to make this as CORS.
My code as below
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/sampleUrl/{pageNumber}")
public String fetchAlertRecords(#PathParam("pageNumber") int pageNumber) throws Exception {
List<CustomVO> list = new ArrayList<CustomVO>();
//do somethimg to insert values to list
ObjectWriter writer = null;
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
FilterProvider filters = new SimpleFilterProvider()
.addFilter(filterClass,SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
writer = mapper.writer(filters);
return writer.writeValueAsString(list);
}
CORS is about request/response headers, what you return (btw you return String and not ObjectWriter) is a response body. So use CORS as you have seen it in examples. May be this link will help https://spring.io/guides/gs/rest-service-cors/
I would like to parse a local JSON file and marshal it into models using RestTemplate, but can't tell if this is possible.
I'm trying to pre-populate a database on an Android app that is using RestTemplate for syncing with the server. Rather than parsing the local JSON on my own, I thought, why not use RestTemplate? It's made exactly for parsing JSON into models.
But...I can't tell from the docs if there is any way to do this. There is the MappingJacksonHttpMessageConverter class which appears to convert the server's http response into a model...but is there any way to hack that to work with a local file? I tried, but kept getting deeper and deeper down the rabbit hole with no luck.
Figured this out. Instead of using RestTemplate, you can just use Jackson directly. There is no reason RestTemplate needs to be involved in this. It's very simple.
try {
ObjectMapper mapper = new ObjectMapper();
InputStream jsonFileStream = context.getAssets().open("categories.json");
Category[] categories = (Category[]) mapper.readValue(jsonFileStream, Category[].class);
Log.d(tag, "Found " + String.valueOf(categories.length) + " categories!!");
} catch (Exception e){
Log.e(tag, "Exception", e);
}
Yes, I think it is possible(with MappingJacksonHttpMessageConverter).
MappingJacksonHttpMessageConverter has method read() which takes two parameters: Class and HttpInputMessage
MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
YourClazz obj = (YourClazz) converter.read(YourClazz.class, new MyHttpInputMessage(myJsonString));
With this method you can read single object from single json message, but YourClazz can be some collection.
Next, You have to create you own HttpInputMessage implementation, in this example it expected json as string but You probably can pass stream to your json file.
public class MyHttpInputMessage implements HttpInputMessage {
private String jsonString;
public MyHttpInputMessage(String jsonString) {
this.jsonString = jsonString;
}
public HttpHeaders getHeaders() {
// no headers needed
return null;
}
public InputStream getBody() throws IOException {
InputStream is = new ByteArrayInputStream(
jsonString.getBytes("UTF-8"));
return is;
}
}
PS. You can publish your app with database
I write my API documentation with Spring REST Docs.
Code example:
#Override
public void getById(String urlTemplate, PathParametersSnippet pathParametersSnippet, Object... urlVariables) throws Exception {
resultActions = mockMvc.perform(get(urlTemplate, urlVariables)
.principal(principal)
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print());
// do..
}
But the problem is that the result of the test is answered in one line. And understanding the structure of the returned data is very difficult.
Response example:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"creator":null,"modifier":null,"modificationTime":null,"creationTime":null,"id":100,"deleted":false,"name":"Name","description":null,"report":[{"creator":"System","modifier":"System","modificationTime":"2019-01-30T14:21:50","creationTime":"2019-01-30T14:21:50","id":1,"name":"Form name","reportType":{"creator":"System","modifier":"System","modificationTime":"2019-01-30T14:21:50","creationTime":"2019-01-30T14:21:50","id":1,"deleted":false,"name":"Raport"},"unmodifiable":true}]}
Forwarded URL = null
Redirected URL = null
Cookies = []
Further, I generate documentation from the answer received and in the documentation also unformatted JSON
What am I doing wrong? How to enable formatting for json?
If you're not in a position to configure your application to produce pretty-printed responses, you can have REST Docs do it for you prior to them being documented. This is described in the Customizing Requests and Responses section of the documentation:
Preprocessing is configured by calling document with an OperationRequestPreprocessor, and/or an OperationResponsePreprocessor. Instances can be obtained using the static preprocessRequest and preprocessResponse methods on Preprocessors. For example:
this.mockMvc.perform(get("/")).andExpect(status().isOk())
.andDo(document("index", preprocessRequest(removeHeaders("Foo")),
preprocessResponse(prettyPrint())));
In the case above the request is being preprocessed to remove a Foo header and the response is being preprocessed so that it appears pretty-printed.
You can try get ResultActions object from mockMvc and than get MockHttpServletResponse object. After that you can get all the values of the fields that came in response. In this case, you will not need to parse the string.
resultActions = mockMvc.perform(get(urlTemplate, urlVariables)
.principal(principal)
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print());
MockHttpServletResponse content = resultActions.andReturn().getResponse();
Also you can transform MockHttpServletResponse object data to json. IUf you use Jacson, than write your custom serializer for this object, add it to MockHttpServletResponse and register in ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(MockHttpServletResponse.class, CustomSerializer.class);
mapper.registerModule(module);
String jsonResult = mapper.writeValueAsString(content);
CustomSerializer should extends StdSerializer<MockHttpServletResponse> and override serialize method.