how to resolve the java.lang.reflect.InvocationTargetException in maven - java

the my web-app working fine in eclipse and the Netbeas but when i try to execute in maven after include the dependency its throwing exception.The dependency is.
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle-jaxrs</artifactId>
<version>2.1.2</version>
</dependency>
This dependency i include because i am using the
ResponseBuilderImpl builder = new ResponseBuilderImpl()
if i remove the builder and dependency then its work in maven but when i included then its giving exception.this is my rest sample rest code.
#Path("/{userId}/logout")
#PUT
public Response logout(#PathParam ("userId") String userId,#Context HttpServletRequest request,#Context HttpServletResponse response)throws ServletException, IOException
{
ResponseBuilderImpl builder = new ResponseBuilderImpl();
log.debug("request user id for logout::"+userId);
MapUserLogin mapUserLogin=new MapUserLogin();
mapUserLogin.removeMap(userId);
log.debug("after remove userinformation from hashmap");
System.out.print("LOGOUT SUCCESSFULLUY");
builder.status(200).entity("SUCCESS");
return builder.build();
}
so for the ResponseBuilderImpl i imported the import org.apache.cxf.jaxrs.impl.ResponseBuilderImpl
if i remove and just return string types then its work but when i am using this above code then only maven is throwing exception The exception is.
INFO: Deployed Application(path=C:\App\apache-tomee-jaxrs-1.5.2\webapps\Snefocaremaven)
Oct 01, 2013 10:51:10 AM org.apache.openejb.observer.ObserverManager fireEvent
SEVERE: error invoking org.apache.openejb.observer.ObserverManager$Observer#21d4f61d
java.lang.reflect.InvocationTargetException

Unless you have a good reason to use the CXF-specific ResponseBuilderImpl you should use the static factory methods of the JAX-RS Response class to obtain a ResponseBuilder, e.g.
Response response = Response.status(200).entity("SUCCESS").build();
The JAX-RS framework will use an internal mechanism to load and initialize the correct implementation. Note that you should not need the CXF dependency at compile time, unless you are using proprietary features.
update:
ResponseBuilder partial = Response.status(200);
Will create a mutable builder instance, which can be further modified. Note that you should also be able to modify the status on the builder. Unfortunately (?) there is no "plain" factory method available from the JAX-RS API. I would suggest to first try out the creation of a Response this way and check, whether it works or if there are more subtle problems.
ResponseBuilder partial = Response.status(200); // mock status
ResponseBuilder filled = fillResponse(partial); // whatever the method is called
return filled.build();
Then you can think about refactoring to get rid of the creation of the builder with a mock status, for example by moving the whole response building into a method that knows the entity and response code.

Related

Unable to test Jax-rs with JSON entity

I am trying to test a Jax-rs resource by following this https://jersey.java.net/documentation/latest/test-framework.html,
and I am using container jersey-test-framework-provider-jdk-http
I can assert status code. However, when I try to readEntity, I get exception:
javax.ws.rs.ProcessingException: Unable to find a MessageBodyReader of content-type application/json and type class java.lang.String
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:39)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:73)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:50)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:248)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:181)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:217)
My Resource Class:
#Path("/")
public class SampleResource {
#GET
#Path("/health")
#Produces(MediaType.APPLICATION_JSON)
public String getServiceStatus() {
return "{\"Status\": \"OK\"}";
}
}
My Test Class:
public class TestSampleResource extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(SampleResource.class);
}
#Test
public void testHealthEndpoint() {
Response healthResponse = target("health").request(MediaType.APPLICATION_JSON).get();
Assert.assertEquals(200, healthResponse.getstatus()); // works
String body = healthResponse.readEntity(String.class);
Assert.assertEquals("{\"Status\": \"OK\"}", body);
}
}
Can anyone please help?
The problem comes from having both Jersey and RestEasy client on the classpath. When you call target() on the JerseyTest, the WebTarget is obtained from a Client that is built by calling ClientBuilder.newClient().
The ClientBuilder is a standard JAX-RS API, and it is implemented first to search for an implementation of ClientBuilder through the META-INF/services files, looking for a file named javax.ws.rs.client.ClientBuilder, whose content is the name of an implementation of the ClientBuilder. If no such file is found, it defaults to looking for JerseyClientBuilder.
jersey-client has no such file META-INF/services/javax.ws.rs.core.ClientBuilder because it's ClientBuilder is the default for JAX-RS client. If you look in your resteasy-client jar, you will see the it does have that file. And if you look in the contents of that file, you will see the ResteasyClientBuilder as the implementation.
So even though you are using Jersey's test framework, the Client being used, is RESTeasy's implementation. And I guess all the standard configurations with entity providers never gets configured. Conversion between String and application/json is one of those standard providers you need in your case.
I would say just explicitly use Jersey client implementation. You will no longer be able to call target on the JerseyTest. You will need to explicitly create the client
#Test
public void dotest() {
final Client client = new JerseyClientBuilder().build();
WebTarget target = client.target("http://localhost:9998");
final Response response = target.path("health").request().get();
final String json = response.readEntity(String.class);
}
The default base path for JerseyTest is http://localhost:9998, so I explicitly create the WebTarget with that.
Note that I said the String to/from application/json is supported by standard providers. So if you will only be serializing Strings, then you don't need anything else. If you want POJO serialization support for the Jersey client (and server side), you should add the following
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey2.version}</version>
<scope>test</scope>
</dependency>
I suspect the json parser in your test is being misguided by the presence of curly braces. Basically it thinks you are returning a json object, not a json string. Try returning "Status:OK"
As the exception says you are missing a MessageBodyReader for content-type application/json. Do you have JacksonJsonProvider on your classpath? It can be added as a dependency to jackson-jaxrs-json-provider:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.7.3</version>
</dependency>
Then register the JacksonJsonProvider in your test application:
#Override
protected Application configure() {
return new ResourceConfig(SampleResource.class, JacksonJsonProvider.class);
}

Configure Response object for Rest Services inside a Jersey-Grizzly server, in OSGi container (CORS error prevention with Jersey 1x)

The last couple of days, I have been struggling with an issue. I've created a rest service hosted by a Grizzly server inside an OSGi container. Everything is working perfectly at this point.
Now, I want to add a header in every response.Not so complex or illogical right? Yet, I can't find a way to do it.
I have tried to:
1) Get the response object inside the rest functions as this question suggests (pretty textbook when you are not under OSGi).
2) Add a handler using the code above (in this case the service method is never called)
server.getServerConfiguration().addHttpHandler(
new HttpHandler() {
#Override
public void service(Request arg0, Response arg1)
throws Exception {
arg1.setHeader("Access-Control-Allow-Origin", "*");
}
});
I am using jersey-server/client/core 1.18.1 and grizzly2-server 1.18.1, hence i prefer a solution that can be applied in this version, but I am willing to update jar versions if it cannot be done in 1.18.x.
You could give a try to Jersey filters.
In a nutshell, you should create class implementing ContainerResponseFilter:
public class MyFilter implements ContainerResponseFilter {
#Override
public void filter(
ContainerRequest request,
ContainerResponse response
) throws IOException {
request.getHttpHeaders().add(<header name>, <header value>);
}
}
Then, you should register this filter in your Jersey server configuration.
Please, note, that this filter would be invoked on every response. To bind it only to specific resources, you could use annotation-binding, that is described here.
All other information you could find here.

Using #BeanParameter with Jersey

I am creating an restfull webservice using JAX-RS, I've started developing using Wildfly 8.2 and JEE7 and I was able to achieve this:
endpoint search method:
#GET
#Path("/consultar")
public Response consultar(
#QueryParam("offset") #DefaultValue(value = "0") Integer offSet,
#QueryParam("limit") #DefaultValue(value = "10") Integer limit,
#NotNull #BeanParam EmpresaDTO filtro) {
return super.consultar(offSet, limit, filtro);
}
endpoint abstraction search method:
#Override
public Response consultar(Integer offSet, Integer limit, #NotNull Object filtro) {
T filtroMaterializado = mapper.map(filtro, getClassType());
Example example = getExampleGenerator().generate(filtroMaterializado);
List<T> lista = getRepository().listar(offSet, limit, example);
return getOkResponse(lista);
}
Thats was working until I had the requisite of migrating to Tomcat, then I pick Jersey as my JAX-RS implementation. Now I get an big big error stacktrace, followerd by this warning at server startup:
WARNING: A HTTP GET method, public javax.ws.rs.core.Response br.com.logtec.delivery.resource.AbstractResource.consultar(java.lang.Integer,java.lang.Integer,java.lang.Object), should not consume any entity.
I've googled and I've found this: Using #Consume with GET request in Jersey Rest
But I rather stick with the javax api default annotation #BeanParam, furthermore theres no such annotation #InjectParam into jersey-container-servlet dependency.
So what I ask is, is there a way of using #BeanParam at #GET method? If not, how can I include #InjectParam without including the hole glassfish-embedded-web dependency?
Nevermind, I figured it out. The problem was that my Resource interface abstract methods were annotated by #GET, #POST... I ripped them out and it was solved. Thanks anyway

Building simple http-header for Junit test

I'm trying to test a HttpServletRequest and for that I have used Mockito as follow:
HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
now before putting the http-request in assert methods I just want to build a simple http header as below without starting a real server:
x-real-ip:127.0.0.1
host:example.com
x-forwarded-for:127.0.0.1
accept-language:en-US,en;q=0.8
cookie:JSESSIONID=<session_ID>
can some one help how can I build such a test header? thanks.
You can just stub the calls to request.getHeaders etc. or if you can add a dependency, Spring-test has a MockHttpServletRequest that you could use (see here)
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("x-real-ip","127.0.0.1");
Or you could build your own implementation which allows you to set headers.
The above answer uses MockHttpServletRequest.
If one would like to use Mockito.mock(HttpServletRequest.class) , then could stub the request as follows.
final HttpServletResponse response = mock(HttpServletResponse.class);
when(request.getHeader("host")).thenReturn("stackoverflow.com");
when(request.getHeader("x-real-ip")).thenReturn("127.0.0.1");

CXF Custom Validation Interceptor with custom response not working

I am trying to write a Custom CXF Interceptor to do some validations on SOAP request to a web service. Based on the validation results, I want to block the request to web service and return the response with some modified parameters.
For this, I have written custom CXF ininterceptor extending from AbstractPhaseInterceptor, to run in phase USER_LOGICAL, which does validations, but I am not able to stop the subsequent call to web service and also not able to pass the Custom Response object(Custom Response object type is same as web service return type). How can I do this using interceptors?
I did some research upon the tip from nadirsaghar and I found it to be the cleanes solution available. Using message.getExchange() in JAX-WS is a complete pain, since you have to setup a conduit and fill the response message yourself...
So better do it this way, using HttpServletResponse. - You need to have the java servlet-api.jar on your Path. If you're developing without maven, just link it from your webserver (e.g. tomcat) directory, but exlude it from deployment.
<!-- With Maven add the following dependency -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<!-- The version should match your WebService version e.g. 3.0 for JDK7-->
<version>2.5</version>
<scope>provided</scope>
</dependency>
With scope provided it will not be deployed and is just available so you can access the HttpServletResponse class.
Your Handler Code:
#Override
public void handleMessage( final Message message ) throws Fault
{
if( shouldBlockMessage( message ) )
{
message.getInterceptorChain().abort();
final HttpServletResponse response = (HttpServletResponse)message.get( AbstractHTTPDestination.HTTP_RESPONSE );
// To redirect a user to a different Page
response.setStatus( HttpServletResponse.SC_MOVED_TEMPORARILY );
response.setHeader( "Location", "http://www.bla.blubb/redirectPage" );
// Other possibility if a User provides faulty login data
response.setStatus( HttpServletResponse.SC_FORBIDDEN );
}
}
You can abort execution of the interceptorChain including the webservice using abort method
public void handleMessage(SoapMessage message) {
InterceptorChain chain = message.getInterceptorChain();
chain.abort();
}
Something like this, there is no need to play with Interceptor chain.
public void handleMessage(Message message) {
//your logic
Response response = Response.status(Status.UNAUTHORIZED).type(MediaType.APPLICATION_JSON).build();
message.getExchange().put(Response.class, response);
}

Categories

Resources