I'm currently using Jersey & Jackson for creating REST service. Right now when a Resource method produces application/json and is returned a POJO, it properly serializes the object into JSON and returns the response to the client.
What I'm looking to do now is setup Jersey so when a queryparam comes in (lets say "indent"), I can tell Jackson to serialize the JSON in a "prettier format, aka indented". You can easily tell Jackson to do this by configuring the JSON mapper with SerializationConfig.Feature.INDENT_OUTPUT.
The question is, how do I on a per-request basis take a queryparam and use that to modify Jackson's output?
Something like this:
#GET
#Path("path/to/rest/service")
#Produces("application/json")
public Response getSomething(
#DefaultValue("false") #QueryParam("indent") boolean indent, ...) {
...
if (indent) {
objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
}
...
}
Is what you looking for?
Related
I am trying to unit test a class that uses Jersey 2 Client + Moxy to call a REST service. I want to mock the response, which contains a large JSON object. The code is structured in such a way that I can override/mock the following method:
protected Response doPost(String path, Entity<?> entity) {
Invocation.Builder invocationBuilder = getRestInvocationBuilder(path);
Response response = invocationBuilder.post(entity);
return response;
}
I would like to somehow inject some example JSON data (ideally from a file) into the Response at this point, prior to readEntity() being called, so that I can test that the JSON data is correctly unmarshalled into the target object.
Is there any way to do this? Note that this is for unit testing and therefore I'm not interested in running a local server or other integration testing techniques.
I'm aware similar questions have been asked, but many seem out of date or have incomplete solutions. The closest solution suggested is to mock the readEntity() method of the Response, this will not work for me because it would involve creating an object of the desired type to return, rather than creating one from the example JSON data.
what I want:
#RequestMapping("/**")
public #ResponseBody Object getSomething(#RequestBody DataRequest req) {
// return anything can be transformed into json
}
If I use concrete returning type on this method, it will work. for example:
#RequestMapping("/**")
public #ResponseBody List<User> getSomething(#RequestBody DataRequest req) {
return UserManager.getAllUsers();
}
Does Spring MVC support this? As I know Gson library can deserialize arbitrary Java object into json, while Spring MVC use jackson, I don't know if it is possible.
Does Spring MVC support this?
Yes, Spring converts the returned object to a response body by using an HttpMessageConverter. With an approperiate Jackson dependency on the classpath, MappingJackson2HttpMessageConverter will convert the return type to the corresponding JSON representation, if possible.
As I know Gson library can deserialize arbitrary Java object into
json, while Spring MVC use jackson
As of Spring 4.1.x, there is a GsonHttpMessageConverter. So you can use GSON for reading and writing from/to JSON. For more information on this topic, check the Spring documentation on HTTP Message Converters.
We have a Resteasy webservice.
I use Jackson provider for JSON, both outgoing JSON in response and incoming JSON in request.
Is it possible to have a PostProcessInterceptor to be executed after JSON-Jackson serialization?
My PostProcessInterceptor has to change the JSON content for every outgoing response. But when the PostProcessInterceptor is executed if I print the entity response.getEntity().toString(); I see the toString method of the java.lang.Object, not the JSON String. That's because the Object has not yet been serialized by Jackson.
Is it possible to serialize with Resteasy/Jackson before running the PostProcessInterceptor?
I've also tried to use #Precedence annotation on my PostProcessInterceptor. But it doesn't work, even using "DECODER" precedence (which is the last one).
Any idea? Thanks in advance.
I would go for a CDI interceptor instead. You can get the intercepted method parameters from the InvocationContext and change them if necessary.
I need to write a Json client in Android for Zenfolio API. I decided to use Spring ResTemplate with MappingHttpJacksonConverter. When i do POST with "exchange" method i recieve json response with one element named "#type" that causes deserializatoon exception. Is there an annotation that tells deserializer to omit that tag? How to turn on annotation for json deserializer?
Try #JsonIgnoreProperties(ignoreUnknown=true) on your mapping classes if you want to ignore all elements that you are not interested in.
Try using #JsonIgnore ("#type"), Jackson annotations are enabled by default.
See http://wiki.fasterxml.com/JacksonAnnotations for more info.
I feel embarrassed to ask: but what is the right combination of annotations for a resteasy service method that will unmarshall a custom type?
I am able to successfully generate json and xml from methods which return custom types (with jaxb annotations), but I have failed to turn these types into method parameters. All the examples around the web seem to pass simple types such as strings.
Documentation claims that resteasy can unmarshall json and xml to annotated types, but how? The following signature requires an object with a string parameter taking constructor, which is not what I'm looking for.
#GET
#Path("/somepath/ontheserver/settestchild")
#Produces("application/xml")
String getQueryParam(#QueryParam("testchild")TestChild param);
TestChild has JAXB annotations, but I want resteasy to unmarshal incoming xml to an instance of this object, which is not happening. Am I missing something here?
You can use the #Consumes annotation:
#PUT
#Path("/")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
TestChild addTestChild(TestChild testChild);