users@jersey.java.net

RE: [Jersey] Integrating Jersey and Spring

From: Florian Hehlen <Florian.Hehlen_at_imc.nl>
Date: Thu, 21 Jan 2010 15:00:12 +0100

Ronak,

Can you provide more details on how you have things configured. I have just tried it myself and the spring application does not get loaded.

I load my spring app using the com.sun.jersey.spi.spring.container.servlet.SpringServlet provided by Jersey. Is that how you do it?

Cheers,
Florian

From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: 21 January, 2010 12:37
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Integrating Jersey and Spring


On Jan 20, 2010, at 5:31 PM, Fernando Soares wrote:


I'am using jersey-spring 1.1.4.1 with springsource-3.0.0-RELEASE without any problem so far.

Wow! thanks for sharing. I was expecting some backwards compatibility issues given it is a major release.

Paul.



On 01/20/2010 12:51 AM, Ronak Patel wrote:
Hi,

On a similar note,

I was wondering if JAX-RS Jersey is updated to use Spring Framework 3.0 now. If not, any clue as to when that support will be available?

Thanks!

Ronak Patel

________________________________
From: Brad Lee <s.brad.lee_at_gmail.com><mailto:s.brad.lee_at_gmail.com>
To: users_at_jersey.dev.java.net<mailto:users_at_jersey.dev.java.net>
Sent: Tue, January 19, 2010 12:28:20 PM
Subject: Re: [Jersey] Integrating Jersey and Spring

Hi Mahesh. Sorry I am late to reply here, this email never responded directly to me. Anyway, on this email you will find the JerseySpringController that very simply forwards Spring requests to Jersey.

I don't have any examples of interceptors extending ContainerFilters and Jersey Resource filters, but I don't honestly think that it would be that hard to implement. If I ever have a need for one, then I will post back when I write it.

Right now, I'm not bothering with annotations, although I would imagine you could configure it using annotations. The properties file above is what I use to inject the Properties instance variable on the JerseController class.

Also, since Struts2 is YASF(yet another servlet framework), I would think it very easy to forward requests it receives into Jersey.

package org.springframework.web.servlet.jersey<http://web.servlet.jersey>;

import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;

import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.ServletContextAware<http://web.context.ServletContextAware>;
import org.springframework.web.servlet.ModelAndView<http://web.servlet.ModelAndView>;
import org.springframework.web.servlet.mvc.Controller<http://web.servlet.mvc.Controller>;

import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.sun.jersey.spi.container.servlet.WebConfig;
import com.sun.jersey.spi.spring.container.SpringComponentProviderFactory;

public class JerseyController
extends ServletContainer
implements Controller, ServletContextAware, InitializingBean, ApplicationContextAware {
    //==========================================================================
    // Private Static Variables
    //==========================================================================
    private static final Logger logger =
        LoggerFactory.getLogger(JerseyController.class);
    //==========================================================================
    // SpringServlet methods are private instead of protected,
    // so I have to redo their servlet extension of ServletContainer...
    //==========================================================================
    @Override
    protected void initiate(ResourceConfig rc, WebApplication wa) {
        try {
            wa.initiate(rc, new SpringComponentProviderFactory(rc, getContext()));
        } catch (RuntimeException e) {
            logger.error("Exception occurred during initializing "+SpringComponentProviderFactory.class.getName()+"!", e);
            throw e;
        }
    }
    protected ConfigurableApplicationContext getContext() {
        final ConfigurableApplicationContext springContext =
                (ConfigurableApplicationContext) this.getApplicationContext();
        return springContext;
    }

    //==========================================================================
    // Instance Variables
    //==========================================================================
    private ServletContext springServletContext;
    private Properties jerseyConfiguration;
    private ApplicationContext applicationContext;
    //==========================================================================
    // Getters
    //==========================================================================
    @Override
    public void setServletContext(ServletContext servletContext) {
        springServletContext = servletContext;
    }
    public Properties getJerseyConfiguration() {
        return jerseyConfiguration;
    }
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    //==========================================================================
    // Setters
    //==========================================================================
    public ServletContext getSpringServletContext(){
        return springServletContext;
    }
    @Override
    public ServletContext getServletContext(){
        return this.getSpringServletContext();
    }
    public void setJerseyConfiguration(Properties jerseyConfiguration) {
        if( logger.isDebugEnabled() ){
            StringBuffer buffer = new StringBuffer();
            buffer.append("Setting jersey configuration:\n");
            for( Object key : jerseyConfiguration.keySet() ){
                buffer.append("\t").append(key).append("=").append(jerseyConfiguration.get(key)).append("\n");
            }
            logger.debug(buffer.toString());
        }
        this.jerseyConfiguration = jerseyConfiguration;
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    //==========================================================================
    // Interfaces
    //==========================================================================
    @Override
    public ModelAndView handleRequest(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        String uri = request.getRequestURI().substring(
                request.getContextPath().length(), request.getRequestURI().length());
        logger.info<http://logger.info>("Handling request {}, by passing it to parent jersey servlet...", uri);
        try{
            super.service(request, response);
        }catch(Throwable t){
            logger.error("An error occurred processing request: "+uri, t);
            throw new ServletException("The REST web service had an error. Please report this problem.", t);
        }
        logger.info<http://logger.info>("For path {}, returning DoNothingView...", uri);
        return new ModelAndView("DoNothingView");
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        final String fName = getClass().getName();
        final Properties fJerseyConfig = this.getJerseyConfiguration();
        logger.info<http://logger.info>("Initializing Bean {}...", fName);
        FilterConfig config = new FilterConfig() {
            @Override
            public ServletContext getServletContext() {
                return getSpringServletContext();
            }
            @Override
            public String getFilterName() {
                return fName;
            }
            @Override
            public Enumeration getInitParameterNames() {
                return fJerseyConfig.keys();
            }
            @Override
            public String getInitParameter(String paramName) {
                return fJerseyConfig.getProperty(paramName);
            }
        };

        logger.debug("Initializing Jersey through super.init(FilterConfig)...");
        super.init(config);
    }//end afterPropertiesSet()

}/* end JerseyIntegrationFilter */


Where the injected properties file looks like this:
# If true the request URI will be normalized as specified by
# {@link java.net<http://java.net>.URI#normalize}. If not true the request URI is not
# modified.
# The default value is false.

com.sun.jersey.config.feature.NormalizeURI=true


# If true the request URI path component will be canonicalized by removing
# contiguous slashes (i.e. all /+ will be replaced by /). If not true the
# request URI path component is mot modified.
# The default value is false.

com.sun.jersey.config.feature.CanonicalizeURIPath=true


# If true, and either NORMALIZE_URI or CANONICALIZE_URI_PATH is true,
# and the normalization and/or path canonicalization operations on the
# request URI result in a new URI that is not equal to the request URI,
# then the client is (temporarily) redirected to the new URI. Otherwise
# the request URI is set to be the new URI.
# <p>
# If true, and the path value of a {@link javax.ws<http://javax.ws.rs.Pa>.rs.Path} annotation ends
# in a slash, the request URI path does not end in a '/' and would otherwise
# match the path value if it did, then the client is (temporarily)
# redirected to a new URI that is the request URI with a '/' appended to the
# the end of the path.
# <p>
# The default value is false.

com.sun.jersey.config.feature.Redirect=true


# If true matrix parameters (if present) in the request URI path component
# will be ignored when matching the path to URI templates declared by
# resource classes.
# <p>
# The default value is false.

#com.sun.jersey.config.feature.IgnoreMatrixParams=true


# If true then the matching algorithm will attempt to match and accept
# any static content or templates associated with a resource that were
# not explicitly decared by that resource.
# <p>
# If a template is matched then the model for the viewable will be the
# resource instance associated with the template.
# <p>
# The default value is false.

com.sun.jersey.config.feature.ImplicitViewables=true


# If true then disable WADL generation.
# <p>
# By default WADL generation is automatically enabled, if JAXB is
# present in the classpath.
# <p>
# The default value is false.

#com.sun.jersey.config.feature.DisableWADL=true


On Wed, Jan 13, 2010 at 4:02 PM, Mahesh Venkat <mhvenkat_at_gmail.com<mailto:mhvenkat_at_gmail.com>> wrote:
Hi Brad,

Is it possible to share this working code?
Also if you have an example of adding Spring interceptors that extend the Jersey ContainerFilters and Jersey ResourceFilters it will be great!

In fact, in Spring 3.0 they are attempting do to take a similar approach to integrate with Jersey.

We also have to some thing similar for Struts2 too. The Apache community is attempting to define yet another REST mechanism rather than integrating Jersey with Struts2.






--

Fernando Soares

Director Técnico

Media Capital Multimédia, S. A.



T.: +351 21 434 63 99

M.: +351 91 758 56 70

F.: +351 21 434 76 53

Rua Mário Castelhano, 40

Queluz de Baixo

2734-502 Barcarena



www.iol.pt<http://www.iol.pt> ▪ www.mediacapital.pt<http://www.mediacapital.pt>





  ________________________________

Esta mensagem e quaisquer ficheiros anexos podem conter informação confidencial ou de uso restrito. Se não for o destinatário da mesma por favor notifique imediatamente o seu remetente e proceda à sua destruição. Não poderá revelar, copiar, distribuir ou de alguma forma usar o seu conteúdo. O Grupo Media Capital e suas associadas utilizam software de anti-virus. No entanto, não obstante terem sido tomadas todas as precauções, não é garantido que a mensagem ou os seus anexos não contenham vírus.



This message, including any attachments, may contain confidential information or privileged material. If you are not the intended recipient please notify the sender immediately by e-mail and delete it from your system. You should not disseminate, distribute or copy this e-mail or disclose its content. We believe, but do not warrant, that this e-mail, including any attachments, is virus free.


________________________________
The information in this e-mail is intended only for the person or entity to which it is addressed.

It may contain confidential and /or privileged material. If someone other than the intended recipient should receive this e-mail, he / she shall not be entitled to read, disseminate, disclose or duplicate it.

If you receive this e-mail unintentionally, please inform us immediately by "reply" and then delete it from your system. Although this information has been compiled with great care, neither IMC Financial Markets & Asset Management nor any of its related entities shall accept any responsibility for any errors, omissions or other inaccuracies in this information or for the consequences thereof, nor shall it be bound in any way by the contents of this e-mail or its attachments. In the event of incomplete or incorrect transmission, please return the e-mail to the sender and permanently delete this message and any attachments.

Messages and attachments are scanned for all known viruses. Always scan attachments before opening them.