diff --git a/READ.md b/READ.md
index 83ac6dd8f5557e8ef004186e788f8959ea0b3f5a..05b296f163b07026dab7ca1d7bb63f00ac56d6b7 100644
--- a/READ.md
+++ b/READ.md
@@ -27,6 +27,12 @@
- web模块
- 发邮件
+
+- 数据校验规则
+
+- 乱码问题 WebMvcConfigurationSupport
+
+- 批处理
## 三.链接
diff --git a/pom.xml b/pom.xml
index 508ff1fd118fcb0a2ee8ed929e62f2ca612a49e4..f9293f909a97dc7d95dbbddddc99e0679db65bde 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,6 +15,9 @@
Demo project for Spring Boot
1.8
+
+ UTF-8
+ UTF-8
@@ -113,6 +116,14 @@
org.springframework.boot
spring-boot-starter-mail
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-batch
+
diff --git a/src/main/java/com/kwan/springbootkwan/SpringBootKwanApplication.java b/src/main/java/com/kwan/springbootkwan/SpringBootKwanApplication.java
index d2a159195f0db6977ccd1f1096c7df8deea5707e..cc603b3be2e283bcabbbb228cb0a7494e9207a3d 100644
--- a/src/main/java/com/kwan/springbootkwan/SpringBootKwanApplication.java
+++ b/src/main/java/com/kwan/springbootkwan/SpringBootKwanApplication.java
@@ -1,4 +1,5 @@
package com.kwan.springbootkwan;
+import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -6,6 +7,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication
+@EnableBatchProcessing
public class SpringBootKwanApplication {
public static void main(String[] args) {
diff --git a/src/main/java/com/kwan/springbootkwan/config/CsvBatchJobConfig.java b/src/main/java/com/kwan/springbootkwan/config/CsvBatchJobConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..96a55253a468c580264c37dc9cc187adf48a1eca
--- /dev/null
+++ b/src/main/java/com/kwan/springbootkwan/config/CsvBatchJobConfig.java
@@ -0,0 +1,83 @@
+package com.kwan.springbootkwan.config;
+
+import com.kwan.springbootkwan.entity.Person;
+import org.springframework.batch.core.Job;
+import org.springframework.batch.core.Step;
+import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
+import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
+import org.springframework.batch.core.configuration.annotation.StepScope;
+import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
+import org.springframework.batch.item.database.JdbcBatchItemWriter;
+import org.springframework.batch.item.file.FlatFileItemReader;
+import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
+import org.springframework.batch.item.file.mapping.DefaultLineMapper;
+import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class CsvBatchJobConfig {
+
+
+ @Autowired
+ JobBuilderFactory jobBuilderFactory;
+ @Autowired
+ StepBuilderFactory stepBuilderFactory;
+ @Autowired
+ DataSource dataSource;
+
+
+ @Bean
+ @StepScope
+ FlatFileItemReader itemReader() {
+ FlatFileItemReader reader = new FlatFileItemReader<>();
+ reader.setLinesToSkip(1);
+ reader.setResource(new ClassPathResource("data.csv"));
+ reader.setLineMapper(new DefaultLineMapper() {{
+ setLineTokenizer(new DelimitedLineTokenizer() {
+ {
+ setNames("id", "username", "address", "gender");
+ //配置列与列之间的间隔符(将通过间隔符对每一行的数据进行切分),最后设置要映射的实体类属性即可
+ setDelimiter(",");
+ }
+ });
+ setFieldSetMapper(new BeanWrapperFieldSetMapper() {
+ {
+ setTargetType(Person.class);
+ }
+ });
+
+ }});
+ return reader;
+ }
+
+ @Bean
+ public JdbcBatchItemWriter jdbcBatchItemWriter() {
+ JdbcBatchItemWriter writer = new JdbcBatchItemWriter();
+ writer.setDataSource(dataSource);
+ writer.setSql("insert into person(id, username,address,gender)" + "values (:id, :username, :address, :gender)");
+ writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
+ return writer;
+ }
+
+ @Bean
+ Step csvStep() {
+ return stepBuilderFactory.get("csvStep")
+ .chunk(2)
+ .reader(itemReader())
+ .writer(jdbcBatchItemWriter())
+ .build();
+ }
+
+ @Bean
+ Job csvJob() {
+ return jobBuilderFactory.get("csvJob")
+ .start(csvStep())
+ .build();
+
+ }
+}
diff --git a/src/main/java/com/kwan/springbootkwan/config/MyWebMvcConfig.java b/src/main/java/com/kwan/springbootkwan/config/MyWebMvcConfig.java
index fcab5b2570b6643d56855d58dba528dec6860d1f..42bc12caf43f79490a552242974dc271054bee20 100644
--- a/src/main/java/com/kwan/springbootkwan/config/MyWebMvcConfig.java
+++ b/src/main/java/com/kwan/springbootkwan/config/MyWebMvcConfig.java
@@ -1,10 +1,23 @@
package com.kwan.springbootkwan.config;
+import org.springframework.boot.validation.MessageInterpolatorFactory;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.validation.MessageCodesResolver;
+import org.springframework.validation.Validator;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.config.annotation.*;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
/**
* 全局webconfig-跨域配置
@@ -14,7 +27,49 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* @date : 2022/12/19 16:11
*/
@Configuration
-public class MyWebMvcConfig implements WebMvcConfigurer {
+public class MyWebMvcConfig extends WebMvcConfigurationSupport implements WebMvcConfigurer {
+
+ @Override
+ public void extendMessageConverters(List> converters) {
+ // 解决controller返回字符串中文乱码问题
+ for (HttpMessageConverter> converter : converters) {
+ if (converter instanceof StringHttpMessageConverter) {
+ ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
+ } else if (converter instanceof MappingJackson2HttpMessageConverter) {
+ ((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
+ }
+ }
+ }
+
+ @Override
+ public void configureHandlerExceptionResolvers(List resolvers) {
+ WebMvcConfigurer.super.configureHandlerExceptionResolvers(resolvers);
+ }
+
+ @Override
+ public void extendHandlerExceptionResolvers(List resolvers) {
+ WebMvcConfigurer.super.extendHandlerExceptionResolvers(resolvers);
+ }
+
+ @Override
+ public Validator getValidator() {
+ ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
+ messageSource.setDefaultEncoding("utf-8");// 读取配置文件的编码格式
+ messageSource.setCacheMillis(-1);// 缓存时间,-1表示不过期
+ messageSource.setBasename("ValidationMessages");// 配置文件前缀名,设置为Messages,那你的配置文件必须以Messages.properties/Message_en.properties...
+
+ LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
+ MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();
+ factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
+ factoryBean.setValidationMessageSource(messageSource);
+ return factoryBean;
+ }
+
+ @Override
+ public MessageCodesResolver getMessageCodesResolver() {
+ return WebMvcConfigurer.super.getMessageCodesResolver();
+ }
+
/**
* 配置静态资源
*
@@ -26,6 +81,31 @@ public class MyWebMvcConfig implements WebMvcConfigurer {
.addResourceLocations("classpath:/static/");
}
+ @Override
+ public void configurePathMatch(PathMatchConfigurer configurer) {
+ WebMvcConfigurer.super.configurePathMatch(configurer);
+ }
+
+ @Override
+ public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
+ WebMvcConfigurer.super.configureContentNegotiation(configurer);
+ }
+
+ @Override
+ public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
+ WebMvcConfigurer.super.configureAsyncSupport(configurer);
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ WebMvcConfigurer.super.configureDefaultServletHandling(configurer);
+ }
+
+ @Override
+ public void addFormatters(FormatterRegistry registry) {
+ WebMvcConfigurer.super.addFormatters(registry);
+ }
+
/**
* 配置拦截器
*
@@ -51,4 +131,29 @@ public class MyWebMvcConfig implements WebMvcConfigurer {
.maxAge(1800)
.allowedOrigins("http://localhost:8081");
}
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ WebMvcConfigurer.super.addViewControllers(registry);
+ }
+
+ @Override
+ public void configureViewResolvers(ViewResolverRegistry registry) {
+ WebMvcConfigurer.super.configureViewResolvers(registry);
+ }
+
+ @Override
+ public void addArgumentResolvers(List resolvers) {
+ WebMvcConfigurer.super.addArgumentResolvers(resolvers);
+ }
+
+ @Override
+ public void addReturnValueHandlers(List handlers) {
+ WebMvcConfigurer.super.addReturnValueHandlers(handlers);
+ }
+
+ @Override
+ public void configureMessageConverters(List> converters) {
+ WebMvcConfigurer.super.configureMessageConverters(converters);
+ }
}
diff --git a/src/main/java/com/kwan/springbootkwan/controller/PersonController.java b/src/main/java/com/kwan/springbootkwan/controller/PersonController.java
index 92ee4b74c96f04637c709c85e55a8a3202831832..47a38c3135a0d53a6be8b9f458f59a04284534c9 100644
--- a/src/main/java/com/kwan/springbootkwan/controller/PersonController.java
+++ b/src/main/java/com/kwan/springbootkwan/controller/PersonController.java
@@ -5,6 +5,9 @@ import com.kwan.springbootkwan.entity.User;
import com.kwan.springbootkwan.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import org.springframework.batch.core.Job;
+import org.springframework.batch.core.JobParameters;
+import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -22,6 +25,12 @@ import java.util.List;
@RestController
@RequestMapping("/person")
public class PersonController {
+
+ @Autowired
+ private JobLauncher jobLauncher;
+ @Autowired
+ private Job job;
+
/**
* {
* "name": "zhang san",
@@ -33,9 +42,18 @@ public class PersonController {
@GetMapping("/person")
public Person person() {
Person person = new Person();
- person.setName("zhang san");
- person.setAge(24);
- person.setBirthday(new Date());
+ person.setUsername("zhang san");
+ person.setId(24);
+ person.setAddress("湖北");
return person;
}
+
+ @GetMapping("/hello")
+ public void hello() {
+ try {
+ jobLauncher.run(job, new JobParameters());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/kwan/springbootkwan/controller/UserController.java b/src/main/java/com/kwan/springbootkwan/controller/UserController.java
index 65e944e1a74693b027a6415be563d16aff6d0c0d..158bb87917bf23b2871818a1b4e4624a35c2d00d 100644
--- a/src/main/java/com/kwan/springbootkwan/controller/UserController.java
+++ b/src/main/java/com/kwan/springbootkwan/controller/UserController.java
@@ -1,13 +1,21 @@
package com.kwan.springbootkwan.controller;
+import com.kwan.springbootkwan.entity.Student;
import com.kwan.springbootkwan.entity.User;
import com.kwan.springbootkwan.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpRequest;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.ObjectError;
+import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -38,4 +46,18 @@ public class UserController {
public User getUserById(@PathVariable Integer id) {
return userService.getUserById(id);
}
+
+
+ @PostMapping(value = "/student",produces = "application/json;charset=utf-8")
+ public List addUser(@RequestBody @Validated Student student, BindingResult result ) throws UnsupportedEncodingException {
+ List errors = new ArrayList<>();
+ if (result.hasErrors()) {
+ List allErrors = result.getAllErrors();
+ for (ObjectError error : allErrors) {
+ errors.add(error.getDefaultMessage());
+ }
+ }
+ log.info("errors={}", errors);
+ return errors;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/kwan/springbootkwan/entity/MailInfo.java b/src/main/java/com/kwan/springbootkwan/entity/MailInfo.java
index c9d88628a51b9ff9ee1e84cf176f55c283eda51e..ec6b71d9a4c6793cab0db732eb4aefa14e59c141 100644
--- a/src/main/java/com/kwan/springbootkwan/entity/MailInfo.java
+++ b/src/main/java/com/kwan/springbootkwan/entity/MailInfo.java
@@ -1,5 +1,6 @@
package com.kwan.springbootkwan.entity;
+import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
@@ -13,16 +14,16 @@ import java.util.Map;
*/
@Data
public class MailInfo {
- // 邮件接收人
+ @ApiModelProperty(value = "邮件接收人")
private String[] receiver;
- // 邮件主题
+ @ApiModelProperty(value = "邮件主题")
private String subject;
- // 邮件的文本内容
+ @ApiModelProperty(value = "邮件的文本内容")
private String content;
- // 抄送人
+ @ApiModelProperty(value = "抄送人")
private String[] cc;
- // 邮件附件的文件名
+ @ApiModelProperty(value = "邮件附件的文件名")
private String[] attachFileNames;
- // 邮件内容内嵌图片
+ @ApiModelProperty(value = "邮件内容内嵌图片")
private Map imageMap;
}
diff --git a/src/main/java/com/kwan/springbootkwan/entity/Person.java b/src/main/java/com/kwan/springbootkwan/entity/Person.java
index a609748fff6ba33bf73a3eec7522bafd7a895826..93db08fe81f79b3a21d3225974acc6b53acedc23 100644
--- a/src/main/java/com/kwan/springbootkwan/entity/Person.java
+++ b/src/main/java/com/kwan/springbootkwan/entity/Person.java
@@ -1,42 +1,20 @@
package com.kwan.springbootkwan.entity;
-import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
-import java.util.Date;
-
+@Data
+@TableName(value = "person")
@ApiModel(value = "用户基本信息")
public class Person {
- @ApiModelProperty(value = "姓名")
- private String name;
- @ApiModelProperty(value = "年龄")
- private Integer age;
- @ApiModelProperty(value = "生日")
- @JsonFormat(pattern = "yyyy-MM-dd")
- private Date birthday;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public Date getBirthday() {
- return birthday;
- }
-
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
-}
+ @ApiModelProperty(value = "主键")
+ private Integer id;
+ @ApiModelProperty(value = "名称")
+ private String username;
+ @ApiModelProperty(value = "地址")
+ private String address;
+ @ApiModelProperty(value = "性别")
+ private String gender;
+}
\ No newline at end of file
diff --git a/src/main/java/com/kwan/springbootkwan/entity/Student.java b/src/main/java/com/kwan/springbootkwan/entity/Student.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec4408ea7b304db0d0c3f25255e50b06578831b1
--- /dev/null
+++ b/src/main/java/com/kwan/springbootkwan/entity/Student.java
@@ -0,0 +1,37 @@
+package com.kwan.springbootkwan.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.*;
+
+/**
+ * 数据校验
+ *
+ * @author : qinyingjie
+ * @version : 2.2.0
+ * @Size 示一个字符串的长度或者一个集合的大小,必须在某一个范围中; min 参数表示范围的下限; max参数表示范围的上限; message 表示校验失败时的提示信息。
+ * @NotNull 注解表示该字段不能为空。
+ * @DecimalMin 注解表示对应属性值的下限,@DecimalMax 注解表示对应属性值的上限
+ * @Email 注解表示对应属性格式是一个 Email
+ * @date : 2022/12/20 09:00
+ */
+@Data
+public class Student {
+ @ApiModelProperty(value = "主键")
+ private Integer id;
+ @ApiModelProperty(value = "姓名")
+ @Size(min = 5, max = 10, message = "{user.name.size}")
+ private String name;
+ @ApiModelProperty(value = "地址")
+ @NotNull(message = "{user.address.notnull}")
+ private String address;
+ @ApiModelProperty(value = "年龄")
+ @DecimalMin(value = "1", message = "{user.age.size}")
+ @DecimalMax(value = "200", message = "{user.age.size}")
+ private Integer age;
+ @ApiModelProperty(value = "邮箱")
+ @Email(message = "{user.email.pattern}")
+ @NotNull(message = "{user.email.notnull}")
+ private String email;
+}
diff --git a/src/main/resources/ValidationMessages.properties b/src/main/resources/ValidationMessages.properties
new file mode 100644
index 0000000000000000000000000000000000000000..268e77715499f4e75a9de13f445b507a56c61b0d
--- /dev/null
+++ b/src/main/resources/ValidationMessages.properties
@@ -0,0 +1,5 @@
+user.name.size=用户名的长度在5到10个字符之间
+user.address.notnull=用户地址不能为空
+user.age.size=年龄输入不正确
+user.email.notnull=邮箱不能为空
+user.email.pattern=不正确的电子邮件格式
\ No newline at end of file
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 84243657fc5b90d1742fc6c11660ec68fa16712c..1de9fb41ed1564582e3a5cec15342da1b8bcc57a 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -1,11 +1,24 @@
server:
port: 8761
+ servlet:
+ encoding:
+ force: true
+ charset: UTF-8
+ enabled: true
swagger:
enable: true
#兼容swagger配置
spring:
+ #项目启动时创建数据表的 SQL 脚本,该脚本由 Spring Batch 提供
+ #spring.datasource.schema=classpath:/org/springframework/batch/core/schema-mysql.sql
+ # 在项目启动时执行建表 SQL
+ batch:
+ initialize-schema: always
+ # 禁止 Spring Batch 自动执行,在 SpringBoot 中,默认情况,当项目启动时就会执行配置好的批理操作,添加了该配置后则不会自动执行,而需要用户手动触发执行
+ job:
+ enabled: false
mail:
host: smtp.qq.com
# 发送者的邮箱账号
diff --git a/src/main/resources/data.csv b/src/main/resources/data.csv
new file mode 100644
index 0000000000000000000000000000000000000000..7323856112b15ffed6b1b19bbc30352f489a4aa0
--- /dev/null
+++ b/src/main/resources/data.csv
@@ -0,0 +1,5 @@
+id,username,address,gender
+1,张三,成都,男
+2,李四,深圳,女
+3,张三,成都,男
+4,李四,深圳,女
\ No newline at end of file