Spring Mobile-拦截器未应用?设备为空 [英] Spring Mobile - Interceptor not applied? Device is null

查看:79
本文介绍了Spring Mobile-拦截器未应用?设备为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试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)也许您可以使用

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆