I'm using web services and I want to step it up a notch. I'm using Axis2 with JAX-WS. I'm thinking of transfering objects instead of String[]. After I googled a bit, I found that JAXB is the right support to do this.
However, everytime I want to add a modelclass that needs to be transferred, I need to do a lot of work (to shut up about all the annotations where I can make mistakes). So I thought it would be easier to abstract this a bit.
I was thinking of creating web services using the Object type. I can then use methods as addObject(Object object), removeObject(Object object), retrieveObject(). This means my server needs to handle incomming objects. If I then add a new model class, I just need to catch it at server end. My client will need to include the model classes causing some redundancy but I'm OK with that. I have the feeling that Java cannot support my idea at this momemnt. At least JAX-WS & JAXB technologies.
Can you guys tell me if I'm right or wrong about this, if this is a good idea or not and if so, maybe point me into the right direction on how to fix this (even if it means using another technology)
Thanks in advance!
Your client won't need a model type, but you will have to serialize and deserialize your data when you send messages from your server to your client. I'm not sure if JAX-WS is different from JAX-RS, but if they are the same, then you can add annotations that mark whether or not you want to produce/consume json or xml.
Once you serialize your model to json, your client will have no problem reading your data.
Also, yest you can use object when creating request and response objects. In a webservice that I recently wrote I created a service response class similar to this
public class Response
{
private Object data;
private boolean success;
public Response()
{
super();
}
//write getters and setters here
}
I think that I'm using the Object class in a similar fashion to what you have in mind.
I definitely recommend you JAX-RS (implementing JAXB), in particular using the Jersey framework. It's usage is simple and allow you to marshall and unmarshall business objects.
Look at this Jersey Example
Hope it helps!
Related
I'm passing a Java object to a Web service that accepts json, using HttpURLConnection.
Employing com.fasterxml.jackson to convert the object to json string and then writing it to the output stream, the service works fine for simple dummy POJOs, but the application breaks when I use a complex object that I'm originally intend to send,
with the console filled with exceptions like StackOverflow and endless clutter of
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
at
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
Common solutions are like annotating the class with json annotation.
Is there any other way to get around it, like using different accept:content-type for web service (other than json or xml as they require annotated objects) or like that?
You can use mixin annotations to provide hints for Jackson on how to serialize your data, without polluting the POJO with unnecessary dependencies.
Here's the reference to documentation article, that has good example:
http://wiki.fasterxml.com/JacksonMixInAnnotations
I'm trying to learn Spring Boot by implementing a simple REST API.
My understanding was that if I need to transfer an object over the wire, that object should implement Serializable.
In many examples on the net though, including official ones, domain classes that need to be transferred from server to client (or vice-versa) do not to implement Serializable.
For instance: https://spring.io/guides/gs/rest-service/
But in some cases, they do:
For instance: https://github.com/szerhusenBC/jwt-spring-security-demo/blob/master/src/main/java/org/zerhusen/security/JwtAuthenticationRequest.java
Is there a general rule of thumb on when to implement Serializable?
To update this, advice about Serializable has changed, the recommendation currently seems to be Don’t use Serializable for anything.
Using the Java serialization API means you need something in Java on the other side of the wire to deserialize the objects, so you have to control the code that deserializes as well as the code that serializes.
This typically isn't relevant for REST applications, consuming the application response is the business of someone else's code, usually outside your organization. When building a REST application it's normal to try to avoid imposing limitations on what is consuming it, picking a format that is more technology-agnostic and broadly available.
Some reasons for having an object implement java.io.Serializable would be:
so you can put it in an HttpSession
so you can pass it across a network between parts of a distributed application
so you can save it to the file system and restore it later (for instance, you could make the contents of a queue serializable and have the queue contents saved when the application shuts down, reading from the save location when the application starts to restore the queue to its state on shutdown).
In all these cases, you serialize so you can save something to a filesystem or send it across a network.
There are many ways to serialize an object. Java's object serialization is just one of them. From the official documentation:
To serialize an object means to convert its state to a byte stream
REST APIs usually send and receive JSON or XML. In that case serializing an object means converting its state to a String.
There is no direct connection between "sending an object over the wire" and implementing Serializable. The technologies you use dictate whether or not Serializable has to be implemented.
The specific examples you have mentioned do not transfer objects over the wire. From the example links I see that the controller methods return a domain object with ResponseBody annotation. Just because the return type of the method is the domain object it is not necessary that the whole object is being sent to the client. One of the handler method in Spring mvc framework internally intercepts the invocation and determines that the method return type does not translate to direct ModelAndView object. RequestResponseBoodyMethodProcessor which handles the return value of such annotated methods and uses one of the message converters to write the return object to the http response body. In the case the message converter used would be MappingJackson2HttpMessageConverter. So if are to follow the same coding style you are not required to implement Serializable for your domain objects.
Have a look at this link for the Http message converters provided by default from spring. The list is quiet extensive however not exhaustive and if requirements arise you can implement your own custom message converter to user as-well.
that's a good question when to implement Serializable interface.
these links can provides some useful contents:
Serializing java.io.Serializable instance into JSON with Spring and Jackson JSON
When and why JPA entities should implement the Serializable interface?
I sometimes wonder about this, and I think
Because Java is a open source language, and more libraries providered by third party. for tells who will serialize and deserialize the object, the java offical declare a constract interface, makes transfer easy and safety throught different library.
It's just a constract, most third-party libraries can serialize/deserialize when checking implement this constract. and jackson's jar library is not use it.
So you can deem if you use serialize/deserialize object data in your own system, and simple process, likes just serialize and response it(jackson in spring MVC), you needn't to implements it.
but if you used in other jar library, likes saving in HttpSession, or other third-party componens/library, you should(or have to) implement Serializable, otherwise the libraries will throw a exception to tell you the constract interfaced which it knows is not provide.
But they said it's a good habit and best properties that to implement the Serializable when serialize a custom class. :)
you should serialize if you are using caching for database operations.Usually the third party cache providers like (hazle cast, Jboss cache etc..) internally serialize/ de serialise objects.In that case model classes should implement Serializable to facilitate caching.
We have a front-end service that uses a back-end service to get a list of Metric objects. We've written a Java ClientSDK for the back-end service to make life easier for development of client applications of that service.
We also expose a list of Metrics from the front-end service. For now, we're directly exposing and converting the back-end Metric objects to JSON.
My concern is that if changes are made to the back-end Metric object - say a developer adds a new secret ID field - we don't want to expose it from the front-end service.
We're also writing a clientSDK for the front-end service. We don't want to reference the Metric class from the back-end clientSDK, so the logical option is to define a similar Metric object in the front-end SDK.
I don't want to waste CPU cycles copying 1000's of Metrics from one class definition to another.
Is there a way to specify which fields I should expose from the back-end Metric to the front-end definition of Metric as I'm converting to JSON? Better yet, can I reference the front-end definition to the JSON converter as I ask it to marshal the back-end object?
We're using Jackson with the Spring rest framework for context, but I'd be happy to drop that in a heartbeat since marshaling objects via annotations seems to be the root cause of this problem.
Take a look at Jackson's JsonView construct.
I can see your example looking something like this:
class Views {
static class Client {}
static class Backend extends Client {}
}
public class Metric {
#JsonView(Views.Client.class) String metricName;
#JsonView(Views.Client.class) String count;
#JsonView(Views.Backend.class) String secretKey;
}
The #JsonView annotation is supported on Spring #ResponseBody annotated methods as of Spring 4.1.
As Nicholas Hausschild has suggested you can achieve this by annotations with your marshalling/unmarshalling framework.
However you can simply use inheritance and casting like this:
class SomeSuperClass {
String exposeThis;
String exposeThat;
// getters and setters...
}
class SomeSubClass extends SomeSuperClass {
String doNotExposeThis;
// getters and setters...
}
This way you can cast to the super class when returning an object to the JSON parser, and at the same time use the subclass internally to carry additional information which you don't really want to expose.
Another possibility is the use of Mixins, so you can define different scenarios without touching the original DTO.
I myself use a library I wrote to achieve this dynamically:
https://github.com/Antibrumm/jackson-antpathfilter
This works well for not too deep graphs, else someone wrote another approach in a similar way here which seems more performant for these scenarios, but behaves a bit different.
https://github.com/krishna81m/jackson-nested-prop-filter
I am trying to use axis2-wsdl2code-maven-plugin for auto generating the server side class files from a wsdl.
I am not sure how to implement the SkeletonInterface to call the business logic. There is an auto-generated Skeleton file which implements the interface, but it has a un-implemented method in it.
The problem is that I am not allowed to modify auto-gen files hence not sure on how to implement the method.
Below are the things that I have tried:
Few issues that I am facing:
i. Tried to rename the interface implementation class and call it through service.xml, but the new impl was not being called. (AuthenticatedServicesValidSkeletonImpl.java)
ii. Tried to extend the Skeleton class, but got null pointer exception while deploying the application and there was nothing much which I could get from the logs.
iii. Tried with cfx plugin for auto-generation of classes as well, but getting similar issues in it.
Please help regarding this.
You need to put your business logic in the un-implemented method in the AuthenticatedServicesValidSkeletonImpl.java. This will provide you a POJO of Request, and at the end, you need to return back a POJO of Response which will then be serialized into the WebService Response. The Request and Response objects are already created by WSDL2java, you just need to use them.
I was wondering if is it possible to force the rest framework in java to return the actual implementation of some class instead of information that is only visible in the abstract class.
So I have a method that looks like
#GET
#Path("/}")
public Model getModel() {
return (Car) system.getCar();
}
So I would like that when ever someones hits this path to what is returned is the information about the CAR and not just what is contained in the model. Is it possible to force this behavior with some annotations?
PS The example above is just for demonstration. The actually reason is that I have a class that has a parameter of the abstract class and I would like to see the information in the xml about the concrete implementation so that I know what type it is.
Thanks for assistance.
cheers
EDIT
To tell you truth I have no idea what is the implemenation. But maybe this artical about what I use can help you http://docs.codehaus.org/display/TYNAMO/tapestry-resteasy+guide
I tested this in my REST project, it works without any extra work. I am using RestEasy framework to implement REST webservices. I checked this for XML as well as JSON datatype. For JSON serialization I am using jackson library.
The REST implementation serializes an actual concrete instance of a class (not an abstract class, since you cant have an instance of an abstract class anyway) into the requested content type, for eg, JSON or XML.
What gets serialized is the domain object's fields based on their mappings.
You can control what fields of the domain object gets serialized, or you can create a custom POJO with only fields that you want to send in the response.
It is not working on my JSON (with JACKSON), and I think it indeed should not work.
If your API provides a Model then it should not return Car fields. The executor of the API might not be able to parse the returned Car fields, since expected a Model.
This would be kind of up-casting which is generally shows a bad design. IMHO.
I liked the question though :)