GenericType unmarshalling fails in spring restful - java

Given below is the scenario in which I am facing difficulty, I am using Restful based webservice in spring MVC where I am ineracting with JSON.
I have a class :
RegexObject and another class RegexObjectDME extends RegexObject.
RegexObject is in one common project, which is being used as it is in webservice consumer and RegexObjectDME in webservice provider.
Now, There is another bean in the same common project, Say HDTaskInfoBean ,
There are two child beans extending HDTaskInfoBean as
HDTaskInfoBeanClient extends HDTaskInfoBean<RegexObject>
and
HDTaskInfoBeanAgent extends HDTaskInfoBean<RegexObjectDME> .
The RegexObjectDME and RegexObject have same properties except a few methods.
HDTaskInfoBeanClient and HDTaskInfoBeanAgent too have same properties and there is generic setter getters for regexObject and regexObjectDME. The T type property name is regexArray.
HDTaskInfoBeanClient is used while making request and HDTaskInfoBeanAgent is used on webservice side.
I am getting the following exception:
Syntactical Error.
Another Scenario I used string as requestbody and tried to unmarshall it into Java Object using Gson() , It gave error:
Request processing failed; nested exception is java.lang.UnsupportedOperationException: Expecting parameterized type, got class com.*.
Are you missing the use of TypeToken idiom?
Please help, I want to use **HDTaskInfoBeanClient ** in Request and HDTaskInfoBeanAgent on webservice provider side. If there is any alternative to it, Kindly suggest.
Thanks in advance :)

I am not sure that why did this weird behavior was shown by default message converter which Comes with Spring Framework.
I found that one of the very good message converter from JSON to Object and back is GSON(A utility by Google) .
One reliable approach to handle such a problem is write your own Custom Message Converter by overriding a class and Using GSON in that. Here is the link for such a solution. I hope it helps you as a solution and would be more reliable.
Regards,
Rahul

Related

how to create json response in spring boot java like this as shown when the following attributes are not present in json request

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.

multiple parameters with no annotation error on Javax WS and retrofit when I use "suspend" , how to handle?

I am creating a very basic controller using Kotlin with javax.ws and retrofit libraries.
I created a controller like this...
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
suspend fun sayHello(request: StudentRequest): StudentResponse {
that basically calls another service.
But when I run the app I get this error:
[FATAL] Method public final java.lang.Object MyResource.sayHello(StudentRequest,kotlin.coroutines.Continuation) on resource class MyResource contains multiple parameters with no annotation. Unable to resolve the injection source.;
handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor#a0bf272]},
definitionMethod=public final java.lang.Object my.org.package.MyResource(sayHello,k**otlin.coroutines.Continuation**),
the weird part is that are couple of similar posts Jersey #PathParam : contains multiple parameters with no annotation
How can I pass multiple parameter to restful webservice using http post
https://github.com/dropwizard/dropwizard/issues/1115
but are not the same because my problem is with my ONLY parameter
There is no missing tag to my body request and I basically dont know what to look for at this point, any idea what could be wrong with this?
After debugging I noticed that there are two parameters, mine and one injected by Kotlin, when removing the "suspend" everything works fine, but then I am not able to make my async call.
To use coroutines from blocking code you need to use coroutine builder (e.g. launch {} or runBlocking {}).
Unfortunately in this case you can't just mark your glassfish controller as a suspendable function because framework don't know how to deal with continuations.

Spring: When to chose which validation method?

I have a Spring application with a JPA Repository. Now I'd like to add some validations. I found several solutions but none works perfect and I don't know which methode should be used in which case:
1.) Im using validation annotations (e.g. #NotNull) in my model object. But this generates a not usefull rest error response like ""Internal Server Error","message":"Could not commit JPA transaction; "
2.) I'm using the 'Validator' interface for custom validations but I get the spring "compiler" error "Validator has incorrect spelling"
3.) Some tutorials use 'ConstraintValidator' interface
4.) Some tutorials write custom rest methods for validations.
When should I use which and how can I solve my problems?
This is how you can manage it and easy is:
Define all your custom message in /messages/messages.properties under resources folder.
so if you error property is: error.user.name = User name can not be null.
then call your specific property in your pojo for that property.
#NotNull(message = "error.user.name")

Spring Data REST Bean Validation

Consider a Person entity with a property name that is annotated as #NotNull. Then a simple PersonRepository and this repo exposed with Spring Data Rest.
When I POST to create a new Person, if the name property is null a ValidationException occurs as expected. But what I actually get on the client is an Internal Server Error (500) and the message is a TransactionSystemException that happened much later in the exception chain.
What I'd expect to get is a Bad Request (400) with the actual ValidationException and all it's useful information so the client can know what's wrong with the posted data.
There seems to be a way to attach custom validators with SDR as explained here. But the thing is, this is not a custom validator, it's a standard bean validation that happens when the repository is asked to save data. So I'm not really sure how those two come together.
So questions:
What are my options to let the client know what's wrong with the submitted data when using SDR?. Things like what fields are invalid and what's the error for each field would be awesome.
Are there any examples about this anywhere?
Thanks a lot.
What you need is a proper ExceptionHandler, it will handle back end exceptions and send meaningful rich messages (json/xml) to the front end client.
Take a look a this git repository

Jersey client proxy not resolving calls to URI with multiple path params

I have the following javax rs annotated interface:
#Path("/")
public interface MyRestEndpoint {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("myapp/resources/resourceId/{resourceId}/memberId/{memberId}")
MyResource findMyResource(#PathParam("resourceId") int resourceId,
#PathParam("memberId") long memberId);
Which I am calling via a jersey proxy client created as such:
MyRestEndpoint myRestEndpointForTests = WebResourceFactory.newResource(MyRestEndpoint.class, lobbyClient().target(myHost));
...
myRestEndpointForTests.findMyResource(resourceId, memberId);
But when I do so, I get the following exception:
java.lang.IllegalStateException: Unresolved variables; only 0 value(s) given for 2 unique variable(s)
at org.glassfish.jersey.client.JerseyWebTarget.getUri(JerseyWebTarget.java:134)
at org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:214)
at org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:59)
at org.glassfish.jersey.client.proxy.WebResourceFactory.invoke(WebResourceFactory.java:312)
at com.sun.proxy.$Proxy89.findCurrentTableOfPlayer(Unknown Source)
Having debugged somewhat through the Jersey codebase, it seems that the WebResourceFactory is trying to create a WebTarget by looping over the annotations on the MyRestEndpoint class. It picks up both annotations, and both provided values but seems to overwrite any previously resolved path params as it loops over them (so its left with only the memberId path param being resolved). Can anyone explain why? Is this a bug or expected behaviour? How can I support multiple path params?
I know this is specific to having more than one path parameter configured via annotation. As I have other methods in the annotated interface that have only one path parameter and work perfectly when called in the same way.
I'm using Jersey v2.16 components and Javax rs v2.0.1 components
Looks like WebResourceFactory is not actively developed also it's source code was quite hard to understand for me.
So we created another implementation of proxing rest interfaces.
Feel free to try https://github.com/adaptris/jaxrs-client-proxy implementation. It's under development currently so for sure have some bugs.

Categories