I'm confronted to a problem between two applications that we are using in my company. A CRM called Infonova and a mobile application.
The two applications have their own API, one is giving responses in xml format and the other one in Json.
The solution that I'm thinking to implement is to create an application that will be a facade API (gateway). This application will call the url API of the first application and will get xml response, and I'm thinking to map this solution to a json format and return it.
Since the attributes between xml and json are not the same, I want to know if there's a solution to map the two entities that will represent my responses.
Thanks in advance,
You could define an XML unmarshaller with spring, call your service that returns xml, unmarshal response to that bean. And then you could return this bean in response from a controller annotated with #Produces("application/json").
So, to sum it up. You have a controller that produces json, a bean containing field names you want in your json, and a custom unmarshaller for xml to populate those fields (custom because the field names between json and xml do not match).
Related
I am creating an controller where there is certain attributes in json which is an doing in postman a POST request like this if all attributes are posted then its fine
if one then is missing then it would look like this
i want this response when some attribute is missing how to implement this
This is normally implemented in two steps:
Implement a validation mechanism for the method that handles the incoming request. Normally you would throw an exception here if the input is incorrect, in your example a missing JSON key.
Implement a global error handler that will process the exception from point 1 and format the response as JSON.
For point 1 the usual choice is the Java Bean Validation framework because it's integrated with Spring Boot and allows to define validation constraints with annotations like #NotEmpty. You can take a look at this example.
For point 2 the usual choice is #RestControllerAdvice or #ControllerAdvice. You would have to understand your service web server setup to implement it properly e.g. it might behave differently if you use Spring WebFlux.
Can someone please help clarify and show how to properly go about this issue?
What I understand so far is that the Spring framework uses Message Converters when a method is annotated with #ResponseBody to convert the return Java object to a format that can be accepted by the Client. If the clients' HTTP request Accept Header includes "application/json", it will use Jackson and the Jackson converter to convert the object and return it in a json format. Similarly if the Accept Header includes "application/xml", then the Message Converter will use Jaxb and the corresponding converter to convert the object to xml.
Now my issue is that I include both the Jackson and Jaxb libraries as specified in Spring documentation so that the corresponding converters can work. This should be enough for Spring to employ #ResponseBody as its supposed to. However, when I send an HTTP Request with the Accept header "application/xml" I get a 406 status code and when I send one with "application/json" I receive a correct json response.
From my research online, I see that some people use the ContentNegotiation technique to work around this, but I would like to use the Message Converter for now. However, every technique to make the Message Converter technique to respond to json and xml resource requests involve formatting my POJO with JAXB annotation. Is this really necessary?
I guess what I am asking is how would one set up their project properly so that Spring can use the Message Converter technique to respond to json and xml requests? What libraries must be included? Does one need to add JAXB annotations or is there an automatic way for Spring to format an object into xml the way it does for json?
I thank you for your time and help with this, but so far I am really loving Spring's implementation of JAX-RS!
Before AJAX was popular, it was possible to convert between id's and entities by using a custom property editor and registering that in your controllers. So if you had a User form backing object that contained a Company, if company.id was 5, Spring would call your custom property editor to so that you could go fetch the Company with id 5 and set it onto your user.company property.
Now in the Ajax way of doing things, we have similar requirements. Instead of using a form backing object, we want to do an HTTP POST or PUT of a User object as JSON data and have Spring automatically convert that JSON to a User object on our behalf. Spring has made this possible with the #RequestBody annotation, and by using Jackson to marshall the JSON back and forth to Java objects.
This is just a fictitious example. Imagine a User containing a Company object with the appropriate getters/setters.
#RequestMapping(method = RequestMethod.POST)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void create(#Valid #RequestBody User user) {
userService.saveUser(user);
}
Since property editors are a thing of the past as far as Spring is concerned, we are expected to use the new Conversion Service API. For my application, I have successfully created a factory that does what my old property editor did before - converting id's back to entities.
My question is, how can I get Spring to call into the conversion service during or after Jackson marshals the JSON data? I know it is possible to create a custom JsonDeserializer, but I find writing/testing these to be a pain and lengthy process as I need to do it for a massive number of entities, and each deserializer would take anywhere from 60 to 200 lines of code each.
I'd love it if Spring could do the id to entity mapping for me on my behalf, just as it did for form backing objects. Is there a way?
It will only work the root object User in this case it will not work for nested components. Spring Data REST has a `DomainClassConverter' which you can take a look at.
Basically you want to create ConditionalGenericConverter which checks if it can convert the requested object (i.e. can it be loaded by the EntityManager/SessionFactory). (A non-conditional version is here.
This all goes a bit against REST (basically) to do the lookup on the serverside as you should be sending everything needed with the request (Representational State Transfer and Hypermedia as Transfer Engine of All State). But that is for another discussion :) .
Links
Domain Entity Converter blog
Spring Reference guide
The M. Deinum's answer was great.
But for a practical work , think about AOP ;)
It can be interesting to use it in your problem :).
I am creating a Web Service that will handle incoming request properly (I knew, it is a description) I found some sample code which present SOAP WS and looks like:
#SoapAction("some fine url")
#ResponsePayload
public CertResponse getCert(#RequestPayload Cert param)
{...}
It takes Cert object from request and manages it properly. I want to do it in the REST approach and I changed this class to look like:
#RequestMapping(value="getCert", method = RequestMethod.POST)
#ResponseBody
public CertResponse getCert(#RequestBody Cert param)
{...}
But I have no idea how or even if it is possible to write a client that can send object through HTTP Post.
Can anyone give me a hint how can i send object Cert? Or if i have to stay with #SoapAction what should I do to make it work? I guess removing #Controller is not enough.
In SOAP approach, there is a well defined way to convert each class object to SOAP formatted XML. Thus, there is no effort.
If you will use RESTful approach, you have to describe how your Cert or CertResponse objects will be written to/read from the response/request.
Basically you have three options:
Use JSON or XML or plain String. Convert your Web service descriptor so that the request and response are one of those (JSON, XML, String). Then your getCert method should convert the request to Cert object, prepare your response as CertResponse object and convert it to an appropriate response type.
Leave your getCert method as is. But you need to specify "how Cert objects are read from request" and "how CertResponse objects are written to response" You need to define classes that extend interfaces MessageBodyReader and MessageBodyWriter. In these classes a similar conversion logic should be implemented that converts your objects to/from JSON or XML or String.
In any of these two options you need to implement two things : A method that converts JSON/XML/String to Cert, a method that converts CertResponse object to JSON/XML/String.
You can do a text based implementation, which parses/constructs the request/response by text processing and uses String class only. Or you can use some library such as JSON library with JSONObject class, or Java SAX or DOM based XML libraries that come with the Java bundle.
Check out for application frameworks such as Spring. They might provide ways to automatically convert your objects to JSON or XML, reducing the programming effort necessary.
Spring allows you to pass JSON objects from the client as a request parameters, it will convert them into your objects automatically. This discussion have some examples.
SOAP services are not really compatible with REST semantics. And it's not clear what SOAP framework do you use. Typically most SOAP frameworks offer you one way or another to generate a SOAP client code for you WSDL. You can check cxf.apache.org.
For REST services use something like Jersey or Spring MVC
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.