Jersey /* Servlet Mapping Causes 404 Error for Static Resources

Jersey Viewable resulting in 404

For anyone experiencing this issue, here's the solution, courtesy of the link provided by peeskillet here. My issue was that I was missing the following dependency, though mine was a different version:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.0-m07-1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

After adding that dependency to my pom everything worked.

Server always returns 404 Error with Jersey 2 + Tomcat 6

<param-value>com.tutorial.example</param-value>

Your class is not in the com.tutorial.example package. It's in the com.tutorial package. Jersey scans the package you put there for classes, and registers them. In your case, do classes get picked up. Make the change accordingly.

Note that the package you put, will be scanned recursively. Also you can put multiple packages separated by a comma.

Serving static files with Jersey 2

I was pointed to this question and got my answer. Basically I just need to change the Jersey servlet to a filter and supply a static content regex as an init param. Now I have my servlet mounted at the root and my static files are getting served up just like I wanted.

Spring-Jersey : How to return static content?

"How do I expose my css/, images/, js/ and other static files?"

The jersey.config.servlet.filter.staticContentRegex property should work, but you need to specify all the possible patterns for all the types of files you want to serve. The easier way is to just use the property jersey.config.servlet.filter.forwardOn404, as pointed out in this answer. And yes with both choices, you need configure Jersey as a filter, rather than a servlet. So your web.xml might look like

<filter>
<filter-name>Jersey</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.component.ResourceRegister</param-value>
</init-param>
<!-- pass to next filter if Jersey/App returns 404 -->
<init-param>
<param-name>jersey.config.servlet.filter.forwardOn404</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<url-pattern>/*</url-pattern>
<filter-name>Jersey</filter-name>
</filter-mapping>

"How do I return a JSP page in my controller (not a String method) for my index view?"

First thing you need is the jsp mvc dependency

<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc-jsp</artifactId>
<version>2.25</version>
</dependency>

Then you need to register the feature

public ResourceRegister () {
...
register(JspMvcFeature.class);
}

Then you need to specify the template base path for all your jsp pages. For example I used /WEB-INF/jsp

public ResourceRegister () {
...
property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/jsp");
}

So for this case, all the jsp files should be located in /WEB-INF/jsp directory.

Example jsp and controller

index.jsp

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>JSP Page</title>
<link href="css/styles.css" rel="stylesheet">
</head>
<body>
<h1>${it.hello} ${it.world}</h1>
</body>
</html>

Controller

@Path("/")
public class HomeController {

@GET
@Produces(MediaType.TEXT_HTML)
public Viewable index() {
Map<String, String> model = new HashMap<>();
model.put("hello", "Hello");
model.put("world", "World");
return new Viewable("/index", model);
}
}

public ResourceRegister () {
...
register(HomeController.class);
}

Here the /index in the Viewable points the index.jsp (we don't need the .jsp extension). Jersey knows how to find the file from the property we set above.

See Also:

  • Complete example from Jersey project
  • MVC Templates documentation

Spring-Boot Jersey: allow Jersey to serve static content

Let me just first state, that the reason the static content won't be served is because of the default servlet mapping of the Jersey servlet, which is /*, and hogs up all the requests. So the default servlet that serves the static content can't be reached. Beside the below solution, the other solution is to simply change the servlet mapping. You can do that by either annotating your ResourceConfig subclass with @ApplicationPath("/another-mapping") or set the application.properties property spring.jersey.applicationPath.


In regards to your first approach, take a look at the Jersey ServletProperties. The property you are trying to configure is FILTER_STATIC_CONTENT_REGEX. It states:

The property is only applicable when Jersey servlet container is configured to run as a Filter, otherwise this property will be ignored

Spring Boot by default configures the Jersey servlet container as a Servlet (as mentioned here):

By default Jersey will be set up as a Servlet in a @Bean of type ServletRegistrationBean named jerseyServletRegistration. You can disable or override that bean by creating one of your own with the same name. You can also use a Filter instead of a Servlet by setting spring.jersey.type=filter (in which case the @Bean to replace or override is jerseyFilterRegistration).

So just set the property spring.jersey.type=filter in your application.properties, and it should work. I've tested this.

And FYI, whether configured as Servlet Filter or a Servlet, as far as Jersey is concerned, the functionality is the same.

As an aside, rather then using the FILTER_STATIC_CONTENT_REGEX, where you need to set up some complex regex to handle all static files, you can use the FILTER_FORWARD_ON_404. This is actually what I used to test. I just set it up in my ResourceConfig

@Component
public class JerseyConfig extends ResourceConfig {

public JerseyConfig() {
packages("...");
property(ServletProperties.FILTER_FORWARD_ON_404, true);
}
}

Why do I get static text/html when returning a 404 Response with Java / Jersey?

Can you try again with the following configuration:

<servlet>
<servlet-name>API</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
...
<init-param>
<param-name>jersey.config.server.response.setStatusOverSendError</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

This flag defines if Jersey - when sending a 4xx or 5xx response status - uses ServletResponse.sendError(flag is false) or ServletResponse.setStatus (flag is true).

Calling ServletResponse.sendError usually resets the response entity and headers and returns a (text/html) error page for the status code.

Since you want to return an own custom error entity, you need to set this flag to true.



Related Topics



Leave a reply



Submit