2024-09-09

MyBatis 使用的数据库连接池可能会在某些情况下丢失与数据库的连接。为了确保连接池能够自动恢复,你可以配置连接池的自动恢复策略。

以下是一个使用 HikariCP 连接池的 MyBatis 配置示例,它配置了自动恢复策略:




<configuration>
    <!-- 其他配置... -->
 
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/yourdatabase"/>
                <property name="username" value="yourusername"/>
                <property name="password" value="yourpassword"/>
                
                <!-- 配置 HikariCP 的自动恢复策略 -->
                <property name="autoCommit" value="false"/>
                <property name="connectionTimeout" value="30000"/>
                <property name="idleTimeout" value="600000"/>
                <property name="maxLifetime" value="1800000"/>
                <property name="maximumPoolSize" value="10"/>
                <!-- 其他 HikariCP 属性配置 -->
            </dataSource>
        </environment>
    </environments>
</configuration>

在这个配置中,maxLifetime 属性定义了连接的最大生命周期,超过这个时间连接会被自动丢弃。idleTimeout 属性定义了连接在多长时间没有被使用后会被自动回收。connectionTimeout 属性设置了数据库连接的超时时间。

确保你的 MyBatis 版本与连接池(例如 HikariCP)兼容,并且根据你使用的数据库以及连接池的文档调整这些设置。

2024-09-09



import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.IpAddressMatcher;
 
import java.util.HashMap;
import java.util.Map;
 
@Configuration
public class IpAccessControlConfiguration {
 
    @Bean
    public IpAccessControlExtension ipAccessControlExtension() {
        return new IpAccessControlExtension();
    }
 
    @Configuration
    @Order(1)
    public static class IpAccessControlConfig extends WebSecurityConfigurerAdapter {
 
        private final IpAccessControlExtension ipAccessControlExtension;
 
        public IpAccessControlConfig(IpAccessControlExtension ipAccessControlExtension) {
            this.ipAccessControlExtension = ipAccessControlExtension;
        }
 
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // 应用IP访问控制规则
            http.authorizeRequests()
                    .anyRequest().access("@ipAccessControlExtension.hasIpAccess(request, authentication)");
        }
    }
 
    public static class IpAccessControlExtension {
        private Map<String, String> whiteList = new HashMap<>();
        private Map<String, String> blackList = new HashMap<>();
 
        public IpAccessControlExtension() {
            // 初始化白名单和黑名单
            whiteList.put("192.168.1.0/24", "白名单IP段");
            blackList.put("10.0.0.0/8", "黑名单IP段");
        }
 
        public boolean hasIpAccess(Object request, Object authentication) {
            String remoteAddr = ((javax.servlet.http.HttpServletRequest) request).getRemoteAddr();
            IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(whiteList.keySet());
            // 设置白名单规则
            ipAddressMatcher.setNegated(false);
2024-09-09



import org.springframework.stereotype.Service;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
 
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import com.openhtmltopdf.pdfboxout.support.Watermark;
 
import java.io.*;
 
@Service
public class PdfExportService {
 
    public Resource generatePdfWithWatermark(String htmlContent, String watermarkText) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            // 使用OpenPDF和Freemarker生成HTML内容
            String processedHtmlContent = processHtmlTemplate(htmlContent);
 
            // 使用OpenPDF将HTML转换为PDF
            PdfRendererBuilder builder = new PdfRendererBuilder();
            builder.useFastMode();
            builder.withWatermark(new Watermark(watermarkText, 45, Color.GRAY));
            builder.withHtmlContent(processedHtmlContent, "file:///")
                    .toStream(outputStream);
            builder.run();
 
            // 将PDF内容封装为Spring的Resource对象
            return new InputStreamResource(new ByteArrayInputStream(outputStream.toByteArray()));
        } catch (Exception e) {
            e.printStackTrace();
            // 异常处理逻辑
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 异常或正常结束时的返回值逻辑
        return null;
    }
 
    private String processHtmlTemplate(String htmlContent) {
        // 使用Freemarker处理HTML模板,生成最终的HTML字符串
        // 这里是模拟的Freemarker处理逻辑
        return htmlContent;
    }
}

这段代码展示了如何在Spring Boot应用中使用OpenPDF和Freemarker来生成带有水印的PDF文件。首先,它创建了一个ByteArrayOutputStream来暂存PDF文件内容。然后,它使用OpenPDF的PdfRendererBuilder来处理HTML内容,并为PDF文档添加水印。最后,它将生成的PDF内容封装为Spring的Resource对象,以便可以在控制器中返回并下载给客户端。

2024-09-09

以下是一些超牛的 Spring Cloud 实战项目,它们涵盖了微服务架构的方方面面,包括服务发现注册、配置中心、负载均衡、断路器、微服务安全等内容。

  1. Spring Cloud Samples

    这是一个由 Pivotal 团队维护的项目,提供了大量的 Spring Cloud 用例。

  2. Spring Cloud for Alibaba

    这是由 Alibaba 开源的 Spring Cloud 版本,提供了服务发现注册、配置中心等功能。

  3. Spring Cloud Netflix

    这是一个由 Netflix 开源的项目,提供了一系列的微服务工具,包括 Eureka、Hystrix、Zuul 等。

  4. Spring Cloud Kubernetes

    这是一个用于在 Kubernetes 上运行 Spring Boot 应用的项目,提供服务发现注册、配置中心等功能。

  5. Spring Cloud Security

    这是一个提供安全保护的 Spring Cloud 项目,提供了 OAuth2 客户端和服务端的实现。

  6. Spring Cloud Data Flow

    这是一个用于构建数据处理管道的工具,可以在 Spring Cloud 的基础上运行。

  7. Spring Cloud Zookeeper

    这是一个用于服务发现和配置管理的项目,结合了 Zookeeper 和 Spring Cloud 的功能。

每个项目都有详细的文档和实例代码,可以帮助开发者快速理解和应用这些技术。

2024-09-09

在Spring Boot项目中,Maven配置主要涉及以下几个方面:

  1. 设置项目打包方式为jar,因为Spring Boot建议你打包为可执行的jar文件。
  2. 添加Spring Boot的parent,用于管理Spring Boot的版本和依赖。
  3. 添加Spring Boot的starter依赖,它是一系列依赖的集合,简化了项目配置。
  4. 配置Maven插件,用于打包和运行Spring Boot应用。

以下是一个简单的Maven配置示例:




<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-project</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <!-- 设置打包方式为jar -->
    <packaging>jar</packaging>
 
    <!-- 继承Spring Boot的parent,管理版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version> <!-- 请使用最新的稳定版本 -->
        <relativePath/>
    </parent>
 
    <!-- 添加Spring Boot的starter web依赖 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
 
    <!-- 配置Maven插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

在这个配置中,我们指定了项目的打包方式为jar,继承了Spring Boot的parent项目,这样可以自动管理Spring Boot的版本。我们还添加了spring-boot-starter-web依赖,它是用于创建具有Spring MVC的Web应用程序的起步依赖。最后,我们配置了spring-boot-maven-plugin插件,以确保我们可以使用Maven打包和运行Spring Boot应用。

2024-09-09

Sentinel 是阿里巴巴开源的面向分布式服务架构的轻量级流量控制框架,主要以流量为切入点,提供多维度的流量控制、熔断降级、系统负载保护等功能。

以下是一个使用 Sentinel 的简单示例,演示如何在 Spring Cloud 应用中集成 Sentinel 来实现流量控制。

  1. 在 pom.xml 中添加 Sentinel 依赖:



<dependencies>
    <!-- Sentinel 核心库 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-core</artifactId>
        <version>1.8.0</version>
    </dependency>
    <!-- Sentinel API 模块 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-api-ds</artifactId>
        <version>1.8.0</version>
    </dependency>
</dependencies>
  1. 在代码中定义资源并配置规则:



import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
 
import java.util.ArrayList;
import java.util.List;
 
public class SentinelDemo {
 
    private static final String RESOURCE_KEY = "myResource";
 
    public static void main(String[] args) {
        initFlowRules();
 
        while (true) {
            //  entry 方法将会执行资源的访问.
            try (Entry entry = SphU.entry(RESOURCE_KEY)) {
                // 被保护的代码
                System.out.println("Hello Sentinel!");
            } catch (Exception e) {
                // 处理异常
                System.out.println("Sentinel limiting!");
            }
 
            // 每秒执行一次
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 
    private static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource(RESOURCE_KEY);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(20);
        rules.add(rule);
 
        FlowRuleManager.loadRules(rules);
    }
}

在这个例子中,我们定义了一个名为 "myResource" 的资源,并且初始化了一个流量控制规则,限制每秒钟的访问量不超过 20 次。在 while 循环中,我们持续地调用 SphU.entry() 方法访问这个资源,并且处理了可能发生的异常。如果访问频率超过规定的限制,Sentinel 会抛出异常,并执行异常块中的代码。

这只是 Sentinel 使用的简单示例,Sentinel 提供了更多高级特性,如系统保护、熔断降级等,需要结合实际业务场景进行使用和配置。

2024-09-09

在Spring Boot项目中集成MyBatis,首先需要在项目的pom.xml中添加MyBatis和数据库驱动的依赖。以下是一个简化的例子:




<dependencies>
    <!-- Spring Boot相关依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
    <!-- MyBatis依赖 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
 
    <!-- 数据库驱动,以MySQL为例 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version>
    </dependency>
 
    <!-- 其他必要的依赖 -->
</dependencies>

接下来,在application.propertiesapplication.yml中配置数据库连接信息和MyBatis的相关设置:




# 数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
# MyBatis 设置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.yourpackage.model

创建Mapper接口和Mapper XML文件。例如:




// UserMapper.java
package com.yourpackage.mapper;
 
public interface UserMapper {
    User selectUserById(int id);
}



<!-- UserMapper.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yourpackage.mapper.UserMapper">
    <select id="selectUserById" parameterType="int" resultType="com.yourpackage.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

在Spring Boot的主类或配置类中,通过@MapperScan注解指定Mapper接口的位置:




// YourApplication.java
package com.yourpackage;
 
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
@MapperScan("com.yourpackage.mapper")
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

最后,可以在Service层中注入Mapper并使用:




// UserService.java
package com.yourpackage.service;
 
import com.yourpackage.mapper.UserMapper;
import com.yourpackage.model.User;
import org.springframe
2024-09-09

在Spring Boot中整合XXL-JOB的步骤如下:

  1. 添加XXL-JOB的依赖到你的pom.xml文件中:



<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>你的版本号</version>
</dependency>
  1. application.propertiesapplication.yml中配置XXL-JOB:



# xxl-job admin address
xxl.job.admin.addresses=你的XXL-JOB-ADMIN地址
# xxl.job executor appname
xxl.job.executor.appname=你的执行器名称
# xxl.job executor ip
xxl.job.executor.ip=自动获取可以为空
# xxl.job executor port
xxl.job.executor.port=你的执行器端口
# xxl.job access token
xxl.job.accessToken=你的访问令牌
# xxl.job executor logpath
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
# xxl.job executor logretentiondays
xxl.job.executor.logretentiondays=30
  1. 创建一个JobHandler类实现com.xxl.job.core.handler.IJobHandler接口:



@Component
public class SampleXxlJob implements IJobHandler {
    @Override
    public ReturnT<String> execute(String param) throws Exception {
        // 你的任务逻辑
        XxlJobLogger.log("这是一个XXL-JOB的示例");
        return ReturnT.SUCCESS;
    }
}
  1. 配置执行器Bean:



@Configuration
public class XxlJobConfig {
 
    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;
 
    @Value("${xxl.job.executor.appname}")
    private String appName;
 
    @Value("${xxl.job.executor.ip}")
    private String ip;
 
    @Value("${xxl.job.executor.port}")
    private int port;
 
    @Value("${xxl.job.accessToken}")
    private String accessToken;
 
    @Bean
    public XxlJobExecutor xxlJobExecutor() {
        XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();
        // 设置admin地址
        xxlJobExecutor.setAdminAddresses(adminAddresses);
        // 设置执行器相关信息
        xxlJobExecutor.setAppName(appName);
        xxlJobExecutor.setIp(ip);
        xxlJobExecutor.setPort(port);
        xxlJobExecutor.setAccessToken(accessToken);
        return xxlJobExecutor;
    }
}
  1. 在Spring Boot启动类上添加@EnableXxlJob注解启用XXL-JOB:



@SpringBootApplication
@EnableXxlJob
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}
  1. 在XXL-JOB的管理界面配置你的任务,指定执行器,并且设置相应的JobHandler类名称。

以上步骤完成后,你的Spring Boot应用就可以通过XXL-JOB执行定时任务了。

2024-09-09

解决Tomcat日志中文乱码的问题,主要是设置Tomcat的字符编码。以下是步骤和示例配置:

  1. 找到Tomcat的配置文件logging.properties,这个文件通常位于$CATALINA_HOME/lib目录下。
  2. 打开logging.properties文件,找到以下行:

    
    
    
    java.util.logging.ConsoleHandler.encoding = UTF-8

    确保这一行存在并且设置为UTF-8

  3. 如果你使用的是Windows系统,可能需要将UTF-8改为GBK或者你希望的任何支持中文的编码格式。
  4. 保存logging.properties文件,重启Tomcat服务。

如果上述步骤不适用,可能需要在Tomcat启动脚本中设置JVM的字符编码参数。编辑catalina.sh(Linux)或catalina.bat(Windows),在CATALINA_OPTSJAVA_OPTS环境变量中添加:

对于Linux系统:




CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8"

对于Windows系统:




set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8

重新启动Tomcat服务后,日志乱码问题应该得到解决。如果仍然存在问题,请检查操作系统的区域设置是否支持中文,以及是否有其他中间件或应用程序可能影响字符编码的设置。

2024-09-09

在Tomcat中设置项目的根路径,通常是通过修改server.xml文件来实现的。以下是一个简化的步骤说明和示例代码:

  1. 打开Tomcat的安装目录下的conf文件夹,找到server.xml文件。
  2. 找到<Host>元素,在其中添加或修改<Context>元素,指定path属性为空字符串(""),并设置docBase属性为你的项目文件夹路径。

示例代码:




<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
    <!-- 其他配置 ... -->
 
    <Context path="" docBase="/path/to/your/application" />
</Host>

在这个例子中,path属性被设置为空字符串,表示这个Context是根ContextdocBase属性设置为你的项目文件夹的绝对路径。

对于Tomcat 8及以上版本,可以在conf/Catalina/localhost目录下创建一个以ROOT.xml命名的文件,其中包含类似的配置:




<Context docBase="/path/to/your/application" />

这样做的好处是不需要直接修改server.xml文件,而且更加符合Tomcat的模块化管理方式。

注意:修改配置后需要重启Tomcat服务器使更改生效。