Spring Mobile-拦截器未应用?设备为空 [英] Spring Mobile - Interceptor not applied? Device is null
问题描述
我正在尝试Spring Mobile,但似乎无法使基本示例正常工作.我感觉自己缺少了一些愚蠢的简单东西,但我不知道它是什么.这就是我所拥有的...
I'm experimenting with Spring Mobile but I can't seem to get the basic example working. I have a feeling I'm missing something stupidly simple but I can't figure out what it is. Here is what I have in place...
在web.xml中
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>deviceResolverRequestFilter</filter-name>
<filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>deviceResolverRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在applicationContext.xml中
In applicationContext.xml
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:device="http://www.springframework.org/schema/mobile/device"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mobile/device
http://www.springframework.org/schema/mobile/device/spring-mobile-device-1.0.xsd">
<!-- Interceptors that execute common control logic across multiple requests -->
<interceptors>
<!-- Detects the client's Device -->
<beans:bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
</interceptors>
</beans:beans>
在我的Java课中:
public class TestAction extends ActionSupport implements ServletRequestAware {
// So that we can lookup the current Device
private HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
@Override
public String execute() {
Device currentDevice = DeviceUtils.getCurrentDevice(request);
if (currentDevice.isMobile()) // <-- fails here with NPE
为什么未设置设备并显示为空?
日志文件似乎表明设置拦截器存在问题,但我仍然不确定出错的地方.
Log files seem to indicate a problem with setting the interceptor but I'm still not sure where I went wrong.
2012-05-29 09:36:36,696调试[ConstructorResolver.java:201]: 忽略构造函数[public org.springframework.web.servlet.handler.MappedInterceptor(java.lang.String [],org.springframework.web.context.request.WebRequestInterceptor)] Bean'org.springframework.web.servlet.handler.MappedInterceptor#0'的形式: org.springframework.beans.factory.UnsatisfiedDependencyException: 使用名称创建bean时出错 'org.springframework.web.servlet.handler.MappedInterceptor#0': 不满意的依赖关系通过构造函数参数表示为 类型索引1 [org.springframework.web.context.request.WebRequestInterceptor]:可以 不转换类型的构造函数参数值 [org.springframework.mobile.device.DeviceResolverHandlerInterceptor] 到所需的类型 [org.springframework.web.context.request.WebRequestInterceptor]: 无法转换类型的值 'org.springframework.mobile.device.DeviceResolverHandlerInterceptor' 到所需的类型 'org.springframework.web.context.request.WebRequestInterceptor'; 嵌套的异常是java.lang.IllegalStateException:无法转换 类型值 [org.springframework.mobile.device.DeviceResolverHandlerInterceptor] 到所需的类型 [org.springframework.web.context.request.WebRequestInterceptor]:否 找到匹配的编辑器或转换策略
2012-05-29 09:36:36,696 DEBUG [ConstructorResolver.java:201] : Ignoring constructor [public org.springframework.web.servlet.handler.MappedInterceptor(java.lang.String[],org.springframework.web.context.request.WebRequestInterceptor)] of bean 'org.springframework.web.servlet.handler.MappedInterceptor#0': org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.web.servlet.handler.MappedInterceptor#0': Unsatisfied dependency expressed through constructor argument with index 1 of type [org.springframework.web.context.request.WebRequestInterceptor]: Could not convert constructor argument value of type [org.springframework.mobile.device.DeviceResolverHandlerInterceptor] to required type [org.springframework.web.context.request.WebRequestInterceptor]: Failed to convert value of type 'org.springframework.mobile.device.DeviceResolverHandlerInterceptor' to required type 'org.springframework.web.context.request.WebRequestInterceptor'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.mobile.device.DeviceResolverHandlerInterceptor] to required type [org.springframework.web.context.request.WebRequestInterceptor]: no matching editors or conversion strategy found
推荐答案
我对此进行了查看,并设法使它自己起作用.所以我有几点评论.
I've had a look at this and managed to get it to work myself. So I have a few comments.
1a)我认为过滤器和拦截器都不是必需的. 我刚刚使用过滤器就足够了.
1a) I don't think both the Filter and the Interceptor are required. I've just used the Filter and that was enough.
1b)拦截器(如果使用)应在DispatcherServlet
xml配置文件中进行配置.您看起来像是使用ActionSupport
来使用Struts,这是正确的吗?如果是这样,您(可能)将没有DispatcherServlet
,因此我认为此配置不会按预期工作.我认为这就是为什么要获取堆栈跟踪的原因.
1b) The Interceptor (if used) should be configured in a DispatcherServlet
xml config file. You look like you are using Struts from the use of ActionSupport
, is this correct? If so, you (probably) won't have a DispatcherServlet
and therefore I don't think this config will work as expected. I think that's why you're getting the stack trace.
2)我将在org.springframework.mobile.device.DeviceResolverRequestFilter.doFilterInternal
上添加一个断点,以确保它正在执行.
2) I would add a breakpoint to org.springframework.mobile.device.DeviceResolverRequestFilter.doFilterInternal
to make sure it's being executed.
3)我将检查Struts是否没有对ServletRequest
做任何有趣"的操作,并隐藏.实际上,如果可能的话,我会将您的代码移植到Vanilla Spring.
3) I would check that Struts isn't doing something 'funny' with the ServletRequest
, and hiding the "currentDevice" request attribute from you somehow. In fact, I would port your code to vanilla Spring if possible.
4) Maybe you could use ServletActionContext.getRequest
in your execute
method and see if that works, and/or compare the returned request to that set in setServletRequest
.
使用Spring MVC,这对我有效.我的项目称为spring-mobile-test,"spring-mobile-test"是其上下文根:
Using Spring MVC, this is what works for me. My project is called spring-mobile-test, and "spring-mobile-test" is its context root:
web.xml:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 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" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>deviceResolverRequestFilter</filter-name>
<filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>deviceResolverRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/mvc/*</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.xml为空.
applicationContext.xml is empty.
mvc-servlet.xml:
mvc-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="temp" />
</beans>
temp.TestController:
temp.TestController:
package temp;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class TestController {
private static final Logger logger = Logger.getLogger(TestController.class);
@RequestMapping("/")
public @ResponseBody
String home(HttpServletRequest req) {
Device device = DeviceUtils.getCurrentDevice(req);
String msg = "";
if (device.isMobile()) {
msg = "Hello mobile user!";
} else {
msg = "Hello desktop user!";
}
logger.info(msg);
return msg;
}
}
当我浏览到URL http://localhost/spring-mobile-test/mvc/
时,浏览器显示以下文本:
The browser shows the following text when I browse to the URL http://localhost/spring-mobile-test/mvc/
:
您好,桌面用户!
Hello desktop user!
这篇关于Spring Mobile-拦截器未应用?设备为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!