Jersey integration with Spring MVC - rest

I want to create a website that is able to work with rest with an android application.
For these rest-calls I want to make use of a seperate servlet
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Stage XT-i</display-name>
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-servlet.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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.config.property.packages</param-name>
<param-value>be.kdg.teamf</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
As you can see al the jersey information is passed using the url: /rest/*
When I want to do a GET for a string using the url: localhost:9999/rest/user/sample it work perfectly.
However when I use #Autowired with jersey I get a nullpointer exception.
Java class:
#Path("/user")
public class UserRest {
#Autowired
private UserService userService;
#Context
UriInfo uriInfo;
// Another "injected" object. This allows us to use the information that's
// part of any incoming request.
// We could, for example, get header information, or the requestor's address.
#Context
Request request;
// Basic "is the service running" test
#GET
#Produces(MediaType.TEXT_PLAIN)
public String respondAsReady() {
return "Demo service is ready!";
}
#GET
#Path("sample")
#Produces(MediaType.APPLICATION_JSON)
public User getUserJson() {
User u = userService.listUsers().get(0);
System.out.println("Returning person");
return u;
}
}
Does anyone see the problem?
Thanks in advance.

Use Spring Jersey integration servlet
com.sun.jersey.spi.spring.container.servlet.SpringServlet

Related

Weblogic: The servlet is referenced in servlet-mapping but not defined in web.xml

Getting this error why trying to deploy the war in weblogic
Caused By: weblogic.management.DeploymentException: [HTTP:101170]The
servlet Web Rest Services is referenced in servlet-mapping /myrest/*
but not defined in web.xml.
at weblogic.servlet.internal.WebAppServletContext.verifyServletMappings(WebAppServletContext.java:1465)
at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:2809)
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1661)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:822)
at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
my web.xml:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>REST</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<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.config.property.packages</param-name>
<param-value>rest.apis</param-value>
</init-param>
<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>
<servlet-mapping>
<servlet-name>Web Rest Services</servlet-name>
<url-pattern>/myrest/*</url-pattern>
</servlet-mapping>
</web-app>
If required I can paste the code of rest resources but not sure it matters.
What worries me, can there be issue with weblogic?
Note: Recently app server was upgraded to weblogic 12.1.2
<servlet-name --> Jersey Web Application != Web Rest Services
The <servlet-name> in the <servlet-mapping> should correspond to a <servlet-name> in a <servlet> definition. Hence the error
The servlet Web Rest Services is referenced in servlet-mapping /myrest/* but not defined in web.xml
Try this configuration for your web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>NAME</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>YOUR REST CLASS PACKAGE</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
</web-app>
And create an weblogic.xml file in the same folder (web-app\WEB-INF) like this:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
<library-ref>
<library-name>jax-rs</library-name>
<specification-version>2.0</specification-version>
<implementation-version>2.5.1</implementation-version>
<exact-match>false</exact-match>
</library-ref>
<container-descriptor>
<prefer-application-packages>
<package-name>org.glassfish.jersey.media.*</package-name>
<package-name>org.glassfish.jersey.client.*</package-name>
<package-name>org.glassfish.jersey.servlet.*</package-name>
<package-name>org.glassfish.jersey.jaxb.internal.*</package-name>
<package-name>com.sun.research.ws.wadl.*</package-name>
<package-name>org.glassfish.hk2.*</package-name>
<package-name>org.jvnet.hk2.*</package-name>
<package-name>jersey.repackaged.org.objectweb.asm.*</package-name>
<package-name>org.objectweb.asm.*</package-name>
<package-name>com.sun.ws.rs.ext.*</package-name>
<package-name>org.aopalliance.*</package-name>
<package-name>javax.annotation.*</package-name>
<package-name>javax.inject.*</package-name>
<package-name>javax.ws.rs.*</package-name>
<package-name>jersey.repackaged.com.google.common.*</package-name>
<package-name>javassist.*</package-name>
</prefer-application-packages>
</container-descriptor>
<context-root>YOUR_ROOT</context-root>
</weblogic-web-app>

JPetShop and Azure Application Insight

I would like to to test the Application Insight tool of Microsoft Azure.
For this reason, I took a Spring application, jpetshop (https://github.com/mybatis/jpetstore-6), and I am trying to set up the Application Insight on top of it following this guide: https://learn.microsoft.com/en-us/azure/application-insights/app-insights-java-get-started
I added the Maven dependency and repository and, thanks to Eclipse, I created the ApplicationInsights.xml file with my InstrumentationKey. The only thing that I am not sure about is how to add is the HTTP filter on this application.
I modified the web.xml in this way:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>JPetStore</display-name>
<description>Online Pet Store Sample Application</description>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>StripesResources</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>org.mybatis.jpetstore.web</param-value>
</init-param>
<init-param>
<param-name>Extension.Packages</param-name>
<param-value>net.sourceforge.stripes.integration.spring</param-value>
</init-param>
<init-param>
<param-name>ApplicationInsightsRequestNameInterceptor</param-name>
<param-value>com.microsoft.applicationinsights.web.struts.RequestNameInterceptor</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>net.sourceforge.stripes.controller.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
However, if I change the filter-mapper field as shown in the guide, the application doesn't work anymore.
Since the jpetshop application uses the Spring framework I also though to modify the *-servlet.xml file. However, this file is not present in this project.
Do you know how can I make the Azure Application Insight work on this application?
Thank you
I think you missed the section where you need to define ApplicationInsights's filter:
<filter>
<filter-name>ApplicationInsightsWebFilter</filter-name>
<filter-class>
com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>ApplicationInsightsWebFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Viewable route returns 404

When trying to access /Example/Site a 404 no found page will be shown, but the jsp is in webapp/WEB-INF/jsp/. Why is this not working?
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>jmattheis rest app</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-servlet</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.stackoverflow.jmattheis.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.servlet.filter.forwardOn404</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.mvc.jsp.JspMvcFeature</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.mvc.templateBasePath.jsp</param-name>
<param-value>/WEB-INF/jsp</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.tracing</param-name>
<param-value>ALL</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Here the Resource:
#Component
#Path("Example")
public class Example {
#GET
#Path("/Site")
#Produces(MediaType.TEXT_HTML)
public Response getSite() {
return Response.ok(new Viewable("/test")).build();
}
}
Have a look at the Jersey2 MVC documentation
Jersey web applications that want to use JSP templating support should be registered as Servlet filters rather than Servlets in the application's web.xml. The web.xml-less deployment style introduced in Servlet 3.0 is not supported at the moment for web applications that require use of Jersey MVC templating support.
So you need to change your servlet to an filter to make it work.
It could be that this was not needed in the early versions of jersey 2, but I cannot find the older documentation for that so we'll never know.
Like this:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>jmattheis rest app</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>jersey-filter</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.stackoverflow.jmattheis.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.servlet.filter.forwardOn404</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.server.mvc.jsp.JspMvcFeature</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.mvc.templateBasePath.jsp</param-name>
<param-value>/WEB-INF/jsp</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.tracing</param-name>
<param-value>ALL</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

CORS Filter is not changing my header

I have a maven project (with web and JPA facets) in Eclipse Java EE IDE for Web Developers. I have added the jars to my tomcat library and everything compiles great.
However, my webpage header does NOT reflect what I have enabled in my web.xml through the CORS filter.
My header looks like:
And my web.xml contains:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!-- Servlet 1: Expose the OData service endpoint -->
<servlet>
<servlet-name>OData</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<!-- all additional parameters will be passed to your factory create method -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.odata4j.jersey.producer.resources.ODataApplication</param-value>
</init-param>
<init-param>
<param-name>odata4j.producerfactory</param-name>
<param-value>org.odata4j.producer.jpa.JPAProducerFactory</param-value>
</init-param>
<init-param>
<param-name>odata4j.jpa.persistenceUnitName</param-name>
<param-value>Resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>OData</servlet-name>
<url-pattern>/example.svc/*</url-pattern>
</servlet-mapping>
<!-- Servlet 2: Enable crossdomain access for browser clients -->
<servlet>
<servlet-name>CrossDomain</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.odata4j.producer.resources.RootApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CrossDomain</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Use CORSFilter for CORS -->
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!-- Note: All parameters are options, if ommitted CORS Filter
will fall back to the respective default values.
-->
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, OPTIONS, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Content-Type, X-Requested-With, Accept, Authentication</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>X-Test-1, X-Test-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I fixed my headers to support CORS by implementing Padcom's CORS filter for Java application as described here.
I'm still not sure why the method I tried above didn't work...
But if you are stuck trying the method above, it is easy and work trying Padcom's method. :)

Form Based authentication in REST Web serivces

I have created the REST web services using dynamic web project in eclipse and running in tomcat 7.
I am able to do basic authentication for the web services. Now I am trying to implement form based authentication.Now, any web service call from the browser shows 404 error instead of showing the login form.
May be , I guess the issue is path of the LoginForm.html. I have created the LoginForm.html directly under webcontent.
My web.xml code is
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>CustomerConnect</display-name>
<security-role>
<role-name>manager</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>management pages</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/LoginForm.html</form-login-page>
<form-error-page>/LoginError.html</form-error-page>
</form-login-config>
</login-config>
<!-- <session-config> -->
<!-- <session-timeout> -->
<!-- 1 -->
<!-- </session-timeout> -->
<!-- </session-config> -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.feature.Redirect</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/views/</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(images|css|jsp)/.*</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.bvbi.customerconnect.middletier</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<description>Location to store uploaded file</description>
<param-name>file-upload</param-name>
<param-value>
/home/bvbi/Desktop/apache-tomcat-7.0.26/webapps/CredoImages/
</param-value>
</context-param>
</web-app>
Your path configuration is correct. Remove * from your <url-pattern> inside the <servlet-mapping>.
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Does it make any difference?