[JAVA] Utilisez Spring Mobile pour déterminer le type d'appareil des smartphones, tablettes et ordinateurs personnels

Aperçu

Code source

Liste des codes sources

Seulement deux, DeviceInfoController.java et pom.xml.

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

Fichier de construction Maven pom.xml

-Introduction de Spring Mobile dans les dépendances

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>

    <!--Lancement de Spring Mobile-->
    <dependency>
      <groupId>org.springframework.mobile</groupId>
      <artifactId>spring-mobile-device</artifactId>
      <version>2.0.0.M3</version>
    </dependency>
  </dependencies>

  <repositories>
    <!--Dépôt ajouté avec la version jalon de Spring Mobile-->
    <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);
  }

  //Requis pour utiliser Spring Mobile
  @Bean
  public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
    return new DeviceResolverHandlerInterceptor();
  }

  //Requis pour utiliser Spring Mobile
  // 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;
  }
}

Construire et lancer

Générez un fichier JAR avec le package mvn.

$ mvn package

Démarrez Spring Boot avec la commande java.

$ java -jar target/deviceinfo-0.0.1.jar

Essayez d'accéder avec divers agents utilisateurs

Essayez d'y accéder en spécifiant divers agents utilisateurs avec Ruby + curl.

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

Résultat de l'exécution. Vous pouvez voir que l'agent utilisateur est analysé et peut être déterminé fermement.

{
  "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"
}

Autoriser le périphérique à être spécifié comme argument de la méthode du gestionnaire

Modifiez DeviceInfoController.java afin que Device puisse être spécifié comme argument de la méthode du gestionnaire (méthode avec l'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);
  }

  //Requis pour utiliser Spring Mobile
  @Bean
  public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
    return new DeviceResolverHandlerInterceptor();
  }

  //Requis pour utiliser Spring Mobile
  // WebMvcConfigurer#addInterceptors
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(deviceResolverHandlerInterceptor());
  }

  // @Méthode avec RequestMapping(Méthode du gestionnaire)À l'argument de
  //Requis pour pouvoir spécifier l'appareil de Spring Mobile
  @Bean
  public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() {
    return new DeviceHandlerMethodArgumentResolver();
  }

  // @Méthode avec RequestMapping(Méthode du gestionnaire)À l'argument de
  //Requis pour pouvoir spécifier l'appareil de Spring Mobile
  // 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);

    //Ce processus n'est pas nécessaire car Device peut être spécifié comme argument de la méthode du gestionnaire.
    //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;
  }
}

Comment Spring Mobile identifie les appareils

Le prochain article concerne une version plus ancienne, mais je soupçonne qu'elle n'a pas beaucoup changé.

Spring Mobile 1 \ .0 publié

LiteDeviceResolver est utilisé par défaut pour la résolution de l'appareil. Il est basé sur l'algorithme de détection de WordPress Mobile Pack. Vous pouvez connecter une autre implémentation DeviceResolver en injectant l'argument constructeur de DeviceResolverHandlerInterceptor. Les résolveurs d'appareils plus sophistiqués tels que WURFL peuvent identifier des fonctionnalités spécifiques de l'appareil telles que la taille de l'écran, le fabricant, le modèle ou le balisage de priorité.

Si vous regardez le code source de LiteDeviceResolver.java, vous pouvez voir comment le périphérique est identifié à partir de la chaîne de l'agent utilisateur.

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);
}

Pour utiliser Spring Mobile, vous devez implémenter WebMvcConfigurer # addInterceptors et ajouter l'objet DeviceResolverHandlerInterceptor à l'objet InterceptorRegistry dans sa méthode.

Cela est dû au fait que l'objet DeviceResolverHandlerInterceptor crée un objet Device et l'ajoute en tant qu'attribut dans HttpServletRequest # setAttribute avant le traitement dans la méthode du gestionnaire.

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 ne renvoie que les attributs définis.

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

Matériel de référence

Recommended Posts

Utilisez Spring Mobile pour déterminer le type d'appareil des smartphones, tablettes et ordinateurs personnels
Ressentez facilement le type de base et le type de référence avec ruby
[Pour les débutants] DI ~ Les bases de DI et DI au printemps ~
Compatibilité de Spring JDBC et My Batis avec Spring Data JDBC (provisoire)
Accédez au h2db intégré de Spring Boot avec jdbcTemplate
Jusqu'à l'utilisation de Spring Data et JPA Part 2
Jusqu'à l'utilisation de Spring Data et JPA Part 1
Ressentez facilement le type de base et le type de référence avec ruby 2
Contrôlez le flux de traitement Spring Batch avec JavaConfig.
Trouvez la classe d'adresse et le type d'adresse à partir de l'adresse IP avec Java
Une histoire remplie des bases de Spring Boot (résolu)
La validation de printemps était importante dans l'ordre de Form et BindingResult
Voir le comportement des mises à jour d'entités avec Spring Boot + Spring Data JPA
Coexistence de Flyway dans la base de données embarquée (h2) de l'environnement de développement et la base de données des versions (SQL Server) avec Spring Boot