在Spring moble框架中提供了一个Device的接口
package org.springframework.mobile.device;
/**
* A model for the user agent or device that submitted the current request.
* Callers may introspect this model to vary UI control or rendering logic by device type.
* @author Keith Donald
* @author Roy Clarkson
* @author Scott Rossillo
* @author Onur Kagan Ozcan
*/
public interface Device {
/**
* True if this device is not a mobile or tablet device.
*/
boolean isNormal();
/**
* True if this device is a mobile device such as an Apple iPhone or an Nexus One Android.
* Could be used by a pre-handle interceptor to redirect the user to a dedicated mobile web site.
* Could be used to apply a different page layout or stylesheet when the device is a mobile device.
*/
boolean isMobile();
/**
* True if this device is a tablet device such as an Apple iPad or a Motorola Xoom.
* Could be used by a pre-handle interceptor to redirect the user to a dedicated tablet web site.
* Could be used to apply a different page layout or stylesheet when the device is a tablet device.
*/
boolean isTablet();
/**
*
* @return resolved DevicePlatform
*/
DevicePlatform getDevicePlatform();
}
想要拓展这个接口,加上自己的deivce
package eu.digient.billfold.support.web
import org.springframework.mobile.device.Device
import org.springframework.mobile.device.DevicePlatform
import eu.digient.sdk.util.DeviceType
interface TitanDevice extends Device {
boolean isMobileApp()
}
class TitanDeviceImpl implements TitanDevice {
private final Device device
private final DeviceType deviceType
TitanDeviceImpl(Device device) {
this.device = device
}
TitanDeviceImpl(Device device, DeviceType deviceType) {
this.device = device
this.deviceType = deviceType
}
boolean isNormal() {
return deviceType == DeviceType.Desktop ?: device?.isNormal()
}
boolean isMobile() {
return deviceType == DeviceType.Mobile ?: device?.isMobile()
}
boolean isTablet() {
return deviceType == DeviceType.Tablet ?: device?.isTablet()
}
boolean isMobileApp() {
return deviceType == DeviceType.MobileApp
}
DevicePlatform getDevicePlatform() {
return device?.getDevicePlatform()
}
}
对外提供两个构造方法用来辨别deviceType, 在重写一下LiteDeviceResolver里面的resolveDevice方法这里面可以加上自己的逻辑。
class InternalDeviceResolver extends LiteDeviceResolver {
private static final String USER_AGENT_HEADER_NAME = 'userAgent'
private static final String USER_AGENT_MOBILE_APP = 'XXXXX'
@Override
Device resolveDevice(HttpServletRequest request) {
def device = super.resolveDevice(request)
def ua = request.getHeader(USER_AGENT_HEADER_NAME)
if (ua != null && ua.toLowerCase().indexOf(USER_AGENT_MOBILE_APP) >= 0) {
return new TitanDeviceImpl(device, DeviceType.MobileApp)
}
return new TitanDeviceImpl(device)
}
}
接着在Springmvc.xml 配置文件中添加 InternalDeviceResolver 拦截器:
<mvc:interceptors>
<!-- On pre-handle, resolve the device that originated the web request -->
<bean class="eu.digient.billfold.support.web.InternalDeviceResolverHandlerInterceptor"/>
</mvc:interceptors>
使用自定义的define拦截器而不是spring拦截器从请求解析设备
class InternalDeviceResolverHandlerInterceptor extends HandlerInterceptorAdapter {
private final InternalDeviceResolver deviceResolver
InternalDeviceResolverHandlerInterceptor(InternalDeviceResolver deviceResolver) {
this.deviceResolver = deviceResolver
}
InternalDeviceResolverHandlerInterceptor() {
this(new InternalDeviceResolver())
}
@Override
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Device device = deviceResolver.resolveDevice(request)
request.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, device)
return true
}
}
这样我们在解析device的时候,只需要把device 强转成 TitanDevice就好了
class DeviceResolverImpl implements DeviceResolver {
DeviceType resolveDevice(final Device device) {
TitanDevice titanDevice = device as TitanDevice
if (titanDevice?.isMobileApp()) {
return DeviceType.MobileApp
} else if (titanDevice?.isTablet()) {
return DeviceType.Tablet
} else if (titanDevice?.isMobile()) {
return DeviceType.Mobile
}
return DeviceType.Desktop
}
}