users@jersey.java.net

Re: [Jersey] SOLVED: Jersey-Spring, _at_Context and InitializingBean

From: Tom Schindl <tom.schindl_at_bestsolution.at>
Date: Fri, 12 Feb 2010 12:13:39 +0100

Could you please turn the read request stuff when sending mails to this
group?

Tom

Am 12.02.10 11:31, schrieb Patrick Dreyer:
> Paul, thank you not only for the most welcome alternative and more
> elegant solution but also for the fast and very comprehensive answer.
> As you asked, the issue is logged
> (https://jersey.dev.java.net/issues/show_bug.cgi?id=469).
>
> For the archive, I decided to go with the setter method. Below how the
> Bean and Jersey resource do look like now.
>
> Regards, Patrick
>
> Bean
> ====
>
> @Component @Scope("prototype")
> public final class TaskDO implements InitializingBean
> {
> private static Logger logger = Logger.getLogger(TaskDO.class.getName());
>
> private ResourceContext resourceContext;
> @FormParam("xml") private String xml;
>
> private TaskState state;
>
> @Context public void setResourceContext(final ResourceContext value) throws Exception {
> resourceContext = value;
> state = resourceContext.getResource(...);
> }
> }
>
> Jersey resource
> ===========
>
> @Path("/tasks")
> @Component @Scope("request")
> public class TasksResource
> {
> @POST
> @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
> @Produces(MediaType.APPLICATION_XHTML_XML)
> public Response createTaskXHtml(@Inject final TaskDO taskDO) {
> ...
> return ...
> }
> }
>
> Paul Sandoz schrieb:
>> Hi Patrick,
>>
>> This is an issue with the Jersey/Spring integration.
>>
>> Jersey gets a reference to the Spring bean and then performs its own
>> injection. It currently does not register a bean post process listener
>> or something like that (i cannot remember the exact name) to perform
>> injection at the appropriate stage in the spring bean construction
>> process.
>>
>> Jersey does have framework support to integrate in such a manner as it
>> uses that for integration with CDI and EJBs so i think it should be
>> possible to support this properly with Spring. Gonna require a little
>> experimentation as my Spring knowledge is rusty. Could you log an issue?
>>
>>
>> A alternative work around may be to use setter methods:
>>
>> @Component @Scope("prototype")
>> public final class TaskDO implements InitializingBean
>> {
>> private static Logger logger =
>> Logger.getLogger(TaskDO.class.getName());
>>
>> @FormParam("xml") private String xml;
>>
>> private TaskState state;
>>
>> @Context
>> public void setTask(ResourceContext resourceContext) {
>> state = resourceContext.getResource(...);
>> }
>> }
>>
>> JAX-RS setter methods are called after injection onto fields is
>> performed.
>>
>>
>> If TasksResource, TaskDO and TaskState are spring-managed beans you
>> may be able to use spring auto-wiring rather than use ResourceContext.
>>
>> If you need the TaskDO instance to be created only for the resource
>> method "createTaskXHtml" rather than being created at class
>> construction you can do:
>>
>> public Response createTaskXHtml(@com.sun.jersey.spi.inject.Inject
>> TaskDO t) {
>> ...
>> }
>>
>>
>> The @Inject essentially does the same thing as one can do
>> programatically using ResourceContext. Also if using Jersey >= 1.1.4.1
>> you can do:
>>
>> @Inject Injectable<TaskDO> it;
>>
>> public Response createTaskXHtml() {
>> TaskDO t = it.get();
>> }
>>
>> which also allows you to inject per-request or prototype scoped
>> references onto singletons.
>>
>> Hth,
>> Paul.
>>
>> On Feb 12, 2010, at 9:47 AM, Patrick Dreyer wrote:
>>
>>
>>> Hi Jersey cracks
>>>
>>> Unfortunately, Spring is calling
>>> InitializingBean.afterPropertiesSet() BEFORE Jersey had it's chance
>>> to inject @Context fields, like "@Context private ResourceContext
>>> resourceContext".
>>> Thus, being in afterPropertiesSet(), the resourceContext field is
>>> not set yet. As you'll see, as temporary workaround I'm currently
>>> calling TaskDO.init() after creation through ResourceContext.
>>> Is this behaviour by design or, what I hope, can you spot a
>>> misunderstanding/misconfiguration on my side?
>>> Below you'll find my Environment, Bean, Jersey Resource, web.xml and
>>> applicationContext.xml
>>>
>>> Environment:
>>> =========
>>> * JRE 1.6.0_18-b07
>>> * JDK 1.6.0_17
>>> * Apache Tomcat/6.0.20
>>> * Jersey 1.1.5
>>> * Spring 3.0.0-RELEASE
>>> * Jersey-Spring 1.1.5
>>>
>>> Bean implementing InitializingBean:
>>> =======================
>>> @Component @Scope("prototype")
>>> public final class TaskDO implements InitializingBean
>>> {
>>> private static Logger logger =
>>> Logger.getLogger(TaskDO.class.getName());
>>>
>>> @Context private ResourceContext resourceContext;
>>> @FormParam("xml") private String xml;
>>> private TaskState state;
>>>
>>> @Override public void afterPropertiesSet() {
>>> int i = 0; // <-- ISSUE: resourceContext is not set yet; same
>>> goes for xml
>>> }
>>>
>>> public TaskDO init() throws Exception {
>>> state = resourceContext.getResource(...); // <-- obviously
>>> resourceContext is set now, same applies to xml
>>> return this;
>>> }
>>> }
>>>
>>> Jersey resource instantiating the Bean:
>>> =========================
>>> @Path("/tasks")
>>> @Component @Scope("request")
>>> public class TasksResource
>>> {
>>> @Context private ResourceContext resourceContext;
>>>
>>> @POST
>>> @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
>>> @Produces(MediaType.APPLICATION_XHTML_XML)
>>> public Response createTaskXHtml() throws Exception {
>>> TaskDO task = resourceContext.getResource(TaskDO.class).init());
>>> ...
>>> return ...
>>> }
>>> }
>>>
>>> web.xml
>>> ======
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <web-app
>>> id="WebApp_ID"
>>> version="2.5"
>>> xmlns="http://java.sun.com/xml/ns/javaee"
>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>> xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>>> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
>>> ">
>>> <display-name>...</display-name>
>>>
>>> <context-param>
>>> <param-name>contextConfigLocation</param-name>
>>> <param-value>classpath:applicationContext.xml</param-value>
>>> </context-param>
>>>
>>> <context-param>
>>> <param-name>log4jConfigLocation</param-name>
>>> <param-value>classpath:log4j.properties</param-value>
>>> </context-param>
>>>
>>> <listener>
>>> <listener-
>>> class>org.springframework.web.util.Log4jConfigListener</listener-
>>> class>
>>> </listener>
>>> <listener>
>>> <listener-class>org.springframework.web.context.ContextLoaderListener
>>> </listener-class>
>>> </listener>
>>> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener
>>> </listener-class>
>>> </listener>
>>> <welcome-file-list>
>>> <welcome-file>index.jsp</welcome-file>
>>> <welcome-file>index.html</welcome-file>
>>> </welcome-file-list>
>>>
>>> <servlet>
>>> <servlet-name>jersey</servlet-name>
>>> <servlet-
>>> class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</
>>> servlet-class>
>>> <init-param>
>>> <param-
>>> name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
>>> <param-value>/WEB-INF</param-value>
>>> </init-param>
>>> <load-on-startup>1</load-on-startup>
>>> </servlet>
>>>
>>> <servlet-mapping>
>>> <servlet-name>jersey</servlet-name>
>>> <url-pattern>/ws/*</url-pattern>
>>> </servlet-mapping>
>>> </web-app>
>>>
>>> applicationContext.xml
>>> ================
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <beans
>>> xmlns="http://www.springframework.org/schema/beans"
>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>> xmlns:context="http://www.springframework.org/schema/context"
>>> xsi:schemaLocation="
>>> http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
>>> http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
>>> ">
>>> <context:component-scan base-package="..."/>
>>> </beans>
>>>
>>>
>>> Regards
>>> ---
>>> Patrick Dreyer
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>


-- 
B e s t S o l u t i o n . a t                        EDV Systemhaus GmbH
------------------------------------------------------------------------
tom schindl                                        geschaeftsfuehrer/CEO
------------------------------------------------------------------------
eduard-bodem-gasse 5/1    A-6020 innsbruck      phone    ++43 512 935834