Jersey endpoints fail to load if index.html is provided - java

I have a Jetty Server which serves up an Angular page but also has several Jersey endpoints coded up. My Angular project is in a resources directory, and after building and running, the target looks like this:
WEB-INF
classes
index.html
com/
web.xml
My web.xml looks like this:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<display-name>Sandbox</display-name>
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Adds JSON processing to map java classes to JSON text in both directions -->
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<!-- Tell the Jersey framework where to search for services. Also, JAX-RS is needed
for the JSON serialization -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.hb.apps.server;org.codehaus.jackson.jaxrs</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>json</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
With this set up, hitting localhost:8080/Sandbox serves up the single page angular app, however hitting localhost:8080/Sandbox/rest/* tells me that my endpoint cannot be found. The Angular app was introduced after the Jersey app, and prior to the Angular app my Jersey endpoints were working fine with this configuration (minus the welcome-file-list). Why would having an Angular app obscure my Jersey endpoints?

The answer was unrelated to the web.xml. One of my colleagues had assisted me with setting up the project to work with Angular and had removed this block from my pom file:
<resource>
<directory>src/main/webapp</directory>
</resource>

Related

AppEngine React and Jersey - The scratchDir you specified is unusable

I have a Java-based REST API (via Jersey 1.18) that I've deployed in an AppEngine application alongside a React front end.
My web.xml declares two servlets:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
...
<servlet>
<servlet-name>react</servlet-name>
<jsp-file>/index.html</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>react</servlet-name>
<url-pattern>/login</url-pattern>
...
</servlet-mapping>
...
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>
<jsp-config>
<taglib>
<taglib-uri>http://www.myapp.com/customtags</taglib-uri>
<taglib-location>/WEB-INF/custom-tags/UserRefTag.tld</taglib-location>
</taglib>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
and, of course, the Jersey filter:
<filter>
<filter-name>jersey</filter-name>
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.myapp.servlets;com.myapp.tasks;com.wordnik.swagger.jersey.listing
</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.provider.packages</param-name>
<param-value>com.myapp.audit;com.myapp.filters</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
<param-value>/WEB-INF/jsp</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
<param-value>/(js|css|(WEB-INF/jsp)|_ah|ipn|woff|woff2|ui|json|html)/.*</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.myapp.audit.AuditLogInterceptor</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.myapp.filters.CorsFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jersey</filter-name>
<url-pattern>/tasks/*</url-pattern>
...
</filter-mapping>
I've specified, in appengine-web.xml the relevant static resources:
<static-files>
<include path="/static/**" expiration="10s"/>
<!-- react ui resources (eg: manifest.json etc) -->
<include path="*.html" expiration="10s"/>
<include path="*.json" expiration="10s"/>
<include path="*.js" expiration="10s"/>
</static-files>
So, ideally, when a user hits an endpoint like /login then it should translate to the react servlet, and be directed to index.html, which is the react app. ReactRouter should then kick in and render the login page. All static, until it checks for a session or something.
This all works wonderfully well in the devserver. When I load /login, it renders my react app. When the react app calls the backend REST endpoints, they all work.
Then, I put it on appengine (standard environment), and it's a different story. The REST endpoints all respond, but the react app doesn't fire. All I get is: Error /login or similar.
When I look in the appengine logs, I see this:
:WARN:oaj.EmbeddedServletOptions:RequestDA26342E: The scratchDir you specified: [/base/data/home/apps/g~myapp-alpha/alpha2.419176782209598562/jsp] is unusable
Googling around, this error appears to be related to directory permissions in the WebContainer, but that's all obfuscated from me, because this is appengine.
What does this error really mean?
What is the problem?
How can I resolve it?
It turns out, after much hacking, that specifying an HTML file in the element was what was causing problems.
Whatever webcontainer appengine uses was trying to compile it, but appengine is supposed to pre-compile all JSPs on upload so it doesn't have to do this. Their setup obviously can't cope with that.
The fix was to move and rename /index.html into /WEB-INF/jsp/index.jsp
It was all perfectly happy then.

Web.xml for jersey2 not allowing rest calls from other applications

I recently upgraded my jersey jars from version 1 to 2 . With jersey-1 my web.xml mappings were as follows
<servlet>
<servlet-name>Restful App</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Restful App</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I have other applications talking to this application through rest calls. After upgrading to jersey 2 I have changed web.xml as follows
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Normal REST calls within the application seems to work fine, but rest calls made by other applications are not hitting my application now. No error logs also.
PS: Also I am having elasticsearch configured to talk to this application, even that gives me this error elasticsearch error

Jersey JAX-RS: Specifying /* as base URL pattern

I have a Dynamic Web application, and because of the requirements, I am specifying two types of servlet mappings in the web.xml file; Faces Servlet & Jersey(JAX-RS implementation).
My problem is, that if I try to use '/' as the base url-pattern in the Jersey configuration, then the resources of Faces Servlets stop working, i.e., nothing happens if I make REST call to those resources, otherwise everything works fine if I place something like'/rest/' in the Jersey Configuration. My web.xml file looks like this:
<!-- Jersey -->
<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.saf.web.v2.beans</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>
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
Is there a way to specify the Jersey mapping so there is nothing in the url-pattern but '/*' and Faces Servlet resources also work fine at the same time.
Thanks!
If you define that Jersey should serve all requests (this is what /* means) the Faces Servlet doesn't have a chance any more. So in general: There is no such way.
Maybe you could work around this be mapping Jersey to /rest and writing an own Servlet mapped to /* which dispatches to one of the other servlets. I would not recommend that.
I had the same problem but I fixed it by using
/rest/*
for jersey's servlet
and other part of application can have any other url-pattern, as in your case it is *.xhtml for JSF's servlet.

Configuring Restlet with App engine

I am using google app engine to develop my software's backend using java along with Restlet framework. I have index.jsp under my war directory which I want to treat as default page when somebody goes to my website(e.g. example.com). So I have mentioned it under welcome-file-list section in web.xml.
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Also, I have my Restlet servlet mapped to "/*" in web.xml.
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
But the problem occurs here, because even the call to default page i.e. example.com, also goes to the restlet which obviously doesn't find the mapping in its router. So I decided to instead map restlet servlet to "/restlet/*".
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/restlet/*</url-pattern>
</servlet-mapping>
But with this I get the HTTP 404 error because somehow even though web.xml successfully routes the call to restlet, but restlet doesn't find the mapping in this case in its router object. I have obviously changed the mapping in the restlet router to match the new pattern "restlet/*".
router.attach("/restlet/doSomething",DoSomething.class);
It would be really great if someone can help me with this. Following is my complete web.xml:
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.application</param-name>
<param-value>com.mWallet.loyaltyCardCase.LoyaltyCardCaseWebService
</param-value>
</init-param>
</servlet>
<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/restlet/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Thanks!
Manas
You don't need to change the mapping in the restlet router to match the new pattern "restlet/*" because the restlet router will now be considering "example.com/restlet/" as the base url.
So, if you change the router to match "/restlet/doSomething", your actual url will be "example.com/restlet/restlet/doSomething", which obviously will not work.
So, change your restlet routing to:
router.attach("/doSomething",DoSomething.class);
I did it in my project and its working.
i think you forgot to write below code in web.xml
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.application</param-name>
<param-value>com.wa.gwtamazon.server.RestApi</param-value>
</init-param>
<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
and i already answer in this link Restlet API example may will help you.

How to serve static resources from a Vaadin/Spring application?

I have Vaadin web application with spring security integration for authentication. The configuration of the Vaadin servlet is pretty simple:
<servlet>
<servlet-name>Vaadin Application Servlet</servlet-name>
<servlet-class>com.example.SpringApplicationServlet</servlet-class>
<init-param>
<param-name>applicationBean</param-name>
<param-value>mainApplication</param-value>
</init-param>
<init-param>
<param-name>widgetset</param-name>
<param-value>com.example.widgetset.CustomWidgetSet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
The servlet initializes the Spring Context and returns the Vaadin application. I have also configured the security for that and have a custom login form configured like this:
<servlet>
<servlet-name>login</servlet-name>
<jsp-file>/jsp/login.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>login_error</servlet-name>
<jsp-file>/jsp/loginError.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>login_error</servlet-name>
<url-pattern>/login_error</url-pattern>
</servlet-mapping>
The login form is styled with an external css and there are also some images. Basically the images are located in /jsp/img and the stylesheet in /jsp/login.css. So the WAR structure looks like:
/jsp
/META-INF
/VAADIN
/WEB-INF
Neither the images nor the css gets loaded, because obviously all those requests are mapped to the vaadin servlet. How can I define some static resources directory, which wouldn't be served by the Vaadin servlet? I have tried the spring mvc:resources but that didn't work. Thank you for your help.
Bye,
Filip
I have figured this out. Although it is rather a workaround. I have mapped the Vaadin Application Servlet to something like /app/* instead of to /* (Remember that in this case you also have to map the same servlet to /VAADIN/*). With this configuration I am able to access the jsp directory from my webapp and everything works fine. I have deleted the whole Spring Resources configuration, as this just didn't work.
So once more, I am still pretty not pretty comfortable with this solution and would rather have my RESOURCES dir configured other way, but the client is happy :). If anyone has got the right solution I would appreciate to read it.
Use a url rewrite filter to get more contro on url mapping.
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
then map Vaadin application to /vaadin for example and configure url maping in urlrewrite.xml
<rule>
<from>/styles/**</from>
<to last="true">/styles/$1</to>
</rule>
<rule>
<from>/images/**</from>
<to last="true">/images/$1</to>
</rule>
<rule>
<from>/**</from>
<to>/vaadin/$1</to>
</rule>
<outbound-rule>
<from>/vaadin/**</from>
<to>/$1</to>
</outbound-rule>
EDIT
Other option is put static files in /VAADIN/ directory.
I have figured this out. Although it is rather a workaround. I have mapped the Vaadin Application Servlet to something like /app/* instead of to /* (Remember that in this case you also have to map the same servlet to /VAADIN/*). With this configuration I am able to access the jsp directory from my webapp and everything works fine. I have deleted the whole Spring Resources configuration, as this just didn't work.
So once more, I am still pretty not pretty comfortable with this solution and would rather have my RESOURCES dir configured other way, but the c
Might be late but for who is still having problems with serving static content while using vaadin /* mapping, the solution I found was using apache's default servlet org.apache.catalina.servlets.DefaultServlet, so a web.xml will have something like:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
id="WebApp_ID" version="3.0" 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/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>com.ex.myprj.MyUI</param-value>
</init-param>
<!-- If not using the default widget set-->
<init-param>
<param-name>widgetset</param-name>
<param-value>com.ex.myprj.AppWidgetSet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Static content Servlet</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Static content Servlet</servlet-name>
<url-pattern>/customer/*</url-pattern>
</servlet-mapping>
</web-app>
So in the example above, despite having vaadin at /*, the /customer/* part will be served as static content by the DefaultServlet

Categories