I need to know, if jackson is doing the correct parse on my class attributes annotated with #JsonProperty, but enabling debug spring options, it does not display the json that was generated in the post.
I tried to create some interceptors to do this task but it did not work, does anyone know if there is any jackson setup that print the payload in the post operation?
just write a unit test for your pojo like this:
#Test
public void testSerialization() throws Exception {
String json = new ObjectMapper().writeValueAsString(yourObjectToBeSerialized);
// and simple print it
System.out.println(json);
// or do some assertions
Related
I have the following annotation used in a controller:
#ApiResponse(code = 400, message = "failed", response = MediaDataProductResponseV2.class)}
As you can see, the response string is displayed based on the class. How can you reference the response from a file like yml or json?
example
#ApiResponse(code = 400, message = "failed", response = "${error}")} -> this doesn't work
The problem I have is that the company's code is including all the error and success objects in a single pojo so there is no way to segregate the type of response we send to our clients. Let's say we have the following pojo response:
public class pojo{
private String error;
private String response;
… setters and getters...
}
If something goes wrong we just return the error part. If success, the response. There is no way I can point that out in the annotations as it will always serialize the whole thing and I don't want to play around with the pojos as they they are generated from a json schema. I need to reference the response from something else that can't be a class.
Error-handling is a cross-cutting concern and hence should not be tangled with business logic. Therefore It would be better to have a seperate class annotated with #ControllerAdvice that handles failures.
You then define a method that takes the exception and a HttpServletRequest as parameters and returns a ResponseEntity of a type that contains the error message you want to return.
This method is annotated with #ExceptionHandler(myException.class). The exception itself is annotated with #ResponseStatus(HTTPSTATUS.MYSTATUS). That way you have centralized your error-handling in one place while at the same time applying the error handling to all your controllers.
You can override this however by passing the basePackageClasses as an argument to the #ControllerAdvice annotation.
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.
This question already has an answer here:
Spring #RestController Get Request Content-Type to response json or html
(1 answer)
Closed 4 years ago.
I need to make a single api, by which I can return data format of json or xml, as it has been requested from the customer.
guys, any idea how I achieve this because when I use #Produces annotation it makes it fix for specific format, but I need to return as it has been requested.
If you can use Spring, configure ContentNegotiationManager in DispatcherServlet.xml and then you can use response type as parameters to url.
For example:
http://localhost:8080/employee-management-system/viewEmployee/4?type=xml
http://localhost:8080/employee-management-system/viewEmployee/4?type=json
More detailed instructions you can find here:
https://www.javainuse.com/spring/rest4
You could specify the response content type using the ResponseEntity object as follows:
return ResponseEntity
.ok()
.contentType(MediaType.IMAGE_GIF);
What I would normally expect to see here are two methods, one that #Produces ("application/json"), and the other that #Produces("application/xml").
#Path("/foobar")
public final class FooBar {
#Produces("application/xml")
public String xml () { ... }
#Produces("application/json")
public String json() { ... }
}
The example in Oracle's description of the #Produces annotation includes an example for text/plain and text/html which is similar.
this is one way to do it, but I don't want to write 2 methods. I want to do it in one method.
Another reasonable approach would be to get closer to the metal
#Path("/foobar")
public final class FooBar {
public Response foobar() (#Context HttpHeaders headers) { ... }
}
And then inspect the headers yourself to decide what to do. See Get HTTP header in JAX-RS
I have spent the past day trying to find a solution to this and could not find any online resource that solves this.
I am using Gson for Message conversion for my application, which works fine outside of unit testing. I even added a HttpMessageConverters bean to take precedence over Jackson instead of writing config values to application.yml. This only works when running the application.
Now my question is, how do I use the Gson serialization/deserialization for MockMvc? I have a class with the #SerializedName("field_one") annotation which the value differs from the actual name. The closest I got to finding an answer was the one below which didn't help:
https://stackoverflow.com/a/20510028/3948882
Any ideas how to replace the ObjectMapper or have MockMvc use Gson instead of Jackson?
Edit: To add a little more context:
When I try to send a Model which was converted to Json with Gson, it get's immediately refused (400) because I have #NotNull annotation for each field in the model. When it deserializes in the controller, it sets fields to null. The below example has #Valid, which makes sure the Model checks out.
#RequestMapping(value = "accept", method = RequestMethod.POST)
public Model resp(#Valid #RequestBody Model model){
return model;
}
On the flip side, when I go to hit an endpoint without #Valid, passing a json that pleases Jackson, and I get the a model back, I cannot check any of the fields:
mockMvc.perform(
post("/test/accept")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(jsonPath("$.field_one", is("Hello world!")))
Exception:
java.lang.AssertionError: No value at JSON path "$.field_one", exception: No results for path: $['field_one']
You have to set-up the MockMvc correctly:
MockMvc mvc = MockMvcBuilders.standaloneSetup(new YourController())
.setControllerAdvice(new SomeExceptionHandler())
.setMessageConverters(new GsonHttpMessageConverter()) //<-- THIS
.build();
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?