提交 4524f2df 编写于 作者: Q qinyingjie

fix:批处理

上级 f2a56f4c
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
- web模块 - web模块
- 发邮件 - 发邮件
- 数据校验规则
- 乱码问题 WebMvcConfigurationSupport
- 批处理
## 三.链接 ## 三.链接
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
<description>Demo project for Spring Boot</description> <description>Demo project for Spring Boot</description>
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<!-- 与1.8配置在一起,设置编码集-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
...@@ -113,6 +116,14 @@ ...@@ -113,6 +116,14 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId> <artifactId>spring-boot-starter-mail</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
......
package com.kwan.springbootkwan; package com.kwan.springbootkwan;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
...@@ -6,6 +7,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; ...@@ -6,6 +7,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling @EnableScheduling
@SpringBootApplication @SpringBootApplication
@EnableBatchProcessing
public class SpringBootKwanApplication { public class SpringBootKwanApplication {
public static void main(String[] args) { public static void main(String[] args) {
......
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<Person> itemReader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<>();
reader.setLinesToSkip(1);
reader.setResource(new ClassPathResource("data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames("id", "username", "address", "gender");
//配置列与列之间的间隔符(将通过间隔符对每一行的数据进行切分),最后设置要映射的实体类属性即可
setDelimiter(",");
}
});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {
{
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")
.<Person, Person>chunk(2)
.reader(itemReader())
.writer(jdbcBatchItemWriter())
.build();
}
@Bean
Job csvJob() {
return jobBuilderFactory.get("csvJob")
.start(csvStep())
.build();
}
}
package com.kwan.springbootkwan.config; 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.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 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-跨域配置 * 全局webconfig-跨域配置
...@@ -14,7 +27,49 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; ...@@ -14,7 +27,49 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
* @date : 2022/12/19 16:11 * @date : 2022/12/19 16:11
*/ */
@Configuration @Configuration
public class MyWebMvcConfig implements WebMvcConfigurer { public class MyWebMvcConfig extends WebMvcConfigurationSupport implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> 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<HandlerExceptionResolver> resolvers) {
WebMvcConfigurer.super.configureHandlerExceptionResolvers(resolvers);
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> 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 { ...@@ -26,6 +81,31 @@ public class MyWebMvcConfig implements WebMvcConfigurer {
.addResourceLocations("classpath:/static/"); .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 { ...@@ -51,4 +131,29 @@ public class MyWebMvcConfig implements WebMvcConfigurer {
.maxAge(1800) .maxAge(1800)
.allowedOrigins("http://localhost:8081"); .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<HandlerMethodArgumentResolver> resolvers) {
WebMvcConfigurer.super.addArgumentResolvers(resolvers);
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
WebMvcConfigurer.super.addReturnValueHandlers(handlers);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
WebMvcConfigurer.super.configureMessageConverters(converters);
}
} }
...@@ -5,6 +5,9 @@ import com.kwan.springbootkwan.entity.User; ...@@ -5,6 +5,9 @@ import com.kwan.springbootkwan.entity.User;
import com.kwan.springbootkwan.service.IUserService; import com.kwan.springbootkwan.service.IUserService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; 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.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -22,6 +25,12 @@ import java.util.List; ...@@ -22,6 +25,12 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/person") @RequestMapping("/person")
public class PersonController { public class PersonController {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
/** /**
* { * {
* "name": "zhang san", * "name": "zhang san",
...@@ -33,9 +42,18 @@ public class PersonController { ...@@ -33,9 +42,18 @@ public class PersonController {
@GetMapping("/person") @GetMapping("/person")
public Person person() { public Person person() {
Person person = new Person(); Person person = new Person();
person.setName("zhang san"); person.setUsername("zhang san");
person.setAge(24); person.setId(24);
person.setBirthday(new Date()); person.setAddress("湖北");
return person; return person;
} }
@GetMapping("/hello")
public void hello() {
try {
jobLauncher.run(job, new JobParameters());
} catch (Exception e) {
e.printStackTrace();
}
}
} }
\ No newline at end of file
package com.kwan.springbootkwan.controller; package com.kwan.springbootkwan.controller;
import com.kwan.springbootkwan.entity.Student;
import com.kwan.springbootkwan.entity.User; import com.kwan.springbootkwan.entity.User;
import com.kwan.springbootkwan.service.IUserService; import com.kwan.springbootkwan.service.IUserService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; 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 org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -38,4 +46,18 @@ public class UserController { ...@@ -38,4 +46,18 @@ public class UserController {
public User getUserById(@PathVariable Integer id) { public User getUserById(@PathVariable Integer id) {
return userService.getUserById(id); return userService.getUserById(id);
} }
@PostMapping(value = "/student",produces = "application/json;charset=utf-8")
public List<String> addUser(@RequestBody @Validated Student student, BindingResult result ) throws UnsupportedEncodingException {
List<String> errors = new ArrayList<>();
if (result.hasErrors()) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError error : allErrors) {
errors.add(error.getDefaultMessage());
}
}
log.info("errors={}", errors);
return errors;
}
} }
\ No newline at end of file
package com.kwan.springbootkwan.entity; package com.kwan.springbootkwan.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.Map; import java.util.Map;
...@@ -13,16 +14,16 @@ import java.util.Map; ...@@ -13,16 +14,16 @@ import java.util.Map;
*/ */
@Data @Data
public class MailInfo { public class MailInfo {
// 邮件接收人 @ApiModelProperty(value = "邮件接收人")
private String[] receiver; private String[] receiver;
// 邮件主题 @ApiModelProperty(value = "邮件主题")
private String subject; private String subject;
// 邮件的文本内容 @ApiModelProperty(value = "邮件的文本内容")
private String content; private String content;
// 抄送人 @ApiModelProperty(value = "抄送人")
private String[] cc; private String[] cc;
// 邮件附件的文件名 @ApiModelProperty(value = "邮件附件的文件名")
private String[] attachFileNames; private String[] attachFileNames;
// 邮件内容内嵌图片 @ApiModelProperty(value = "邮件内容内嵌图片")
private Map<String, String> imageMap; private Map<String, String> imageMap;
} }
package com.kwan.springbootkwan.entity; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date; @Data
@TableName(value = "person")
@ApiModel(value = "用户基本信息") @ApiModel(value = "用户基本信息")
public class Person { public class Person {
@ApiModelProperty(value = "姓名") @ApiModelProperty(value = "主键")
private String name; private Integer id;
@ApiModelProperty(value = "年龄") @ApiModelProperty(value = "名称")
private Integer age; private String username;
@ApiModelProperty(value = "生日") @ApiModelProperty(value = "地址")
@JsonFormat(pattern = "yyyy-MM-dd") private String address;
private Date birthday; @ApiModelProperty(value = "性别")
private String gender;
public String getName() { }
return name; \ No newline at end of file
}
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;
}
}
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;
}
user.name.size=用户名的长度在5到10个字符之间
user.address.notnull=用户地址不能为空
user.age.size=年龄输入不正确
user.email.notnull=邮箱不能为空
user.email.pattern=不正确的电子邮件格式
\ No newline at end of file
server: server:
port: 8761 port: 8761
servlet:
encoding:
force: true
charset: UTF-8
enabled: true
swagger: swagger:
enable: true enable: true
#兼容swagger配置 #兼容swagger配置
spring: 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: mail:
host: smtp.qq.com host: smtp.qq.com
# 发送者的邮箱账号 # 发送者的邮箱账号
......
id,username,address,gender
1,张三,成都,男
2,李四,深圳,女
3,张三,成都,男
4,李四,深圳,女
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册