Spring Mobile - перехватчик не применяется? Устройство является нулевым
Я экспериментирую с Spring Mobile, но не могу заставить работать базовый пример. У меня такое чувство, что я скучаю по чему-то глупо простому, но я не могу понять, что это такое. Вот что у меня на месте...
В 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
<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
Почему устройство не установлено и имеет нулевое значение?
РЕДАКТИРОВАТЬ: файлы журнала, кажется, указывают на проблему с установкой перехватчика, но я все еще не уверен, где я ошибся.
2012-05-29 09: 36: 36 696 DEBUG [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: Ошибка при создании компонента с именем org.springframeletwe. MappedInterceptor # 0 ': Неудовлетворенная зависимость, выраженная через аргумент конструктора с индексом 1 типа [org.springframework.web.context.request.WebRequestInterceptor]: не удалось преобразовать значение аргумента конструктора типа [org.springframework.mobile.device.DeviceResolceptorInIn to to обязательный тип [org.springframework.web.context.request.WebRequestInterceptor]: не удалось преобразовать значение типа 'org.springframework.mobile.device.DeviceResolverHandlerInterceptor' в требуемый тип 'org.springframework.web.context.Reest.Reter.Request.Request. вложенное исключение - java.lang.IllegalStateException: невозможно преобразовать значение типа [org.springframework.mobile.device.DeviceResolverHandlerInterceptor] в требуемый тип [org.springframework.web.context.request.WebRequestInterceptor]: не найдено ни одного редактора или преобразования
2 ответа
Я посмотрел на это и смог заставить его работать сам. Итак, у меня есть несколько комментариев.
1a) Я не думаю, что оба фильтра и перехватчик требуются. Я только что использовал фильтр, и этого было достаточно.
1b) Перехватчик (если используется) должен быть настроен в DispatcherServlet
XML-файл конфигурации. Похоже, вы используете Struts от использованияActionSupport
, это правильно? Если это так, у вас (вероятно) не будетDispatcherServlet
и поэтому я не думаю, что этот конфиг будет работать, как ожидалось. Я думаю, именно поэтому вы получаете трассировку стека.
2) я бы добавил точку остановаorg.springframework.mobile.device.DeviceResolverRequestFilter.doFilterInternal
чтобы убедиться, что он выполняется.
3) Я бы проверил, что Struts не делает что-то "смешное" сServletRequest
и как-то скрыть от вас атрибут запроса "currentDevice". На самом деле, я бы по возможности перенес ваш код в vanilla Spring.
4) Может быть, вы могли бы использоватьServletActionContext.getRequest
в вашем execute
метод и посмотреть, если это работает, и / или сравнить возвращенный запрос с этим набором в setServletRequest
,
Используя Spring MVC, это то, что работает для меня. Мой проект называется spring-mobile-test, а "spring-mobile-test" является корневым контекстом:
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 пуст.
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:
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/
:
Привет, пользователь рабочего стола!
Добавление фильтра в web.xml достаточно для того, чтобы справиться с уязвимостью мобильного устройства.
1- Используйте конфигурацию ниже в файле web.xml.
<!--Device Resolver filter start here -->
<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>
2- Добавление ниже файла JAR
spring-mobile-device-1.x.x.RELEASE.jar
3- Код Для проверки устройства
Device device=DeviceUtils.getCurrentDevice(request);
boolean isMobile = device.isMobile();
boolean isTablet=device.isTablet();