springboot-同名class注入

by kevin 21. 二月 2024 14:30 >
springboot注入默认使用className作为注入的key,如果两个className一样,无法注入   添加配置CoreConfiguration package com.statcore; import com.xmeport.statcore.util.AnnotationBeanNameGenerator; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(nameGenerator = AnnotationBeanNameGenerator.class) @MapperScan(value = "com.xmeport.statcore.mapper" ,nameGenerator = AnnotationBeanNameGenerator.class) public class CoreConfiguration { }   创建AnnotationBeanNameGenerator类 package com.statcore.util; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.StringUtils; import java.util.Map; import java.util.Set; public class AnnotationBeanNameGenerator implements BeanNameGenerator {     private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";     @Override     public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {         if (definition instanceof AnnotatedBeanDefinition) {             String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);             if (StringUtils.hasText(beanName)) {                 // Explicit bean name found.                 return beanName;             }         }         return definition.getBeanClassName();     }     /**      * Derive a bean name from one of the annotations on the class.      *      * @param annotatedDef the annotation-aware bean definition      * @return the bean name, or {@code null} if none is found      */     protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {         AnnotationMetadata amd = annotatedDef.getMetadata();         Set<String> types = amd.getAnnotationTypes();         String beanName = null;         for (String type : types) {             AnnotationAttributes attributes = AnnotationAttributes.fromMap(amd.getAnnotationAttributes(type, false));             if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {                 Object value = attributes.get("value");                 if (value instanceof String) {                     String strVal = (String) value;                     if (StringUtils.hasLength(strVal)) {                         if (beanName != null && !strVal.equals(beanName)) {                             throw new IllegalStateException("Stereotype annotations suggest inconsistent " +                                     "component names: '" + beanName + "' versus '" + strVal + "'");                         }                         beanName = strVal;                     }                 }             }         }         return beanName;     }     /**      * Check whether the given annotation is a stereotype that is allowed      * to suggest a component name through its annotation {@code value()}.      *      * @param annotationType      the name of the annotation class to check      * @param metaAnnotationTypes the names of meta-annotations on the given annotation      * @param attributes          the map of attributes for the given annotation      * @return whether the annotation qualifies as a stereotype with component name      */     protected boolean isStereotypeWithNameValue(String annotationType,                                                 Set<String> metaAnnotationTypes, Map<String, Object> attributes) {         boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||                 (metaAnnotationTypes != null && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME)) ||                 annotationType.equals("javax.annotation.ManagedBean") ||                 annotationType.equals("javax.inject.Named");         return (isStereotype && attributes != null && attributes.containsKey("value"));     } }

springboot移除url中的sessionid

by kevin 21. 二月 2024 14:26 >
1. 配置文件中添加 [sourcecode language='xml' padlinenumbers='true'] server.servlet.session.tracking-modes=COOKIE [/sourcecode] 2. 对每个请求的url判断,重新改写。 package com.ac; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class SessionUrlInterceptor extends HandlerInterceptorAdapter {     @Value("${sessionUrlEnable}")     private boolean sessionUrlEnable;     @Override     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException {         if (sessionUrlEnable && StringUtils.isNotBlank(request.getSession().getId())) {             String requestURI = request.getRequestURI();             String uriSession = ";jsessionid=" + request.getSession().getId();             LogUtils.logInfo("requestURI:" + requestURI + " sessionURI:" + uriSession);             if (requestURI.indexOf(uriSession) != -1) { //                LogUtils.logInfo("requestURI:" + requestURI + " Forward");                                requestURI = requestURI.replace(uriSession, "");                                request.getRequestDispatcher(requestURI).forward(request, response);                 return false;             }         }         return true;     } }

开发杂技 2021-03-23

by kevin 23. 三月 2021 19:23 >
1.java jdk1.8的版本问题 莫名奇妙的报了一个编译错误:对于collect(java.util.stream.Collector<java.lang.Object,capture#1, 共 ?,java.util.List<java.lang.Object>>), 找不到合适的方法 看了一下报错的代码,理论上这里不会错。查了一下,可能是jdk版本低引起的。 把jdk版本从jdk-8u20升级到jdk-8u181,这个问题就解决了。 2.thymeleaf小技巧 2.1 th:disabled等属性 要在页面上输出disabled=”disabled” 或者 readonly=”readonly”,设置th:disabled=true或者th:readonly=true就可以了。 类似的属性checked等也是这样设置。 2.2 th:block 如果需要在页面上输出一端文字,而不使用html标签,可以使用th:block,然后设置th:text=”value”。 如果需要在页面上占据一个位置,而不使用div或者其他标签,可以使用th:block,然后设置th:replace。 处理文字连接,可以使用th:text=”${a}+’b””或者th:text=|${a}b|两种语法 ,如果a值为空,则会输出nullb,处理这种情况,就可以使用th:block,<th:block th:text=”${a}”></th:block>b。

Thymeleaf:自定义布局

by kevin 3. 三月 2021 14:01 >
1.简介 页面需要共享常见的页面组件,例如页眉,页脚,菜单等。Thymeleaf使用自定义方言解决了这一问题,如创建布局,自定义标题或head元素合并。 2. Maven依赖 首先,看一下将Thymeleaf与Spring集成所需的必需配置。thymeleaf库需要依赖: <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.11.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.11.RELEASE</version> </dependency> 请注意,对于Spring 4项目, 必须使用thymeleaf-spring4库而不是thymeleaf-spring5。 还需要自定义布局方言的依赖项: <dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> <version>2.4.1</version> </dependency> springboot项目,添加以下依赖就可以启动。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>   3.命名空间和属性处理器的功能 配置完成后,就可以开始使用布局名称空间和五个新的属性处理器:decorate,title-pattern,insert,replace和fragment。 为了创建要用于HTML文件的布局模板,创建了以下文件,命名为template.html: <!DOCTYPE html> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> ... </html> 将名称空间从标准xmlns:th =“ http://www.thymeleaf.org”更改为xmlns:layout =“ http://www.ultraq.net.nz/thymeleaf/layout”。 在HTML文件中使用属性处理器。 3.1。布局:片段 为了在布局或可重复使用的模板中创建可被共享相同名称的部分替换的自定义部分,在template.html正文中使用fragment属性: <body> <header> <h1>New dialect example</h1> </header> <section layout:fragment="custom-content"> <p>Your page content goes here</p> </section> <footer> <p>My custom footer</p> <p layout:fragment="custom-footer">Your custom footer here</p> </footer> </body> 请注意,有两个部分将被自定义HTML取代-内容和页脚。 如果找不到任何片段,编写将要使用的默认HTML也很重要。 3.2。布局:装饰 需要做的下一步是创建一个HTML文件,该文件将通过布局进行装饰: <!DOCTYPE html> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{template.html}"> <head> <title>Layout Dialect Example</title> </head> <body> <section layout:fragment="custom-content"> <p>This is a custom content that you can provide</p> </section> <footer> <p layout:fragment="custom-footer">This is some footer content that you can change</p> </footer> </body> </html> 如第三行所示,使用layout:decorate并指定装饰器源。布局文件中与内容文件中的片段匹配的所有片段将被其自定义实现替换。 3.3。布局:标题模式 鉴于布局方言会自动使用内容模板中的布局标题覆盖布局标题,可以保留在布局中找到的部分标题。 例如,可以创建面包屑或在页面标题中保留网站名称。在这种情况下,layout:title-pattern处理器会提供帮助。需要在布局文件中指定的所有内容是: <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Baeldung</title> 因此,上一段中呈现的布局和内容文件的最终结果将如下所示: <title>Baeldung - Layout Dialect Example</title> 3.4。布局:插入/布局:替换 第一个处理器layout:insert类似于Thymeleaf的原始th:insert,但是允许将整个HTML片段传递给插入的模板。如果有一些要重用的HTML,但其内容过于复杂而无法单独使用上下文变量来确定或构造,则此功能非常有用。 第二个布局是layout:replace,与第一个类似,但是具有th:replace的行为,该行为实际上将使用定义的片段代码替换host标签。