jersey 2.5 and Spring 2.5 integration not working - spring

I am trying to integrate Jersey (Version 2.x) into our current project which use's Spring 2.5. I have followed all the steps mentioned in their Spring webapp integration sample, but can't seem to get the auto wiring to work when the Jersey bean is called.
My config/class files are given below,
WEB.XML FILE
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.inrev.rest.XXXSpringIntegration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
SPRING FILE
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean name="myresource" class="com.xxx.rest.MyResource" autowire="byName"></bean>
XXXSpringIntegration CLASS
public XXXSpringIntegration()
{
register(RequestContextFilter.class);
register(MyResource.class);
System.err.println("I am getting registered");
}
MyResource.class
#Path("myresource")
public class MyResource {
#Autowired
private IRAdminDAO adminDAO;
public MyResource()
{
System.err.println("Getting ready now");
}
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#Path("/list")
#GET
#Produces("application/json")
public String list()
{
System.err.println("Adming DAO "+adminDAO);
return "Got it!";
}
public void setAdminDAO(IRAdminDAO adminDAO)
{
System.err.println("Adming dao being set "+adminDAO);
this.adminDAO = adminDAO;
}
}
Added configuration for adminDAO
<bean id="adminDAO" class="com.xxx.bm.dao.impl.IRAdminDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
I am sure that the auto wiring works when Spring get's initialised, as the Syserr in the setter get's called when the file get's initialised by spring. However, when I make the API call, the adminDAO is null.
http://bm.com:8080/bm/rest/myresource/list
What could be causing this, I have tried all other permutation combinations but somehow the autowiring doesn't seem to be working when we make the API call.
Regards

Jersey work's fine with Spring 2.5, it's just a few jar's which were not present in my build. I am not sure if they would come with the maven build, but are certainly not present in the .zip download.
Also, there is no exceptions suggesting the jar is missing. jersey-spring3-2.11.jar being the star.

Related

How to make a class aware of multiple application contexts in Spring MVC?

I'm trying to understand the concepts of application context in Spring MVC. To examine it I have created an application with two application contexts Test-application-context1.xml and Test-application-context2.xml and one web application context Test-dispatcher-servlet.xml. In all of these contexts I initialized a simple java bean with two fields:
1) In Test-application-context1.xml:
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName Context1"/>
<property name="lName" value="LastName Context1"/>
</bean>
2) In Test-application-context2.xml:
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName Context2"/>
<property name="lName" value="LastName Context2"/>
</bean>
3) In Test-dispatcher-servlet.xml::
<bean id="testObject" class="test.TestObject">
<property name="fName" value="FirstName WebContext"/>
<property name="lName" value="LastName WebContext"/>
</bean>
I also provided a proper configuration in the web.xml file to initialize all of these contexts when the server starts:
<servlet>
<servlet-name>dispatcherTest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Test-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherTest</servlet-name>
<url-pattern>/Test/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Test-application-context1.xml /WEB-INF/Test-application-context2.xml</param-value>
</context-param>
Now I want to inject these application/web application contexts in one of my controller classes. I'm not sure how to do this for multiple contexts properly. I know when I have one context I can make my class implement ApplicationContextAware so I tried it like this:
#Controller
public class TestController implements ApplicationContextAware{
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
#RequestMapping(value = "/Test")
public void Test(HttpServletRequest request) {
TestObject testObject = applicationContext.getBean("testObject", TestObject.class);
System.out.println("fName="+testObject.getfName()+"; lName="+testObject.getlName());
}
}
In the above example I always get values of testObject from Test-dispatcher-servlet.xml so it seems that applicationContext that is being injected here represents web application context, BUT if I let's say rename testObject to testObject1 in 'Test-dispatcher-servlet.xml' and run the same code I will get values from Test-application-context2.xml so here are the questions I have.
1) When we make class implement ApplicationContextAware having multiple contexts which context will be injected to that class? Is it one context that is being injected or does spring somehow combines all of contexts and inject them as one applicationContext object (that would explain why do I get values from a different context when I change the name of the bean in one of the contexts)?
2) What is the proper way to inject multiple application contexts to the class?
I know the above example is not a typical scenario and probably a bad design pattern but I'm just trying to understand how the whole thing works.
To answer your 2nd question,
Use #ImportResource as below.
From the docs,
Like #Import, this annotation provides functionality similar to the
element in Spring XML. It is typically used when designing
#Configuration classes
#Configuration
#ImportResource( { "Test-application-context1.xml", "Test-application-context2.xml" } )
public class ConfigClass { }
This will load all beans from both application contexts into the class ConfigClass.
Update:
So, there will be only one application context exists after this import.
You can access any bean from any imported *.context.xml by using #Autowired
After import, Your example in question will throw NoUniqueBeanDefinitionException, because you have more than 1 bean with the same name (testObject) in same application Context.

spring mvc get mapping controller method from interceptor

Now I have a controller like this
#RequestMapping("/content/delete.json")
#Security(auth = AuthType.REQUIRED)
public ModelAndView deleteIndex(User user, #RequestParam("id") long id) {
}
Now I am trying to get controller mapping method from interceptor and getting the annotation of the method.
Method method = RestRequestURLUtil.getInvokedMethod(handler, request);
Security security = method.getAnnotation(Security.class);
if(security.getAuth() == AuthType.REQUIRED) {
do some validate here
}
Are there any classes like RestRequestURLUtil in spring?
thanks in advance :)
edit:
web.xml
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/rest-servlet.xml,
/WEB-INF/interceptor-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
interceptor-server.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.test.web.interceptors.SecurityInterceptor" init-method="init">
...
</bean>
</mvc:interceptor>
The annotation on the controller's method can be inspected in the interceptor by means of the HandlerMethod object that the framework should pass as handler Object.
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
if (method.getMethod().isAnnotationPresent(Security.class)) {
//do processing
}
}
However, according to the spring documentation in HandlerMethod javadoc, HandlerMethod class was introduced in Spring 3.1. It seems that, in versions prior to 3.1, handler object was a Controller instance, which makes fetching the annotation of the invoked controller method difficult.
You can either upgrade to 3.1. and fetch the annotation from HandlerMethod object or attempt to parse all the RequestMapping annotations on the controller methods and then attempt to determine which method was invoked by comparing RequestMappings with request URI.
If upgrade is not an option, another alternative would be to use AOP instead of mvc interceptor.

Jersey-Spring #Autowired not working

I'm using Jersey-Spring integration to expose business layer services.
In my web.xml I'm using the SpringServlet:
com.sun.jersey.spi.spring.container.servlet.SpringServlet
My business layer is #Component annotated, so I have #Service's using #Repository's provided via Spring's annotation config.
Repository's are provided to service's via #Autowired annotation.
If I use a repository through a service using my front end MVC classes everithig goes well, but if I use it through Jersey I get a NullPointerException on the repository object.
The version I'm using (through Maven) are:
Spring (and extensions): 3.1.3.RELEASE
Jersey (and extensions): 1.17
There is way to solve this problem using the same version mentioned in your question,
If needed ill mention the second way , the first way is to load sring through web.xml
like shown below as normal spring confifuration:
<servlet>
<servlet-name>project-spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:project-spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>project-spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
Now load your jersey Resources through Application as shown below:
#ApplicationPath("/rest")
public class ResourceLoader extends Application
{
/* (non-Javadoc)
* #see javax.ws.rs.core.Application#getClasses()
*/
#Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
loadResourceClasses(classes);
return classes;
}
private void loadResourceClasses(Set<Class<?>> classes)
{
classes.add(StudentResource.class);
}
}
Then in your resource:
#Path("student")
class StudentResource
{
private StudentService studentService;
StudentResource(#Context ServletContext servletContext)
{
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
this.transactionService = applicationContext.getBean(StudentService .class);
}
}
There'r you go Spring has been configured with all dependency injections with Jersey!!!
You should try using #InjectParam

The spring web mvc framework handle the jsp file dispatch as another request

I am new to spring web mvc framework,and I use struts 2 before.
I create a new dynamic web project using eclipse EE,and add all the jars to the /web-info/lib.
The whole hierarchy of the project is like this:
SpringMVCTest
WEB-INF
web.xml
example-servlet.xml
jsp
hello.jsp
lib
xxxx.jars
.....
This is the servlet definition:
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This is the example-servlet.xml:
<context:component-scan base-package="com.kk.web.controllers" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
And the controller:
package com.kk.web.controllers;
#Controller("example")
#RequestMapping("/example")
public class ExampleController {
#RequestMapping("/hello")
#ResponseBody
public String hello() {
return "hello";
}
#RequestMapping("/hello_jsp")
public ModelAndView hello_jsp(){
ModelAndView mv=new ModelAndView("hello");
mv.addObject("message", "welcome");
return mv;
}
}
It worked when I run:
http://localhost:8080/SpringMVCTest/example/hello
But when I run:
http://localhost:8080/SpringMVCTest/example/hello_jsp
I got the warn:
2011-10-17 10:36:15 org.springframework.web.servlet.DispatcherServlet noHandlerFound
Warn: No mapping found for HTTP request with URI [/SpringMVCTest/WEB-INF/jsp/hello.jsp] in DispatcherServlet with name 'example'
It seems that the ExampleController works,it dispatch the request "/example/hello_jsp" to the right view "jsp/hello.jsp".
But then the spring take the file dispatch "/jsp/hello.jsp" as another request,then it will not find the matched url mapping in the "example" controller.
Why?? IMO,a requst must come from the client to server,the controller receive only one request here "/exmaple/hello_jsp",isn't it?
And How to fix it?
BTW,I can set the url pattern to "/*.xxx",but I do not want the suffix in the url.
Any ideas?
Previous answer did not work...
This posting looks similar: http://forum.springsource.org/showthread.php?55982-No-mapping-found-for-HTTP-request-with-MVC-requests
Summary: change
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
to
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
and checking my latest Spring MVC app I use the latter pattern (no * on the end).

Spring Extension REST Resource #RequestParam annotation not detected

trying to use the spring extension of Restlet ,
have configured as per the example http://wiki.restlet.org/docs_2.1/13-restlet/28-restlet/70-restlet/196-restlet.html
In addition to that trying to capture the request parameters using the #RequestParam annotation but end up getting the parameter value as null.
Resource looks like,
class MyResource extends ServerResource implements IResource {
#Get
#RequestMapping(value="/id")
public void get(#RequestParam(value="name") String name) {
...
}
}
HTTP Request http://localhost:8080/messages/id?name=XXX
Web.xml looks like
<servlet>
<servlet-name>test-servlet</servlet-name>
<servlet-class>org.restlet.ext.spring.RestletFrameworkServlet</servlet-class>
</servlet>
<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>test-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
In the end the name value is 'null'. I think the spring based annotations are not detected. I have no clue why this is happening?

Resources