Logging JSON request and response for jersey - java

I have a JAVA web application application, which exposes RESTful apis. My requirement is to log all the JSON requests and responses that are handled by the server.
Is there any parameter like -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump=true for JAX-WS?
I am also exploring AOP approach. What method signature should I add in the AOP pattern?
I am using Tomcat server and jersey for the JAX-RS implementation.

use LoggingFilter. Just add the following to your web.xml:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>

<!-- Enable Jersey tracing support in Glassfish -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
This worked for me (Jersey 2.x)

Related

java rest service through forbidden 403 error

I'm using java to build web api using rest service.
I have add is filter to my web.xml but post request return forbidden 403 error
but when I use get request it works fine.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>POST,GET,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>false</param-value>
</init-param>
</filter>
Here's postman view
When POST is used, the intention from client is to create a resource.
For example,
POST /api/apples/
BODY {color: "green"}
Client issuing this with the intention to create a create apple object at the server side.
GET in other hand is retrieve an object/objects from the server.
For example,
GET /api/apples/
It returns all apples.
If the client posts to an URL and gets 403, it means that your application does not have permission to create object in the server.
add below dependency in your project it's because of the version mismatch of the httpclient. try using version 4.5.3
maven repo link

Configuring provider packages in web.xml with Jersey

I am working on a web service and I get very strange error.
This is the line from my web.xml:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>service</param-value>
</init-param>
As I know, <param-value> has to be referred in to the package my main application is. However, my application is in rest.main package, but the web service works only with the service value as defined above.
What is the problem, can somebody explain me these lines?
Have a look at the documentation regarding the jersey.config.server.provider.packages configuration property:
Defines one or more packages that contain application-specific resources and providers. If the property is set, the specified packages will be scanned for JAX-RS root resources and providers.
Servlet 2.x containers
This setting is frequently used in the web.xml deployment descriptor to instruct Jersey to scan these packages and register any found resources and providers automatically:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
org.foo.myresources,org.bar.otherresources
</param-value>
</init-param>
With this setting, Jersey will automatically discover the resources and providers in the selected packages. By default, Jersey will recursively scan the sub-packages as well.
Servlet 3.x containers
For Servlet 3.x containers, no web.xml is necessary at all. Instead, an #ApplicationPath annotation can be used to annotate a custom Application or ResourceConfig subclass and define the base application URI for all JAX-RS resources configured in the application.
Use the following to defined the packages that will be scanned:
#ApplicationPath("resources")
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("org.foo.myresources,org.bar.otherresources");
}
}
For more details, check the deployment section of the Jersey documentation.
Important
Always use the qualified name of the package;
Use , or ; as delimiter when declaring multiple packages.
You just need to add the package name to the
Form an Example if I have placed my resource class in com.ft.resources package
then I have to add the package name in
<init-param>
<!-- For Jersey 2.x -->
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ft.resources</param-value>
</init-param>
Hope this might resolve your issue
If the application consists only resources and providers stored in particular packages, Jersey can scan them and register automatically.
<web-app>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.foo.rest;org.bar.rest</param-value>
</init-param>
...
</servlet>
...
</web-app>
The param-value refers to the packages which will be scanned automatically.

Generate DTO classes from XSD or by simple POJO classes

I have been working with an enterprise application, where we use SOAP and RESTful Webservices. At some point we have planned to migrate SOAP to RESTful service in order to produce JSON MediaType as response. For SOAP we have been generating dto classes from XSD files. In case of Restful implementation i can directly use POJO classes as my request and response.
Here XML definition is not required. So is it necessary to create new DTO classes generated from xsd or can i create simple POJO classes and use as request and response.
I can configure POJO maping in web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

PreAuthorize annotation doesn't work with jersey

I'm trying to secure a jersey service using spring security annotations without any luck.
I've added this section to web.xml:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.test.proj.ui.web.rest;com.fasterxml.jackson.jaxrs</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.commons.ui.web.jersey.RestApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Also enabled the pre-post-annotations using this on applicationContext:
<global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />
And this is my service class:
#Component
#Path("/user/{uid: .*}")
public class UserResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
#PreAuthorize("hasRole('ROLE_MANAGE_USER')")
public Response getUserDetail(#PathParam("uid") String uid) {
return "Hi, this is a test";
}
}
Spring security works well in authentication but the authorization doesn't work as expected and ignores the PreAuthorize annotation without any error or log.
I'm using Spring 3.2.4 and Spring Security 3.2.1 and Jersy 2.6.
any idea?
thanks
The spring component scan wasn't configured correctly! To solve the problem, only add component scan correctly and it works.
We were facing exactly the same problem. On the business layer #PreAuthorize annotation worked but on the REST resource didn't. The side effect of this situation was that Spring bean injection didn't work as well. Everything without any error.
The 100% working solution was to use RESTEasy instead of Jersey. They are quite similar so it was not much work.

Spring MVC: RESTful web services + BlazeDS integration possible in the same web application?

I have a Spring MVC web application which provides RESTful web services via a controller class (annotated with #Controller) which has methods mapped to specific request types and signatures via #RequestMapping annotations.
I have attempted to integrate a BlazeDS service destination into the mix by 1) adding the HttpFlexSession listener to the web.xml, 2) adding the flex:message-broker and flex:remoting-destination declarations to my Spring application context configuration file, and 3) adding a generic /WEB-INF/flex/services-config.xml.
The above BlazeDS integration steps appear to have hosed my RESTful web services, in that it appears that requests are no longer being routed to the controller methods.
Is it even possible to do this, i.e, to have a single web application which 1) services HTTP requests via request mapped controller methods and 2) services remote object method calls (i.e. from a Flex client) via a BlazeDS service? If so then can anyone tell me what it may be that I'm doing wrong?
Thanks in advance for your help.
Yes, it's possible, but it requires a little extra configuration.
Essentially you need to create two seperate dispatchers, each with a different path.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<name>flex</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<name>spring-mvc</name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
Now requests to http://yourapp/app/somewhere are routed to Spring MVC, and requests to http://yourapp/messagebroker are routed through BlazeDS.
Also, you'll need to split out your spring context files into three:
A common context (named applicationContext.xml in the above example)
One for Spring MVC (named spring-mvc-servlet.xml in the above example)
One for Flex (named flex-servlet.xml in the above example)
Check out this section from the Spring/BlazeDS docs for more info.

Categories