I am aware of [JsonIgnore] attribute. Unfortunatelly it ignores property on both, the Request and the Response.
I need a way to ONLY ignore it during RESPONSE. Having to work with two different classes for request and response (even by using inheritance) is not an acceptable solution as it introduces a whole a lot of object copying hassle.
Any help is appreciated.
JsonIgnore instructs the JsonSerializer not to serialize the public field or public read/write property value for both request and response.
It sounds like you have a design issue. Create your request/response data contracts separately and more properly.
Related
I'm trying to develop a Jax-RS POST resource, reported here below:
#Path("testJson")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response testJson(Float firstValue, Float secondValue, String thirdValue) {
LOG.info(" firstValue: " + firstValue);
LOG.info(" secondValue: " + secondValue);
LOG.info(" thirdValue: " + thirdValue);
return Response.ok().build();
}
However, i get the following error:
RESTEASY002305: Failed executing POST /aliments/testJson: org.jboss.resteasy.spi.ReaderException: javax.ws.rs.ProcessingException: RESTEASY008200: JSON Binding deserialization error
Searching around, I understood that for a POST method that accepts a JSON, you need to give to it only one parameter, which is in fact the entire JSON message.
My questions are:
Why can't I put two or more parameters? Is that because the Json represents the body part of the message and I can have only one body? Can you explain it better to me please?
I can create a DTO that contains my parameters and use this DTO as one and only parameter for my POST method, but is this the best practice? Doing so, I will have a DTO for each POST method, which actually acts as a Wrapper.
Is there anything I'm missing?
Thank you a lot for your time,
Have a nice day.
Why can't I put two or more parameters? Is that because the Json represents the body part of the message and I can have only one body? Can you explain it better to me please?
JAX-RS allows for one "entity" parameter. This parameter represents the entire request entity. It is determined to be the entity parameter by not having any annotations1. If you want the raw entity, you can use an InputStream parameter. If you want a POJO, you can do so. How the conversion works is with the use of MessageBodyReaders. The reader will be chosen based on the Content-Type header and the parameter type. The framwork comes with some standard readers for easiliy convertable types. For example String, InputStream, byte[]. The reader will get passed the entity stream and it will need to convert the stream to the parameter type. You can read more about "Entity Providers" here.
If you want to use a common media type like JSON, there are libraries that handle JSON/POJO conversion, and from that library, a reader can be made. For JSON, a common librabry is Jackson, and there is a Jackson MessageBodyReader that is provided by the Jackson team.
I can create a DTO that contains my parameters and use this DTO as one and only parameter for my POST method, but is this the best practice? Doing so, I will have a DTO for each POST method, which actually acts as a Wrapper.
Yes, this is very common practice. Get used to it with these type of frameworks.
Is there anything I'm missing?
I don't know, you tell me.
1. Some special annotation are allowed like #Valid for bean validation.
Which annotate the relationship allow Jackson to better handle the relation, for save Click ? How change request:
{ "idBanner": 2, "fullnameClient": "Maria"}
#JsonManagedReference, #JsonBackReference,#JsonIdentityInfo,#JsonIgnore...
Working format-request (save Click):
#RequestParam is used to map just request parameters. For example, it will work for requests like POST /sentemail?fullnameClient=vov&idBanner=1
To get request body you should use #RequestBody annotation.
Important notice
I would recommended don't use models (entities) for requests and responses, because it increases a coupling between your business logic and external contract Rest API. For example, in future you will not able to change model without changing of external contract and vise versa.
But if you still want to use entities as request/response body, I would recommend taking a look on Jackson MixIns. It helps to have separate mapping for Jackson and Entities.
I use Alamofire to interact with the server API via JSON requests/responses. I want to make sure server responds with some strictly formed payload to my requests.
How do I check that, for example, in {"responseCode":15, "data":{"username":"maxpayne", "fullname":"Max Payne", "score":154, friends:["johndoe", "franksinatra"]}}, responseCode is a number, username and fullname are strings, and friends is an array of strings?
I can do it manually for each response, but seems like it's going to be the most worthless time waste.
Alamofire has .validate() method but it is created for different purpose as what I see. I also had a look at JSONSchemaSwift which seems to be a right solution, but is not in active development.
As an alternative, it could be good to have a JSON deserializer which validates a response automatically and creates an object based on a Swift class I define.
May be a bit late, but this came out kylef/JSONSchema.swiftcame out on github. It's a JSONSchema validator, simple and effective.
I have some sensitive domain objects that I would like to convert to json and xml. I am using spring view resolution to do this, but that is beside the point.
I'd like to add annotations to the domain objects to specify which fields should be converted to xml / json.
Something like
#XmlRootElement
public class SensitiveDomainObject {
...
public String getPassword() {...}
#XmlAttribute
#JsonValue
public String getAccountName() {...}
#XmlAttribute
#JsonValue
public String getGoldMemberStatus() {...}
}
I want getAccountName() and getGoldMemberStatus() to be serialised to json and xml, but getPassword to never be serialised.
What I don't want is
1) Separate 'annotation placement strategies' for json and xml as that gets confusing if one needs to markup different methods in different ways as standard.
2) To be explicitly ignoring fields. This is because if some programmer comes along in the future and adds a newly sensitive field without including for example the #JsonIgnore annotation, suddenly that sensitive field is shared.
3) To have to make methods like getPassword() private. I still want to be able to call getPassword() internally.
Has anyone done this or have any thoughts?
EDIT
Included a picture from IBM showing essentially the design I ran with, with explicit DTOs with annotations in the business logic layer. The presentation layer figures out which DTO to request and serve based on the incoming URL.
If you care so much about differentiating what you your business classes are and what is transferred, you may consider implementing a separate package of DTO classes which will explicitly include only those properties you'd like to transfer.
In this case you'll have to explicitly include the transfer properties, this can't happen because the programmer forgot it.
There are other approaches to this like adding some validation rules that the property like password is ignored and enforce them on JAXB context level. But this will only work until someone not knowing will name it kennwort or credentials or whatever may come in mind and your validation rules will be out of effect.
So I see two way:
* Either you trust the programmer (and all the QA/QS process like code reviews etc.) to support her/him.
* Or you make your transfer classes explicit.
For important external interfaces I'd probably go with the second approach (explicit DTOs). If password ends up there, it can't be by forgetting, it will only be on purpose.
I'm developing a RESTful interface which is used to provide JSON data for a JavaScript application.
On the server side I use Grails 1.3.7 and use GORM Domain Objects for persistence. I implemented a custom JSON Marshaller to support marshalling the nested domain objects
Here are sample domain objects:
class SampleDomain {
static mapping = { nest2 cascade: 'all' }
String someString
SampleDomainNested nest2
}
and
class SampleDomainNested {
String someField
}
The SampleDomain resource is published under the URL /rs/sample/ so /rs/sample/1 points to the SampleDomain object with ID 1
When I render the resource using my custom json marshaller (GET on /rs/sample/1), I get the following data:
{
"someString" : "somevalue1",
"nest2" : {
"someField" : "someothervalue"
}
}
which is exactly what I want.
Now comes the problem: I try to send the same data to the resource /rs/sample/1 via PUT.
To bind the json data to the Domain Object, the controller handling the request calls def domain = SampleDomain.get(id) and domain.properties = data where data is the unmarshalled object.
The binding for the "someString" field is working just fine, but the nested object is not populated using the nested data so I get an error that the property "nest2" is null, which is not allowed.
I already tried implementing a custom PropertyEditorSupport as well as a StructuredPropertyEditor and register the editor for the class.
Strangely, the editor only gets called when I supply non-nested values. So when I send the following to the server via PUT (which doesn't make any sense ;) )
{
"someString" : "somevalue1",
"nest2" : "test"
}
at least the property editor gets called.
I looked at the code of the GrailsDataBinder. I found out that setting properties of an association seems to work by specifying the path of the association instead of providing a map, so the following works as well:
{
"someString" : "somevalue1",
"nest2.somefield" : "someothervalue"
}
but this doesn't help me since I don't want to implement a custom JavaScript to JSON object serializer.
Is it possible to use Grails data binding using nested maps? Or do I really heave to implement that by hand for each domain class?
Thanks a lot,
Martin
Since this question got upvoted several times I would like to share what I did in the end:
Since I had some more requirements to be implemented like security etc. I implemented a service layer which hides the domain objects from the controllers. I introduced a "dynamic DTO layer" which translates Domain Objects to Groovy Maps which can be serialized easily using the standard serializers and which implements the updates manually. All the semi-automatic/meta-programming/command pattern/... based solutions I tried to implement failed at some point, mostly resulting in strange GORM errors or a lot of configuration code (and a lot of frustration). The update and serialization methods for the DTOs are fairly straightforward and could be implemented very quickly. It does not introduce a lot of duplicate code as well since you have to specify how your domain objects are serialized anyway if you don't want to publish your internal domain object structure. Maybe it's not the most elegant solution but it was the only solution which really worked for me. It also allows me to implement batch updates since the update logic is not connected to the http requests any more.
However I must say that I don't think that grails is the appropriate tech stack best suited for this kind of application, since it makes your application very heavy-weight and inflexbile. My experience is that once you start doing things which are not supported by the framework by default, it starts getting messy. Furthermore, I don't like the fact that the "repository" layer in grails essentially only exists as a part of the domain objects which introduced a lot of problems and resulted in several "proxy services" emulating a repository layer. If you start building an application using a json rest interface, I would suggest to either go for a very light-weight technology like node.js or, if you want to/have to stick to a java based stack, use standard spring framework + spring mvc + spring data with a nice and clean dto layer (this is what I've migrated to and it works like a charm). You don't have to write a lot of boilerplate code and you are completely in control of what's actually happening. Furthermore you get strong typing which increases developer productivity as well as maintainability and which legitimates the additional LOCs. And of course strong typing means strong tooling!
I started writing a blog entry describing the architecture I came up with (with a sample project of course), however I don't have a lot of time right now to finish it. When it's done I'm going to link to it here for reference.
Hope this can serve as inspiration for people experiencing similar problems.
Cheers!
It requires you to provide teh class name:
{ class:"SampleDomain", someString: "abc",
nest2: { class: "SampleDomainNested", someField:"def" }
}
I know, it requires different input that the output it produces.
As I mentioned in the comment earlier, you might be better off using the gson library.
Not sure why you wrote your own json marshaller, with xstream around.
See http://x-stream.github.io/json-tutorial.html
We have been very happy with xstream for our back end (grails based) services and this way you can render marshall in xml or json, or override the default marshalling for a specific object if you like.
Jettison seems to produce a more compact less human readable JSON and you can run into some library collision stuff, but the default internal json stream renderer is decent.
If you are going to publish the service to the public, you will want to take the time to return appropriate HTTP protocol responses for errors etc... ($.02)