JAX-RS or THE way to do REST in Domino Part 4

If you’ve ever created a REST service you know one of the first problems you’ll run into is that you can only call that service from the same domain that it lives on.  Because of Cross Origin Resource Sharing security issues, The browser will not allow it unless the service includes certain HTTP headers, namely headers that start “Access-Control-Allow” This information is explained in great detail on the Mozilla Developer Network site here.  In Domino adding these http headers to the response can be done differently based on what service you are using.  In XPages or in an NSF it can be done directly via a Phase Listener.  In DAS it can be sort of done by adding custom headers on the Domino Server Config.  It can also be done when writing a custom OSGI plugin.

In plugins you could write to the headers for each method that is specified in your resource, but most likely you want to write out the headers for everything that comes into your service.  The best way to handle it is with a Servlet Filter.  A Servlet Filter is some code that runs before the servlet that can manipulate the request/response and it runs on every request.

In our example we add this simple Servlet Filter


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CORSFilter implements Filter {

public CORSFilter() { }

public void init(FilterConfig fConfig) throws ServletException { }

public void destroy() { }

public void doFilter(
ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

((HttpServletResponse)response).addHeader("Access-Control-Allow-Origin", "*");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Credentials", "true");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Methods", "POST");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Headers", "Content-Type");
((HttpServletResponse)response).addHeader("Access-Control-Max-Age", "86400");

chain.doFilter(request, response);
}
}

It adds to the appropriate headers to every request that comes in and then delegates the request/response to the servlet.

The only other config change that needs to be made is to specify the filter in the web.xml


<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.tobysamples.demo.wink.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>

This puts a pattern on which urls will have the filter applied.  So as you can see this technique is simple and allows for complete flexibility as to what headers are sent down to the client.  So now you can build out your Domino Service and call it from other web apps.

Advertisements

2 thoughts on “JAX-RS or THE way to do REST in Domino Part 4

  1. Dan Soares says:

    Hey Toby, if one is using the extension libraries REST controls to build a custom REST service, how does one get around the CORS issue?

    I’m seeing posts that indicate that modifying those headers is not possible in that scenario.

    Thoughts and suggestions welcome 🙂

    Dan

  2. I’ve tried adding the filter to a REST plugin, but I get the rather unhelpful message “Error 500: javax.servlet.ServletException: Filter [CORSFilter]: com.paulwithers.demoServlet.CORSFilter was found, but is missing another required class.” Most of the references I’ve found to that on the web are to do with Websphere where the filter reference was uncommented and needed commenting out, so they don’t specify how to actually get it working. The logs don’t have any further detaiols of the class missing.

    Looking at your commit on GitHub for that, there’s nothing specifically added. Is there something I’m missing or some additional configuration on the server?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s