


Exemple d'analyse de code du code source d'implémentation inter-domaines Spring MVC Cors
Cet article présente principalement l'analyse du code source de l'implémentation inter-domaines Spring MVC cors. Il a une très bonne valeur de référence. Jetons-y un coup d'œil avec l'éditeur
Explication des termes : Cross-Origin Resource Sharing (Partage de ressources Cross-Origin)
Pour faire simple. , tant que le protocole IP, toute différence dans la méthode http est inter-domaine.
spring MVC a ajouté la prise en charge de plusieurs domaines depuis la version 4.2.
Pour la définition spécifique de cross-domain, veuillez vous rendre sur Mozilla pour voir
Cas d'utilisation
Il y en a 3 utilisations inter-domaines dans la méthode spring mvc :
Configurer CorsFilter dans web.xml
<filter> <filter-name>cors</filter-name> <filter-class>org.springframework.web.filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Configurer
// 简单配置,未配置的均使用默认值,就是全面放开 <mvc:cors> <mvc:mapping path="/**" /> </mvc:cors> // 这是一个全量配置 <mvc:cors> <mvc:mapping path="/api/**" allowed-origins="http://domain1.com, http://www.php.cn/" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" /> <mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" /> </mvc:cors>
en XML à l'aide d'annotations
@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin("http://domain2.com") @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } }
Concepts impliqués
Package spécifique à CorsConfiguration Le pojo des informations de configuration inter-domaines
Requête CorsConfigurationSource et le conteneur pour mapper les informations de configuration inter-domaines
Classe CorsProcessor qui effectue spécifiquement des opérations inter-domaines
Classe d'initialisation des informations de configuration inter-domaines Nogan
Adaptateur inter-domaines Nogan
Classes Java impliquées :
pojo qui encapsule les informations
CorsConfiguration
qui stocke demande et informations de configuration inter-domaines Conteneur
CorsConfigurationSource, UrlBasedCorsConfigurationSource
Classe de traitement spécifique
CorsProcessor, DefaultCorsProcessor
CorsUtils
implémenter l'adaptateur d'interface OncePerRequestFilter
CorsFilter
vérifier si la requête est cors et encapsuler le Adaptateur correspondant
AbstractHandlerMapping, y compris la classe interne PreFlightHandler, CorsInterceptor
Lire les informations d'annotation CrossOrigin
AbstractHandlerMethodMapping, RequestMappingHandlerMapping
à partir du fichier XML Lire les informations de configuration inter-domaines
CorsBeanDefinitionParser
Classe auxiliaire d'enregistrement inter-domaines
MvcNamespaceUtils
Analyse de débogage
Pour comprendre le code, nous devons d'abord comprendre le pojo qui encapsule les informations inter-domaines - CorsConfiguration
Il s'agit d'un pojo très simple, à l'exception de quelques correspondances entre domaines. Les attributs sont uniquement combine, checkOrigin, checkHttpMethod et checkHeaders.
Les attributs sont utilisés en combinaison avec plusieurs valeurs.
// CorsConfiguration public static final String ALL = "*"; // 允许的请求源 private List<String> allowedOrigins; // 允许的http方法 private List<String> allowedMethods; // 允许的请求头 private List<String> allowedHeaders; // 返回的响应头 private List<String> exposedHeaders; // 是否允许携带cookies private Boolean allowCredentials; // 预请求的存活有效期 private Long maxAge;
combiner consiste à fusionner des informations inter-domaines
Les trois méthodes de vérification consistent à vérifier si les informations contenues dans la demande sont incluses dans le cadre autorisé Dans le cadre
Initialisation de la configuration
analyse le fichier de configuration via CorsBeanDefinitionParser lorsque le système démarre
lorsque ; chargement de RequestMappingHandlerMapping, via InitializingBean Le hook afterProperties appelle initCorsConfiguration pour initialiser les informations d'annotation
Initialisation du fichier de configuration
Placer un point d'arrêt dans la méthode d'analyse ; de la classe CorsBeanDefinitionParser.
La pile d'appels de CorsBeanDefinitionParser
Vous pouvez voir l'analyse ici à travers le code
Inter-domaine La configuration des informations peut définir plusieurs relations de mappage en unités de chemins.
S'il n'y a pas de définition lors de l'analyse, les paramètres par défaut seront utilisés
// CorsBeanDefinitionParser if (mappings.isEmpty()) { // 最简配置时的默认设置 CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(DEFAULT_ALLOWED_ORIGINS); config.setAllowedMethods(DEFAULT_ALLOWED_METHODS); config.setAllowedHeaders(DEFAULT_ALLOWED_HEADERS); config.setAllowCredentials(DEFAULT_ALLOW_CREDENTIALS); config.setMaxAge(DEFAULT_MAX_AGE); corsConfigurations.put("/**", config); }else { // 单个mapping的处理 for (Element mapping : mappings) { CorsConfiguration config = new CorsConfiguration(); if (mapping.hasAttribute("allowed-origins")) { String[] allowedOrigins = StringUtils.tokenizeToStringArray(mapping.getAttribute("allowed-origins"), ","); config.setAllowedOrigins(Arrays.asList(allowedOrigins)); } // ... }
Une fois l'analyse terminée, enregistrez-vous via MvcNamespaceUtils. registerCorsConfiguratoions
Ce que nous suivons ici est le processus unifié de gestion des conteneurs de beans Spring, qui est maintenant converti en BeanDefinition puis instancié.
// MvcNamespaceUtils public static RuntimeBeanReference registerCorsConfigurations(Map<String, CorsConfiguration> corsConfigurations, ParserContext parserContext, Object source) { if (!parserContext.getRegistry().containsBeanDefinition(CORS_CONFIGURATION_BEAN_NAME)) { RootBeanDefinition corsConfigurationsDef = new RootBeanDefinition(LinkedHashMap.class); corsConfigurationsDef.setSource(source); corsConfigurationsDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); if (corsConfigurations != null) { corsConfigurationsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } parserContext.getReaderContext().getRegistry().registerBeanDefinition(CORS_CONFIGURATION_BEAN_NAME, corsConfigurationsDef); parserContext.registerComponent(new BeanComponentDefinition(corsConfigurationsDef, CORS_CONFIGURATION_BEAN_NAME)); } else if (corsConfigurations != null) { BeanDefinition corsConfigurationsDef = parserContext.getRegistry().getBeanDefinition(CORS_CONFIGURATION_BEAN_NAME); corsConfigurationsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME); }
Initialisation de l'annotation
Scanner la méthode annotée avec CrossOrigin dans la initCorsConfiguration de RequestMappingHandlerMapping et extraire les informations .
RequestMappingHandlerMapping_initCorsConfiguration
// RequestMappingHandlerMapping @Override protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) { HandlerMethod handlerMethod = createHandlerMethod(handler, method); CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getBeanType(), CrossOrigin.class); CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class); if (typeAnnotation == null && methodAnnotation == null) { return null; } CorsConfiguration config = new CorsConfiguration(); updateCorsConfig(config, typeAnnotation); updateCorsConfig(config, methodAnnotation); // ... 设置默认值 return config; }
Traitement des demandes d'origine croisée
Après avoir manipulé normalement le processeur de recherche, HandlerMapping vérifiera s'il s'agit d'une requête inter-domaine dans AbstractHandlerMapping.getHandler. S'il s'agit d'une requête inter-domaine, elle sera traitée de deux manières :
- .
S'il s'agit d'une pré-requête, remplacez le processeur par la classe interne PreFlightHandler
S'il s'agit d'une requête normale, ajoutez l'intercepteur CorsInterceptor
拿到处理器后,通过请求头是否包含Origin判断是否跨域,如果是跨域,通过UrlBasedCorsConfigurationSource获取跨域配置信息,并委托getCorsHandlerExecutionChain处理
UrlBasedCorsConfigurationSource是CorsConfigurationSource的实现,从类名就可以猜出这边request与CorsConfiguration的映射是基于url的。getCorsConfiguration中提取request中的url后,逐一验证配置是否匹配url。
// UrlBasedCorsConfigurationSource public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for(Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) { if (this.pathMatcher.match(entry.getKey(), lookupPath)) { return entry.getValue(); } } return null; } // AbstractHandlerMapping public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); // ... HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; } // HttpHeaders public static final String ORIGIN = "Origin"; // CorsUtils public static boolean isCorsRequest(HttpServletRequest request) { return (request.getHeader(HttpHeaders.ORIGIN) != null); }
通过请求头的http方法是否options判断是否预请求,如果是使用PreFlightRequest替换处理器;如果是普通请求,添加一个拦截器CorsInterceptor。
PreFlightRequest是CorsProcessor对于HttpRequestHandler的一个适配器。这样HandlerAdapter直接使用HttpRequestHandlerAdapter处理。
CorsInterceptor 是CorsProcessor对于HnalderInterceptorAdapter的适配器。
// AbstractHandlerMapping protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, CorsConfiguration config) { if (CorsUtils.isPreFlightRequest(request)) { HandlerInterceptor[] interceptors = chain.getInterceptors(); chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors); } else { chain.addInterceptor(new CorsInterceptor(config)); } return chain; } private class PreFlightHandler implements HttpRequestHandler { private final CorsConfiguration config; public PreFlightHandler(CorsConfiguration config) { this.config = config; } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { corsProcessor.processRequest(this.config, request, response); } } private class CorsInterceptor extends HandlerInterceptorAdapter { private final CorsConfiguration config; public CorsInterceptor(CorsConfiguration config) { this.config = config; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return corsProcessor.processRequest(this.config, request, response); } } // CorsUtils public static boolean isPreFlightRequest(HttpServletRequest request) { return (isCorsRequest(request) && request.getMethod().equals(HttpMethod.OPTIONS.name()) && request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

En 2023, la technologie de l’IA est devenue un sujet brûlant et a un impact énorme sur diverses industries, notamment dans le domaine de la programmation. Les gens sont de plus en plus conscients de l’importance de la technologie de l’IA, et la communauté Spring ne fait pas exception. Avec l’évolution continue de la technologie GenAI (Intelligence Artificielle Générale), il est devenu crucial et urgent de simplifier la création d’applications dotées de fonctions d’IA. Dans ce contexte, « SpringAI » a émergé, visant à simplifier le processus de développement d'applications fonctionnelles d'IA, en le rendant simple et intuitif et en évitant une complexité inutile. Grâce à « SpringAI », les développeurs peuvent plus facilement créer des applications dotées de fonctions d'IA, ce qui les rend plus faciles à utiliser et à exploiter.

En tant que leader du secteur, Spring+AI fournit des solutions de pointe pour divers secteurs grâce à son API puissante et flexible et ses fonctions avancées. Dans cette rubrique, nous examinerons les exemples d'application de Spring+AI dans divers domaines. Chaque cas montrera comment Spring+AI répond à des besoins spécifiques, atteint ses objectifs et étend ces LEÇONS APPRISES à une gamme plus large d'applications. J'espère que ce sujet pourra vous inciter à comprendre et à utiliser plus profondément les possibilités infinies de Spring+AI. Le framework Spring a une histoire de plus de 20 ans dans le domaine du développement logiciel, et cela fait 10 ans que la version Spring Boot 1.0 est sortie. Maintenant, personne ne peut contester ce printemps

Comment implémenter les transactions programmatiques Spring : 1. Utilisez TransactionTemplate ; 2. Utilisez TransactionCallback et TransactionCallbackWithoutResult ; 3. Utilisez les annotations Transactional ; 4. Utilisez TransactionTemplate en combinaison avec @Transactional ;

Introduction Dans le monde numérique en évolution rapide d'aujourd'hui, il est crucial de créer des applications WEB robustes, flexibles et maintenables. L'architecture PHPmvc fournit une solution idéale pour atteindre cet objectif. MVC (Model-View-Controller) est un modèle de conception largement utilisé qui sépare les différents aspects d'une application en composants indépendants. Les fondements de l'architecture MVC Le principe fondamental de l'architecture MVC est la séparation des préoccupations : Modèle : encapsule les données et la logique métier de l'application. Vue : responsable de la présentation des données et de la gestion des interactions des utilisateurs. Contrôleur : coordonne l'interaction entre les modèles et les vues, gère les demandes des utilisateurs et la logique métier. Architecture PHPMVC L'architecture phpMVC suit le modèle MVC traditionnel mais introduit également des fonctionnalités spécifiques au langage. Ce qui suit est PHPMVC

Comment définir le niveau d'isolement des transactions dans Spring : 1. Utilisez l'annotation @Transactional ; 2. Définissez-le dans le fichier de configuration Spring ; 3. Utilisez PlatformTransactionManager ; Introduction détaillée : 1. Utilisez l'annotation @Transactional, ajoutez l'annotation @Transactional à la classe ou à la méthode qui nécessite la gestion des transactions et définissez le niveau d'isolement dans l'attribut 2. Dans le fichier de configuration Spring, etc.

JUnit est un framework de tests unitaires Java largement utilisé dans les projets Spring et peut être appliqué en suivant les étapes suivantes : Ajouter une dépendance JUnit : org.junit.jupiterjunit-jupiter5.8.1test Écrire des cas de test : utilisez @ExtendWith(SpringExtension.class) pour activer l'extension, utilisez les beans d'injection @Autowired, utilisez @BeforeEach et @AfterEach pour préparer et nettoyer, et marquez les méthodes de test avec @Test.

Spring est un framework open source qui fournit de nombreuses annotations pour simplifier et améliorer le développement Java. Cet article expliquera en détail les annotations Spring couramment utilisées et fournira des exemples de code spécifiques. @Autowired : Autowired L'annotation @Autowired peut être utilisée pour câbler automatiquement les beans dans le conteneur Spring. Lorsque nous utilisons l'annotation @Autowired où les dépendances sont requises, Spring trouvera les beans correspondants dans le conteneur et les injectera automatiquement. L'exemple de code est le suivant : @Auto

Dans les systèmes de gestion back-end, le contrôle des autorisations d'accès est généralement requis pour limiter la capacité des différents utilisateurs à accéder aux interfaces. Si un utilisateur ne dispose pas d'autorisations spécifiques, il ne peut pas accéder à certaines interfaces. Cet article utilisera le projet waynboot-mall comme exemple pour présenter comment les systèmes de gestion back-end courants introduisent le cadre de contrôle des autorisations SpringSecurity. Le schéma est le suivant : Adresse du projet waynboot-mall : https://github.com/wayn111/waynboot-mall 1. Qu'est-ce que SpringSecurity SpringSecurity est un projet open source basé sur le framework Spring, visant à fournir une sécurité puissante et flexible ? pour les applications Java.
