Using Jsp in a Jersey JAX-RS RESTful application

Posted: décembre 29th, 2011 | Author: | Filed under: Dev, Glassfish, Java, Java EE, JAX-RS, Jersey, Tools, Tutorial | Tags: , , , , , , , , , , , | 30 Comments »

So, ok we could easily produce some RESTful applications with Jersey.
But sometimes, the output could be very big to put in a method and a template could be useful.

Jersey provides MVC support for JSP pages.
There is a JSP template processor that resolves absolute template references to processable template references that are JSP.


1 – Configure web.xml

<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.ezakus.web</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>/(resources|(WEB-INF/jsp))/.*</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>jersey</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

Instead of a servlet mapping you need to have a filter.

With the JSPTemplatesBasePath param, you choose your jsp folder

	<param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
	<param-value>/WEB-INF/jsp</param-value>

And with the WebPageContentRegex you are able to serve static resources.
In the previous example, static resources are on the /resources/ or /WEB-INF/jsp/ path but you can put what you want :

	<param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
	<param-value>/(resources|js|css|images)/.*</param-value>

2 – Return Viewable or Response

Now you can use the Viewable class with your jsp path

package com.ezakus.web;

import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import com.sun.jersey.api.view.Viewable;

@Stateless
@Path("/")
public class MyController {

    @GET
    @Produces("text/html")
    public Viewable index() {
    	return new Viewable("/index");
    }

}

Note : /index assume that you have a /WEB-INF/jsp/index.jsp on your path

You can also use the Response class

package com.ezakus.web;

import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

import com.sun.jersey.api.view.Viewable;

@Stateless
@Path("/")
public class MyController {

    @GET
    @Produces("text/html")
    public Response index() {
    	return Response.ok(new Viewable("/index")).build();
    }

}

3 – Using Viewable’s model

The Viewable object could be created with a model :

package com.ezakus.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

import com.sun.jersey.api.view.Viewable;

@Stateless
@Path("/")
public class MyController {

    @GET
    @Produces("text/html")
    public Response index() {
    	Map<String, Object> map = new HashMap<String, Object>();
        map.put("user", "usul");
        List<String> l = new ArrayList<String>();
        l.add("light saber");
        l.add("fremen clothes");
        map.put("items", l);
    	return Response.ok(new Viewable("/cart", map)).build();
    }

}

Note : Jersey will assign the model instance to the attribute « it » in the jsp. (Yes, life is hard)

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${it.user}!</h1>
  <p>
  	items in your cart :<br />
    <c:forEach var="item" items="${it.items}">
    	${item}<br />
    </c:forEach>
  </p>
</body>
</html>
 

  • http://Website gonzalad

    Interesting approach, but only usable for read-only data.

    I don’t know how you can handle POST with Jersey MVC support (validation, conversion, error message, etc…) ?

    Am I missing something ?

    • usul

      You can perform ajax request if you want and post data (even without ajax support).
      Why can’t you do some validation or return error messages ?

  • http://Website Paulo Henrique Trecenti

    In the topic 3 you have forgot to put the the model with the viewable, like this:

    return Response.ok(new Viewable("/cart",map)).build();

    • usul

      Fixed !
      Thx :)

  • RadioInstitute My

    can you display the scriptlet version of the results page jsp

  • Alice

    To the OP, how did you find out that Jersey inserts the model into the « it » variable of the JSP? I’ve looked through a lot of Jersey docs and can’t find anything relating to this. Just want to know if there are docs out there that are actually helpful.

    • fdussert

      Hi, I’ve found https://jersey.java.net/documentation/latest/user-guide.html#d0e13218

      Seems that with new versions you also have model

      • Alice

        thanks! Actually I just posted the comment when I read down to the bottom of that page and found it. Silly me!

      • Alice

        thanks! Actually I just posted the comment when I read down to the bottom of that page and found it. Silly me!

  • disqus_HKCu7HFCpB
    • fdussert

      Replied but it’s ok for me ;)

  • Shiv

    I tried this example and it is almost working for me. But i am not able to use the external css and js files. As shown above i am making the entry for them under of web.xml, but still it is not picking up the file. My folder structure is as follows:-

    WEB-INF/resources/css/styles.css
    WEB-INF/resources/images/image.png
    WEB-INF/resources/js/sample_js.js

    Please help me with this as i am trying to make a sample web application using this Jersey MVC template.

    Thanks.

    • fdussert

      Hi,

      if you want to make it working with

      com.sun.jersey.config.property.WebPageContentRegex
      /(resources|(WEB-INF/jsp))/.*

      You should put resources folder beside WEB-INF, not inside.

      • Shiv

        Now my folder structure is like :-

        WebContent/resources/css/styles.css
        WebContent/WEB-INF/jsp/index.jsp

        I changed the entry in web.xml like :-

        com.sun.jersey.config.property.WebPageContentRegex
        /((resources/css)|(WEB-INF/jsp))/.*

        In index.jsp, i am including the css as :-

        But still not working. Please suggest.

        • fdussert

          Just try to remove .. in your href :

          And be sure that in the war, you have the resources folder near WEB-INF

          • Shiv

            « .. » removed but still not working. When we create any Dynamic Web Project in Eclipse, the folder structure gets created. Under WebContent folder, META-INF and WEB-INF is automatically created. So there only i created my resources folder and the structure looks like:-

            WebContent/META-INF/MANIFEST.MF
            WebContent/resources/css/styles.css
            WebContent/WEB-INF/jsp/index.jsp

            Hope you understood the application structure.
            Please also note that i am using 1.0.2 version of jersey jars.

          • fdussert

            Hum, perhaps just remove the / too.

            Your URL should looks like this :
            http://server:port/contextRootOfYourApp/resources/css/styles.css

            You can test it directly in your browser without using the JSP.
            If you can display the css, check the correct href to put (with ./, without /, …)

          • Shiv

            I am including the css as:-

            Now i tried something different. I removed the filter mappings from web.xml to make the index.jsp invoke from . This time index.jsp picked the css file and displayed the page properly. This means that href= »resources/css/styles.css » is able to find the css file.

            But when i use the filter mappings to invoke my index.jsp as shown in your example above, the css file is not picked up by the jsp. I think the issue is with Jersey’s way of including static contents like css, images, etc. May be i am not able to map my css file correctly as per Jersey’s notation in web.xml.

            Please suggest something helpful in this regard.

          • fdussert

            If you look at the network tab of your browser devtools, what is the url for which its looking for your css ?

          • Shiv

            Are there some other Jersey JARs that are needed for

            com.sun.jersey.config.property.JSPTemplatesBasePath
            com.sun.jersey.config.property.WebPageContentRegex

            Please share the names of all the JARs that are needed here. If possible please provide the path to download them too.

          • fdussert

            Here are my maven deps :

            1.17

            com.sun.jersey
            jersey-server
            ${jersey-version}
            provided

            com.sun.jersey
            jersey-json
            ${jersey-version}
            provided

            javax.servlet
            javax.servlet-api
            3.0.1
            provided

            org.glassfish
            javax.ejb
            3.0
            provided

            org.jboss.weld
            weld-osgi-bundle
            1.0.1-Final
            provided

            You just need jersey server I guess

    • Shrimant Chakrabarti

      HI Shiv! :)

      How did you solve this problem? I am encountering with the same issue! :( Please help! :)

  • Nishanth

    Hello, I executed the example, but model is not getting mapped to the jsp page and im getting the following result.

    Welcome ${it.user}!

    items in your cart :
    ${item}
    ${item}

    Can someone please help me out with this problem.

  • Shrimant Chakrabarti

    Hi! Thanks for this wonderful post. I could navigate from one jsp to another using this method. However, I am facing the same issue as Shiv, i.e., I am not able to put external css, images and js to my jsp.

    As per the discussions between Shiv and fdussert, I changed my WebContent from:

    WEBContent/WEB-INF/jsp
    WEBContent/WEB-INF/assets/css
    WEBContent/WEB-INF/assets/js/
    WEBContent/WEB-INF/assets/fonts
    WEBContent/WEB-INF/assets/images

    TO

    WEBContent/WEB-INF/jsp
    WEBContent/WEB-INF/css
    WEBContent/WEB-INF/js/
    WEBContent/WEB-INF/fonts
    WEBContent/WEB-INF/images

    but even that didn’t help. I have also included the following:

    com.sun.jersey.config.property.JSPTemplatesBasePath
    /WEB-INF/

    com.sun.jersey.config.property.WebPageContentRegex
    /(css|fonts|images|js|vendor)/.*

    But even that didn’t help! :( Please guide me through this issue! :)
    Thanks in advance! :)

    • fdussert

      Hi,
      are your JSP displayed ?
      And what do you put in to link your css file ?

      • Shrimant Chakrabarti

        Hi!
        Thanks for responding. :) Btws, the links I am using for my javascripts and css are like:

        • fdussert

          Have you tried with /css… ?

          • Shrimant Chakrabarti

            Yes, it’s still not working. Btws, FYI, when I am checking « inspect element » from my Chrome browser, it gives the error:

            « Failed to load resource: the server http://localhost/images/abc.png responded with a status of 404 (Not Found).

            Same goes for http://localhost/css/main.css

            UPDATE: Right now, I tried to give the url as:

            <img src = "//images/abc.png »>

            So, now the url : http://localhost//images/abc.png is accessible….

            My web.xml is NOT the same (using ‘filter’ instead of ‘servlet’). The URL I had been giving is wrong. I’ll try the same for css and js. Should work! :)

            UPDATE 2:

            YES!! IT WORKS!!! :) :)

            So, here is the structure of my Web-app:

            Project1:
            -> WebContent(contains the following folders: js,css,fonts,images, WEB-INF)
            – js
            – css
            – fonts
            – images
            – WEB-INF (contains all the JSP pages)

            Web.xml:

            Project1

            Jersey REST Service
            com.sun.jersey.spi.container.servlet.ServletContainer

            com.sun.jersey.config.property.packages
            com.hp.LRScheduleIWF.RESTServices

            com.sun.jersey.config.property.JSPTemplatesBasePath
            /WEB-INF/

            com.sun.jersey.config.property.WebPageContentRegex
            /(js|css|images/fonts)/.*

            Jersey REST Service
            /*

            the URL links have to be given like this:

            Eg:
            Similarly,

            Now, if you check in the « inspect element » from your browser (I use Chrome), the URL will be:
            http://localhost/Project1/images/abc.png

            Thanks for your time and efforts, fdussert! :)

  • thili

    where is source code?

  • thili

    why can’t work for me?