I am trying to use Spring with Jackson to implement REST service using JSON as data interchange format. Now I have hit a road block with handling of generic classes in Jackson/Java. I am reading JacksonDataBinding page but I do not understand how I could use the information to help me with the issue when using Spring annotations. Given a basic response class like this, how do I make it work properly with Jackson and Spring together?
public class BasicResponseDto<ResponseDataType> {
private ResponseDataType data;
// ...
}
Related
We're using javax.ws.rs.core.Response.readEntity(Class type) to parse JSON responses into POJOs. I want to write tests to assure that the entity is correctly mapped into the POJO - so if a boolean "valid" is true in the json, it is also true in the POJO - and vice versa.
I cannot figure out how to do it. Any ideas or tips?
I want to write tests to assure that the entity is correctly mapped into the POJO
If all you want to test is that the POJO is mapped correctly, and you are using Jackson as the JSON provider, you can simply use the ObjectMapper to deserialize the JSON. This is how Dropwizard recommends testing models
final ObjectMapper mapper = new ObjectMapper();
POJO pojo = mapper.readValue(jsonString, POJO.class);
// assertions
Testing marshalling is one of those things in jax-rs services that are not easy to test with plain junit tests. For instance, how can you ensure you did not forget an annotation #Path or #QueryParam, so that your junit test calling the method succeeds, but actually calling the service fails.
Arquillian provides a solution for those tests. Essentially, Arquillian enables executing tests in a running javaee container. The test setup includes building your war, and deploying your application. This way, you can test all elements of your stack, and make sure all goes together: marshalling, request routing, http filters,...
If you are using the jersey jax-rs stack, you can alternatively use JerseyTest.
Arquillian is more complete, since it enables testing with multiple containers (even selenium support) and does not tie you with a jax-rs implementation.
I need to work on an enterprise legacy Java application that is developed in servlets & jsp's.Planning to convert this legacy app to a Single Page application using angular js & Spring MVC REST.
In the new development, AngularJS will be submitting the model object's (as JSON ) to Spring REST methods.
In the existing application there is a lot of code in servlets and classes (at least 2000 lines in 30 classes) written to get request parameter's using HttpServletRequest i.e., request.getParameter("name");
Is it possible to be able to inject/convert the model (JSON) object submitted by angularJs to Spring MVC REST methods into HttpServletRequest object, so that I need not change all the legacy code & classes?
Not considering to use the #RequestParam annotation in the method signature as the number of parameters are high.
Whatever JSON Object you are defining like below and which you trying to pass backend
var dataToPass={
name:"XYZ",
id:12,
selstat:[12,14]
};
For that, you need to create JAVA POJO with similar name like below
class UIData{
private String name; // Getter and Setter
private Integer id; // Getter and Setter
private List<Integer> selstat; // Getter and Setter
}
And in Spring while defining mapping in controller, you need to use annotation #ResuestBody in argument like below
#RequestMapping(value ='/mappingURL', method = RequestMethod.POST)
public #ResponseBody RsponseObject processData(#RequestBody UIData uiData, HttpServletRequest request)
throws MyException {
// Process you data
}
This will automatically convert JSON object into POJO instance.
Please go through Spring Documentation for more details.
And make sure content-type in header while passing is application/json along with Jackson library added in your dependency.
I am working on a project that uses Spring framework and Jackson. However, I was not able to find a place, where it is being plugged. I looked at many examples on the web and most of them use bean of class org.springframework.http.converter.json.MappingJacksonHttpMessageConverter to allow deserialization of #ResponseBody.
So, I was not able to find any references to MappingJacksonHttpMessageConverter.
My question: Will spring framework automatically use Jackson if it will find it on its classpath to convert JSON into #ResponseBody object?
What are other ways how Jackson can be enabled?
If you wire up your spring project using #EnableWebMvc or via XML by using the tag <mvc:annotation-driven /> you enable a bunch of features. You can read the detailed list of features in the original Spring docs.
One of the features that are enabled is the support for #RequestBody method parameters and #ResponseBody method return values. This is done via the HttpMessageConverter component and the feature is enabled for methods that are annotated with #RequestMapping or #ExceptionHandler.
The following lists the converters that are registered by default:
ByteArrayHttpMessageConverter converts byte arrays.
StringHttpMessageConverter converts strings.
ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
FormHttpMessageConverter converts form data to/from a MultiValueMap.
Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML — added if JAXB2 is present on the classpath.
MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter) converts to/from JSON — added if Jackson 2 (or Jackson) is present on the classpath.
AtomFeedHttpMessageConverter converts Atom feeds — added if Rome is present on the classpath.
RssChannelHttpMessageConverter converts RSS feeds — added if Rome is present on the classpath.
So, if you have a web enabled project with Jackson available on the classpath, Spring will automatically convert return values from a controller-method that is annotated with #ResponseBody (if the client caller accepts JSON that is which means that the accept header typically must be set to application/json).
If you wish to override the HttpMessageConverters you can implement the following:
#Configuration
#EnableWebMvc
public class YourConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(
List<HttpMessageConverter<?>> converters) {
// Do your magic, override your stuff
}
}
For a good introduction on how to customize e.g. the Jackson converter you can read this article from DZone about Customizing HttpMessageConverters with Spring Boot and Spring MVC.
I tried to generate a json response earlier using spring-mvc (annotation) . After so may failure i find out some check point :
I need to add <mvc:annotation-driven/> in my servelet mapper. although i don't know the reason.
Then I need to add #ResponseBody annotation which should bound the return value as http response as the documentation says.
And I also need add some jacson dependency.
Did i missed something?
Now i have bunch of questions
why we have to add that in my servelet xml and how this whole process is working?
As json response is most commonly used when why spring need jackson dependency to generate json?
some days ago i was doing Struts2 generating json response there was much simple.
Is there any way to do it more easily in spring-mvc .?
At first you should understand that <mvc:annotation-driven/> annotation used for many cases not only for generating json response in Spring. This annotation allow to use different annotations in Spring mvc classes like:#NumberFormat #DateFormat #Controller #Valid and of course #ResponseBody.
To generate json response you just need #ResponseBody annotation in your controller or servlet and import libraries for processing JSON.
Recently java has oun set of APIs for processing JSON as part of Java EE 7 JSR 353 actually it has clean Oracle tutorial. Also you can use third party libraries like Jackson. To process (parse, generate, transform, and query) JSON text it's necessarily to have one of this libs.
You can learn about most popular third party libraries and their performance in this article
Here you can see simple example.
If you are using jacson you can do something like:
Your Model
public class Shop {
String name;
String staffName[];
}
Your Controller
#Controller
#RequestMapping("/shop/list")
public class JSONController {
#RequestMapping(value="{name}", method = RequestMethod.GET)
public #ResponseBody Shop getShopInJSON(#PathVariable String name) {
Shop shop = new Shop();
shop.setName(name);
shop.setStaffName(new String[]{"mkyong1", "mkyong2"});
return shop;
}
}
mvc-dispatcher-servlet.xml
<context:component-scan base-package="com.example.mypackage" />
<mvc:annotation-driven />
Basically, you need check if:
Your Jackson library is existed in the project classpath
The mvc:annotation-driven is enabled
Return method annotated with #ResponseBody
Here we have a basic webapp using JSP which needs to provide a few JSON based REST service URLs.
These urls will all reside under /services and be generated by a MyRestServicesController.
The examples I see for settings up JSON based views all use ContentNegotiatingViewResolver. But it seems like overkill to me as this resolver seems meant for situations where the same URL might produce different output.
I just want my one RestServicesController to always produce MappingJacksonJsonView(s).
Is there a cleaner, more straight forward way to simply direct the controller to do this?
Is there a cleaner, more straight forward way to simply direct the controller to do this?
Yes there is. You can have a look at this sample I posted in Spring forums. In short the way I prefer to do it is through the following.
ApplicationContext:
<!-- json view, capable of converting any POJO to json format -->
<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
Controller
#RequestMapping("/service")
public ModelAndView getResultAsJson() {
Object jsonObj = // the java object which we want to convert to json
return new ModelAndView("jsonView", "result", jsonObj);
}
EDIT 2013: In these modern days, #skaffman's approach would be a nice alternative.
If all you need to do is output JSON, then the view layer itself is redundant. You can use the #ResponseBody annotation to instruct Spring to serialize your model directly, using Jackson. It requires less configuration than the MappingJacksonJsonView approach, and the code is less cluttered.
As long as you are using mvc:annotation-driven and Jackson is on the classpath then all you should need to do is use #ResponseBody on on your methods and the return type will be converted to JSON per Spring's standard HTTP Message Conversion functionality.
Also check out this video at around 37:00: Mastering Spring MVC.