spring mobile 的扩展

spring mobile 是spring新推出的一个用于支持移动浏览的小框架,用起来很简单,和spring mvc结合也很方便。它可以测试出访问的设备(DEVICE)但是默认的只能检测出三种(Mobile,Tablet,Normal),本文就是对它的扩展(spring mobile 的官网 实例 http://projects.spring.io/spring-mobile)。


首先自定义设备接口继承spring的Device,添加几种设备。

package com.jy.device;

import org.springframework.mobile.device.Device;

public interface CustomDevice extends Device{

    public boolean isIphone();
    public boolean isAndroid();
    public boolean isIpad();
    public boolean isWinPhone();
    
}
设备类型的枚举

package com.jy.device;

public enum CustomDeviceType {


    /**
     * Represents a normal device. i.e. a browser on a desktop or laptop computer
     */
    NORMAL,
    
    /**
     * Represents a mobile device, such as an iPhone
     */
    MOBILE,
    
    /**
     * Represents a tablet device, such as an iPad
     */
    TABLET,
    
    IPHONE,//这两个是新加的
    
    ANDROID
    
    
    
}

设备的实现


package com.jy.device.impl;


import com.jy.device.CustomDevice;
import com.jy.device.CustomDeviceType;

class CustomLiteDevic implements CustomDevice{

    public static final CustomLiteDevic NORMAL_INSTANCE = new CustomLiteDevic(CustomDeviceType.NORMAL);

    public static final CustomLiteDevic MOBILE_INSTANCE = new CustomLiteDevic(CustomDeviceType.MOBILE);

    public static final CustomLiteDevic TABLET_INSTANCE = new CustomLiteDevic(CustomDeviceType.TABLET);
    
    public static final CustomLiteDevic IPHONE_INSTANCE = new CustomLiteDevic(CustomDeviceType.IPHONE);
    
    public static final CustomLiteDevic ANDROID_INSTANCE = new CustomLiteDevic(CustomDeviceType.ANDROID);
    
    public boolean isNormal() {
        return this.deviceType == CustomDeviceType.NORMAL;
    }

    public boolean isMobile() {
        return this.deviceType == CustomDeviceType.MOBILE;
    }

    public boolean isTablet() {
        return this.deviceType == CustomDeviceType.TABLET;
    }

    public CustomDeviceType getDeviceType() {
        return this.deviceType;
    }
    
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[LiteDevice ");
        builder.append("type").append("=").append(this.deviceType);
        builder.append("]");
        return builder.toString();
    }

    private final CustomDeviceType deviceType;

    /**
     * Creates a LiteDevice.
     */
    private CustomLiteDevic(CustomDeviceType customDeviceType) {
        this.deviceType = customDeviceType;
    }

    @Override
    public boolean isIphone() {
        return this.deviceType == CustomDeviceType.IPHONE;
    }

    @Override
    public boolean isAndroid() {
        return this.deviceType == CustomDeviceType.ANDROID;
    }

    @Override
    public boolean isIpad() {
        return false;
    }

    @Override
    public boolean isWinPhone() {
        // TODO Auto-generated method stub
        return false;
    }

}

设备的检测,判断

package com.jy.device.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceResolver;
import org.springframework.stereotype.Component;

@Component
public class CustomLiteDeviceResolver implements DeviceResolver{

    private final List<String> mobileUserAgentPrefixes = new ArrayList<String>();

    private final List<String> mobileUserAgentKeywords = new ArrayList<String>();

    private final List<String> tabletUserAgentKeywords = new ArrayList<String>();

    private final List<String> normalUserAgentKeywords = new ArrayList<String>();

    public CustomLiteDeviceResolver() {
        init();
    }

    public CustomLiteDeviceResolver(List<String> normalUserAgentKeywords) {
        init();
        this.normalUserAgentKeywords.addAll(normalUserAgentKeywords);
    }

    public Device resolveDevice(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        // UserAgent keyword detection of Normal devices
        if (userAgent != null) {
            userAgent = userAgent.toLowerCase();
            for (String keyword : normalUserAgentKeywords) {
                if (userAgent.contains(keyword)) {
                    return resolveFallback(request);
                }
            }
        }
        // UserAgent keyword detection of Tablet devices
        if (userAgent != null) {
            userAgent = userAgent.toLowerCase();
            // Android special case
            if (userAgent.contains("android")) {
                return CustomLiteDevic.ANDROID_INSTANCE;
            }
            if (userAgent.contains("safari")&& userAgent.contains("iphone")) {
                return CustomLiteDevic.IPHONE_INSTANCE;
            }
            
            // Kindle Fire special case
            if (userAgent.contains("silk") && !userAgent.contains("mobile")) {
                return CustomLiteDevic.TABLET_INSTANCE;
            }
            for (String keyword : tabletUserAgentKeywords) {
                if (userAgent.contains(keyword)) {
                    return CustomLiteDevic.TABLET_INSTANCE;
                }
            }
        }
        // UAProf detection
        if (request.getHeader("x-wap-profile") != null
                || request.getHeader("Profile") != null) {
            return CustomLiteDevic.MOBILE_INSTANCE;
        }
        // User-Agent prefix detection
        if (userAgent != null && userAgent.length() >= 4) {
            String prefix = userAgent.substring(0, 4).toLowerCase();
            if (mobileUserAgentPrefixes.contains(prefix)) {
                return CustomLiteDevic.MOBILE_INSTANCE;
            }
        }
        // Accept-header based detection
        String accept = request.getHeader("Accept");
        if (accept != null && accept.contains("wap")) {
            return CustomLiteDevic.MOBILE_INSTANCE;
        }
        // UserAgent keyword detection for Mobile devices
        if (userAgent != null) {
            for (String keyword : mobileUserAgentKeywords) {
                if (userAgent.contains(keyword)) {
                    return CustomLiteDevic.MOBILE_INSTANCE;
                }
            }
        }
        // OperaMini special case
        @SuppressWarnings("rawtypes")
        Enumeration headers = request.getHeaderNames();
        while (headers.hasMoreElements()) {
            String header = (String) headers.nextElement();
            if (header.contains("OperaMini")) {
                return CustomLiteDevic.MOBILE_INSTANCE;
            }
        }
        return resolveFallback(request);
    }

    // subclassing hooks

    /**
     * List of user agent prefixes that identify mobile devices. Used primarily to match
     * by operator or handset manufacturer.
     */
    protected List<String> getMobileUserAgentPrefixes() {
        return mobileUserAgentPrefixes;
    }

    /**
     * List of user agent keywords that identify mobile devices. Used primarily to match
     * by mobile platform or operating system.
     */
    protected List<String> getMobileUserAgentKeywords() {
        return mobileUserAgentKeywords;
    }

    /**
     * List of user agent keywords that identify tablet devices. Used primarily to match
     * by tablet platform or operating system.
     */
    protected List<String> getTabletUserAgentKeywords() {
        return tabletUserAgentKeywords;
    }

    /**
     * List of user agent keywords that identify normal devices. Any items in this list
     * take precedence over the mobile and tablet user agent keywords, effectively
     * overriding those.
     */
    protected List<String> getNormalUserAgentKeywords() {
        return normalUserAgentKeywords;
    }
    
    /**
     * Initialize this device resolver implementation. Registers the known set of device
     * signature strings. Subclasses may override to register additional strings.
     */
    protected void init() {
        getMobileUserAgentPrefixes().addAll(
                Arrays.asList(KNOWN_MOBILE_USER_AGENT_PREFIXES));
        getMobileUserAgentKeywords().addAll(
                Arrays.asList(KNOWN_MOBILE_USER_AGENT_KEYWORDS));
        getTabletUserAgentKeywords().addAll(
                Arrays.asList(KNOWN_TABLET_USER_AGENT_KEYWORDS));
    }

    /**
     * Fallback called if no mobile device is matched by this resolver. The default
     * implementation of this method returns a "normal" {@link Device} that is neither
     * mobile or a tablet. Subclasses may override to try additional mobile or tablet
     * device matching before falling back to a "normal" device.
     */
    protected Device resolveFallback(HttpServletRequest request) {
        return CustomLiteDevic.NORMAL_INSTANCE;
    }

    // internal helpers

    private static final String[] KNOWN_MOBILE_USER_AGENT_PREFIXES = new String[] {
            "w3c ", "w3c-", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq",
            "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-", "dang", "doco",
            "eric", "hipt", "htc_", "inno", "ipaq", "ipod", "jigs", "kddi", "keji",
            "leno", "lg-c", "lg-d", "lg-g", "lge-", "lg/u", "maui", "maxo", "midp",
            "mits", "mmef", "mobi", "mot-", "moto", "mwbp", "nec-", "newt", "noki",
            "palm", "pana", "pant", "phil", "play", "port", "prox", "qwap", "sage",
            "sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-",
            "siem", "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-",
            "tosh", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa", "wapi",
            "wapp", "wapr", "webc", "winw", "winw", "xda ", "xda-" };

    private static final String[] KNOWN_MOBILE_USER_AGENT_KEYWORDS = new String[] {
            "blackberry", "webos", "ipod", "lge vx", "midp", "maemo", "mmp", "mobile",
            "netfront", "hiptop", "nintendo DS", "novarra", "openweb", "opera mobi",
            "opera mini", "palm", "psp", "phone", "smartphone", "symbian", "up.browser",
            "up.link", "wap", "windows ce" };

    private static final String[] KNOWN_TABLET_USER_AGENT_KEYWORDS = new String[] {
            "ipad", "playbook", "hp-tablet", "kindle" };

}

最后在spring_mvc的配置文件中把自己定义的CustomLiteDeviceResolver注入到拦截器中
<mvc:interceptors>
      <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" >
          <constructor-arg>
          <bean class="com.jy.device.impl.CustomLiteDeviceResolver" />
          </constructor-arg>
      </bean>
    </mvc:interceptors>

配置参数的转化(方便spring mvc 中接收处理Device 参数)

<mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

测试方法

启动web服务器
写一个如下的请求测试

    /**
     * 用户退出
     *
     * @param fengexUser
     * @return
     */
    @RequestMapping(value = "/loginout")
    @ResponseBody
    public Object loginOut(CustomDevice device) {// TODO 退出操作(c)
    // logger.debug("member(id) loginout:" + member.getId());
        logger.debug("is phone? " + device.isMobile());
        logger.debug("is tablet? " + device.isTablet());
        logger.debug("is normal? " + device.isNormal());
        return null;
    }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值