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.
Related
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.
I'm not able to correctly configure json support with Spring 4.0.4. A json request results in:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(246): - Looking up handler method for path /equipments/datatable.json
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.resolveException(134): - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
org.springframework.web.servlet.PageNotFound.handleHttpRequestMethodNotSupported(198): - Request method 'GET' not supported
I have an applicationContext.xml and a my-servlet.xml:
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/conf/applicationContext.xml
/WEB-INF/conf/my-security.xml
</param-value>
</context-param>
<servlet>
<servlet-name>losap</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/my-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
applicationContext.xml
<mvc:annotation-driven />
<task:annotation-driven />
<tx:annotation-driven />
<context:component-scan base-package="com.htg.*">
<context:exclude-filter type="regex" expression="com\.htg\.myapp\.mvc"/>
</context:component-scan>
<bean id="messageAdapter"
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</util:list>
</property>
</bean>
my-servlet.xml
<mvc:annotation-driven/>
<context:component-scan base-package="com.htg.myspp.mvc" />
pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
Controller
#Controller()
#RequestMapping(value = "/equipments")
public class EquipmentController extends BaseController {
#RequestMapping(value = "/datatable.json", method = RequestMethod.GET, headers = "Accept:*/*", produces = "application/json")
public #ResponseBody Equipment getEquipmentsDatatable(Model model) {
Equipment e = new Equipment();
e.setEquipmentName("Lathe 123");
e.setEquipmentNumber("12345TTY");
e.setId(89L);
return e;
}
}
jQuery
$.getJSON($('#ctxtrelurl').val() + 'equipments/datatable.json', function(e) {
console.log(e.equipmentName);
});
Chrome Dev. Tools output
I have a feeling it has something to do with having two separate context config. files. Any pointers will be greatly appreciated.
ok, my guess is, that spring doesn't map /datatable.json properly because of the "." I had similar problem at mapping this:
#RequestMapping(value="/somestuff/{fileName:.+}"
i had to put :.+ so spring can properly map the url.
spring seems to truncate ".something" in this case. I actually don't know if it's the case on regular mapping, without #PathVariable. But you could try to map your URL without the dot and check if it will help
And that's why spring try to call the {equipId} function, that is waiting for PUT request. That's why in the response header you see : allow:PUT
I have a web application with Spring MVC.
web.xml
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/companies/*</url-pattern>
</servlet-mapping>
spring controller method:
class RealmInfoController{
#ResponseBody
#RequestMapping(value = {"/companies/{companyId}/realms/{realmName}"})
public RealmInfo realmInfo(#PathVariable long companyId, #PathVariable String realmName)
Handler match:
http://localhost:6122/context/companies/15877/realms/firstRealm
When the server gets this url, the spring servlet gets called. but it cannot match the controller method.
But if I change the request mapping to "/{companyId}/realms/{realmName}" then it matches the controller method. But it is not nice to define the url mapping without '/companies'. Can Spring be instructed in some way to look for match including the url pattern specified in the servlet?
Thanks.
if you want to use "companies" in request mapping you should map your dispatcher servlet to the root:
<url-pattern>/*</url-pattern>
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?
I am working on a Spring application using Tomcat 6 and Spring 2.5. I'm trying to get my URL mapping correct. What I would like to have work is the following:
http://localhost:8080/idptest -> doesn't work
But instead, I have to reference the context name in my URL in order to resolve the mapping:
http://localhost:8080/<context_name>/idptest -> works
How can I avoid the requirement of referencing the context name in my URL without using a rewrite/proxy engine e.g. Apache?
Here is the servlet definition and mapping from my web.xml:
<servlet>
<servlet-name>idptest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/idptest.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>idptest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Here's the outline of my controller (showing annotations for request mappings):
#Controller
#RequestMapping("/idptest")
public class MyController {
#RequestMapping(method=RequestMethod.GET)
public String setupForm(Model model){
MyObject someObject = new MyObject();
model.addAttribute("someObject", someObject);
return "myform";
}
#RequestMapping(method = RequestMethod.POST)
public String processSubmit(#ModelAttribute("someObject") MyObject someObject) throws Exception {
// POST logic...
}
}
Thanks!
That's going to depend on your servlet container, for Tomcat - you pretty much have to deploy your webapp as the ROOT webapp, that is, under $CATALINA_HOME/webapps/ROOT/
More info here
Just rename your war file to ROOT.war, then the application runs in root context (i.e. with empty context name)