JSP & RESTful Web Services

By Nicolas Zozol, http://www.edupassion.com

Global Architecture

The Client sends a request to the JSP Container (here, Tomcat 6.0.x). The JSP Page will forward to a RessourceBean the Request URI, the Request parameters as well as the Request PostBody.

The JSP will lead the work done by the RessourceBean depending on the Http method used.

Note : a RessourceBean is a JavaBean that implements setURI( ) and setPostBody( ) functions.

 

 

Recovering request datas

Recovering parameters

It's the easy and classic part : let's have a request PUT /wsxseditor/service/document/document.jsp?dataBaseId=24&title=ChangeTheTitle

the JSP will contain :

<jsp:useBean id="bean" class="bean.DocumentBean" scope="request"/>
<jsp:setProperty name="bean" property="*"/>
 

The DocumentBean must of course have the setDataBaseId( ) and setTitle( ) function.

 

Recovering request URI

Each JSP can deal with the HttpServletRequest by using ${pageContext.request}. We'll have to add to the JSP :

<jsp:setProperty name="bean" property="URI" value="${pageContext.request.requestURI}"/>

DocumentBean must implement the interface RessourceBean, or at least a setURI ( ) function.

 

Recovering request postBody

This is a little more tricky because we must deal with Streams :

<%
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(request.getInputStream()));

String line,result="";
while ((line = br.readLine()) != null) {
    result+=line;
}
br.close();
bean.setPostBody(result);
%>

DocumentBean must implement the interface RessourceBean, or at least a setPostBody ( ) function.

Dealing with different Http methods

We can do it with the HttpServletRequest


<c:if test="${pageContext.request.method = = 'POST' }">
... some xml ...
</c:if>

<c:if test="${ pageContext.request.method = = 'PUT' }">
... some xml ...
</c:if>

 

Analyzing URIs

Objectives

We have started the article with this request : PUT /wsxseditor/service/document/document.jsp?dataBaseId=24&title=ChangeTheTitle

We would like to have a more sexy URI like : PUT/wsxseditor/document/24?title=ChangeTheTitle

 

Servlet-Mapping

It's vey easy using Netbeans to forward URIs to the good JSP. Just double-click on the web.xml file and fill the form.

The xml will give something like :

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
<servlet>
    <servlet-name>UriAdaptor</servlet-name>
    <jsp-file>/service/document/document.jsp</jsp-file>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>UriAdaptor</servlet-name>
    <url-pattern>/document/*</url-pattern>
</servlet-mapping>
</web-app>

 

Analyzing

The ResourceBean implements the setURI ( ) function. When the URI is forwarded to the bean :

public void setUri(String uri) throws NotFoundException {
   this.uri = uri;
   robusta.rest.j2ee.UrlDecoder decoder=new robusta.rest.j2ee.UrlDecoder();
   this.userId=decoder.firstNumber(uri);
}

UrlDecoder.firstNumber( ) is a function from my Robusta framework that uses regular expressions to detect the first number in the URI.

More Elegance with JSP Tags

JSP scripts ( <% java code %> ) are not sexy and, what's worst, promote copy-paste of code. Using a simple, non-invasive, JSP tag resolves this problem.

robusta.tag, in the folder WebPages/WEB-INF/tags

<%@tag description="Conciliate RESTful Web Services and JSPs" pageEncoding="UTF-8"%>

<%@attribute name="method"%>
<%@attribute name="ressource" rtexprvalue="true" type="base.RessourceBean" required="true"%>
<%@attribute name="request" rtexprvalue="true" type="javax.servlet.http.HttpServletRequest" required="true"%>

<%
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(request.getInputStream()));

String line,result="";
while ((line = br.readLine()) != null) {
    result+=line;
}
br.close();

ressource.setPostRequest(result);
ressource.setURI(request.getRequestURI());
this.method=request.getMethod();
%>

And the JSP will finally look like :

<%@ taglib tagdir="/WEB-INF/tags/" prefix="ws" %>
<jsp:useBean id="bean" class="bean.uriBean" scope="request"/>
<jsp:setProperty name="bean" property="*"/>

<ws:robusta ressource="${bean}" request="${pageContext.request}"/>

<c:if test="${method = = 'POST' }">
... some xml ...
</c:if>

 

Advantages of JSPs versus Servlets and JSF

Concerning Servlets, it's easy : this method avoid theses awful out.println("\\sdqs\\") but deals with URI, postBody and Http methods like Servlets where used to do. JSP, associated with JSTL, is absolutely perfect to exchange XML with Ajax applications.

JSF is intended to be the graphical view but can do the same job. If your application is big enough, you can use a JSP web service for exchanging datas, and use another JSF based web-app for its nice graphical components. If you don't need these components, use only JSP : it's more fast, and more easy if you could work with somebody else later on the project.