[JAVA] Verwenden Sie Spring Mobile, um den Gerätetyp von Smartphones, Tablets und PCs zu bestimmen

Überblick

Quellcode

Quellcodeliste

Nur zwei, DeviceInfoController.java und pom.xml.

├── pom.xml
└── src
    └── main
        └── java
            └── com
                └── example
                    └── deviceinfo
                        └── DeviceInfoController.java

Maven Build-Datei pom.xml

-Einführung von Spring Mobile in Abhängigkeiten

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>com.example</groupId>
  <artifactId>deviceinfo</artifactId>
  <version>0.0.1</version>
  <name>deviceinfo</name>
  <description>Deviceinfo project for Spring Boot</description>

  <properties>
    <java.version>11</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--Einführung von Spring Mobile-->
    <dependency>
      <groupId>org.springframework.mobile</groupId>
      <artifactId>spring-mobile-device</artifactId>
      <version>2.0.0.M3</version>
    </dependency>
  </dependencies>

  <repositories>
    <!--Repository mit Meilensteinversion von Spring Mobile hinzugefügt-->
    <repository>
      <id>spring-milestone</id>
      <name>Spring Milestone Repository</name>
      <url>http://repo.spring.io/milestone</url>
    </repository>
  </repositories>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

DeviceInfoController.java

package com.example.deviceinfo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DevicePlatform;
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@Configuration
@RestController
public class DeviceInfoController implements WebMvcConfigurer {

  public static void main(String[] args) {
    SpringApplication.run(DeviceInfoController.class, args);
  }

  //Erforderlich, um Spring Mobile zu verwenden
  @Bean
  public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
    return new DeviceResolverHandlerInterceptor();
  }

  //Erforderlich, um Spring Mobile zu verwenden
  // WebMvcConfigurer#addInterceptors
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(deviceResolverHandlerInterceptor());
  }

  @RequestMapping("/")
  public Map index(WebRequest req) {

    Map res = new HashMap<String, String>();

    String userAgent = req.getHeader(HttpHeaders.USER_AGENT);
    res.put("useragent", userAgent);

    Device device = DeviceUtils.getCurrentDevice(req);
    if (device == null) {
      res.put("device", "null");
    } else if (device.isMobile()) {
      res.put("device", "mobile");
    } else if (device.isTablet()) {
      res.put("device", "tablet");
    } else if (device.isNormal()) {
      res.put("device", "normal");
    }

    if (device != null) {
      DevicePlatform dp = device.getDevicePlatform();
      switch (dp) {
        case ANDROID:
          res.put("platform", "android");
          break;
        case IOS:
          res.put("platform", "ios");
          break;
        case UNKNOWN:
          res.put("platform", "unknown");
          break;
      }
    }

    return res;
  }
}

Erstellen und starten

Generieren Sie eine JAR-Datei mit dem mvn-Paket.

$ mvn package

Starten Sie Spring Boot mit dem Befehl java.

$ java -jar target/deviceinfo-0.0.1.jar

Versuchen Sie, mit verschiedenen Benutzeragenten darauf zuzugreifen

Versuchen Sie den Zugriff, indem Sie verschiedene Benutzeragenten mit Ruby + Curl angeben.

require 'json'

ualist = []

## Smartphone

# iPhone + iOS + Safari
ualist << 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'

# iPhone + iOS + Chrome
ualist << 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.91 Mobile/15E148 Safari/605.1'

# Galaxy A30 SCV43 + Android + Browser
ualist << 'Mozilla/5.0 (Linux; Android 9; SCV43 Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.0 Chrome/67.0.3396.87 Mobile Safari/537.36'

# Xperia XZ3 SOV39 + Chrome
ualist << 'Mozilla/5.0 (Linux; Android 9; SOV39 Build/52.0.C.1.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36'

## Tablet

# iPad mini + iOS + Safari
ualist << 'Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'

# Qua tab QZ10 + Android + Chrome
ualist << 'Mozilla/5.0 (Linux; Android 8.1.0; KYT33 Build/3.020VE.0072.a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Safari/537.36'

## Desktop

# macOS + Safari
ualist << 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15'

# Windows 10 + Microsoft Edge
ualist << 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'

ualist.each do |ua|
  json = `#{"curl --silent --user-agent '#{ua}' http://localhost:8080/"}`
  puts JSON.pretty_generate(JSON.parse(json))
  puts
end

Ausführungsergebnis. Sie können sehen, dass der Benutzeragent analysiert und fest bestimmt werden kann.

{
  "useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1",
  "device": "mobile",
  "platform": "ios"
}

{
  "useragent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.91 Mobile/15E148 Safari/605.1",
  "device": "mobile",
  "platform": "ios"
}

{
  "useragent": "Mozilla/5.0 (Linux; Android 9; SCV43 Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.0 Chrome/67.0.3396.87 Mobile Safari/537.36",
  "device": "mobile",
  "platform": "android"
}

{
  "useragent": "Mozilla/5.0 (Linux; Android 9; SOV39 Build/52.0.C.1.119) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36",
  "device": "mobile",
  "platform": "android"
}

{
  "useragent": "Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1",
  "device": "tablet",
  "platform": "ios"
}

{
  "useragent": "Mozilla/5.0 (Linux; Android 8.1.0; KYT33 Build/3.020VE.0072.a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Safari/537.36",
  "device": "tablet",
  "platform": "android"
}

{
  "useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15",
  "device": "normal",
  "platform": "unknown"
}

{
  "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362",
  "device": "normal",
  "platform": "unknown"
}

Zulassen, dass das Gerät als Argument der Handler-Methode angegeben wird

Ändern Sie DeviceInfoController.java so, dass Device als Argument der Handler-Methode angegeben werden kann (Methode mit Annotation @RequestMapping).

package com.example.deviceinfo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
import org.springframework.mobile.device.DevicePlatform;
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
import org.springframework.mobile.device.DeviceUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootApplication
@Configuration
@RestController
public class DeviceInfoController implements WebMvcConfigurer {

  public static void main(String[] args) {
    SpringApplication.run(DeviceInfoController.class, args);
  }

  //Erforderlich, um Spring Mobile zu verwenden
  @Bean
  public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
    return new DeviceResolverHandlerInterceptor();
  }

  //Erforderlich, um Spring Mobile zu verwenden
  // WebMvcConfigurer#addInterceptors
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(deviceResolverHandlerInterceptor());
  }

  // @Methode mit RequestMapping(Handler-Methode)Zum Argument von
  //Erforderlich, um das Gerät von Spring Mobile angeben zu können
  @Bean
  public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() {
    return new DeviceHandlerMethodArgumentResolver();
  }

  // @Methode mit RequestMapping(Handler-Methode)Zum Argument von
  //Erforderlich, um das Gerät von Spring Mobile angeben zu können
  // WebMvcConfigurer#addArgumentResolvers
  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(deviceHandlerMethodArgumentResolver());
  }

  @RequestMapping("/")
  public Map index(WebRequest req, Device device) {

    Map res = new HashMap<String, String>();

    String userAgent = req.getHeader(HttpHeaders.USER_AGENT);
    res.put("useragent", userAgent);

    //Dieser Vorgang ist nicht erforderlich, da das Gerät als Argument der Handler-Methode angegeben werden kann.
    //Device device = DeviceUtils.getCurrentDevice(req);

    if (device == null) {
      res.put("device", "null");
    } else if (device.isMobile()) {
      res.put("device", "mobile");
    } else if (device.isTablet()) {
      res.put("device", "tablet");
    } else if (device.isNormal()) {
      res.put("device", "normal");
    }

    if (device != null) {
      DevicePlatform dp = device.getDevicePlatform();
      switch (dp) {
        case ANDROID:
          res.put("platform", "android");
          break;
        case IOS:
          res.put("platform", "ios");
          break;
        case UNKNOWN:
          res.put("platform", "unknown");
          break;
      }
    }

    return res;
  }
}

Wie Spring Mobile Geräte identifiziert

Der nächste Artikel handelt von einer älteren Version, aber ich vermute, dass sich daran nicht viel geändert hat.

Spring Mobile 1 \ .0 veröffentlicht

LiteDeviceResolver wird standardmäßig für die Geräteauflösung verwendet. Es basiert auf dem Erkennungsalgorithmus von WordPress Mobile Pack. Eine andere DeviceResolver-Implementierung kann durch Einfügen des Konstruktorarguments von DeviceResolverHandlerInterceptor angeschlossen werden. Resolver für anspruchsvollere Geräte wie WURFL können bestimmte Gerätefunktionen wie Bildschirmgröße, Hersteller, Modell oder Prioritätsmarkierung identifizieren.

Wenn Sie sich den Quellcode von LiteDeviceResolver.java ansehen, können Sie anhand der Zeichenfolge des Benutzeragenten erkennen, wie das Gerät identifiziert wird.

spring-mobile/LiteDeviceResolver.java at v2.0.0.M3 · spring-projects/spring-mobile · GitHub

// Android special case
if (userAgent.contains("android")) {
  return resolveWithPlatform(DeviceType.MOBILE, DevicePlatform.ANDROID);
}
// Apple special case
if (userAgent.contains("iphone") || userAgent.contains("ipod") || userAgent.contains("ipad")) {
  return resolveWithPlatform(DeviceType.MOBILE, DevicePlatform.IOS);
}

Um Spring Mobile verwenden zu können, müssen Sie WebMvcConfigurer # addInterceptors implementieren und das DeviceResolverHandlerInterceptor-Objekt in seiner Methode zum InterceptorRegistry-Objekt hinzufügen.

Dies liegt daran, dass das DeviceResolverHandlerInterceptor-Objekt ein Geräteobjekt erstellt und es vor der Verarbeitung in der Handler-Methode als Attribut in HttpServletRequest # setAttribute hinzufügt.

spring-mobile/DeviceResolverHandlerInterceptor.java at v2.0.0.M3 · spring-projects/spring-mobile · GitHub

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  Device device = deviceResolver.resolveDevice(request);
  request.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, device);
  return true;
}

spring-mobile/DeviceUtils.java at v2.0.0.M3 · spring-projects/spring-mobile · GitHub

DeviceUtils.getCurrentDevice gibt nur die festgelegten Attribute zurück.

public static Device getCurrentDevice(HttpServletRequest request) {
  return (Device) request.getAttribute(CURRENT_DEVICE_ATTRIBUTE);
}

Referenzmaterial

Recommended Posts

Verwenden Sie Spring Mobile, um den Gerätetyp von Smartphones, Tablets und PCs zu bestimmen
Fühlen Sie den Grundtyp und Referenztyp leicht mit Rubin
[Für Anfänger] DI ~ Die Grundlagen von DI und DI im Frühjahr ~
Kompatibilität von Spring JDBC und My Batis mit Spring Data JDBC (vorläufig)
Greifen Sie mit jdbcTemplate auf das integrierte h2db des Spring Boot zu
Bis zur Verwendung von Spring Data und JPA Part 2
Bis zur Verwendung von Spring Data und JPA Part 1
Fühlen Sie den Grundtyp und Referenztyp leicht mit Rubin 2
Steuern Sie den Spring Batch-Verarbeitungsablauf mit JavaConfig.
Suchen Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java
Eine Geschichte voller Grundlagen von Spring Boot (gelöst)
Die Frühjahrsvalidierung war in der Reihenfolge von Form und BindingResult wichtig
Sehen Sie sich das Verhalten von Entitätsaktualisierungen mit Spring Boot + Spring Data JPA an
Koexistenz von Flyway in der eingebetteten Datenbank (h2) der Entwicklungsumgebung und der Release-Datenbank (SQL Server) mit Spring Boot