Seulement deux, DeviceInfoController.java et pom.xml.
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── deviceinfo
└── DeviceInfoController.java
-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;
}
}
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'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"
}
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;
}
}
Le prochain article concerne une version plus ancienne, mais je soupçonne qu'elle n'a pas beaucoup changé.
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.
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);
}
Recommended Posts