1.springboot数据校验
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
构建需要校验的实体类:
@AllArgsConstructor
@NoArgsConstructor
@Accessors
@Data
public class User {
@NotNull(message = "用户id不能为空")
private Integer id;
@NotBlank(message = "姓名不能为空")
@Length(min = 2, max = 15, message = "姓名长度为2-15位。")
private String name;
@Range(min = 0, max = 100, message = "年龄范围应该在0-100内。")
private Integer age;
@Email(message = "邮箱格式错误")
private String email;
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
@NotBlank(message = "手机号码不能为空")
private String phone;
}
Controller的请求参数上添加@Valid 注解开启验证
@RestController
@Slf4j
public class UserController {
@PostMapping("/user")
public String Validate(@RequestBody @Valid User user){
log.info("The user's information is {}", user);
return "success";
}
}
2.拦截器
编写拦截器实现类,实现HandlerInterceptor接口,在方法内实现自己的业务逻辑代码
package com.wyu.tt12validation.common.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class AdminInterceptor implements HandlerInterceptor {
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
//如果设置为true时,请求将会继续执行后面的操作
log.info("请求处理之前进行调用");
return true;
}
/**
* 请求处理之后进行调用,Controller方法调用之后
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
log.info("请求处理之后进行调用");
}
/**
* 在整个请求结束之后被调用,主要是用于进行资源清理工作
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
log.info("请求结束之后进行调用");
}
}
配置拦截器类并实现WebMvcConfigurer类,并重写其中的方法
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册TestInterceptor拦截器
InterceptorRegistration registration = registry.addInterceptor(new AdminInterceptor());
registration.addPathPatterns("/**"); //所有路径都被拦截
registration.excludePathPatterns( //添加不拦截路径
"/**/*.html", //html静态资源
"/**/*.css" //css静态资源
);
}
}
执行效果:
3.springboot使用@Scheduled定时任务
1.cron表达式字符含义说明
cron表达式:* * * * * *,其实就是一个字符串,
字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,其中常用为六个域。
corn从左到右(用空格隔开)分别是:秒 分 小时 月份中的日期 月份 星期中的日期 年份
字段 | 允许值 | 允许的特殊字符 |
---|---|---|
秒(Seconds) | 0~59的整数 | , - * / 四个字符 |
分(Minutes) | 0~59的整数 | , - * / 四个字符 |
小时(Hours) | 0~23的整数 | , - * / 四个字符 |
日期(DayofMonth) | 1~31的整数(但是你需要考虑你月的天数) | ,- * ? / L W C 八个字符 |
月份(Month) | 1~12的整数或者 JAN-DEC | , - * / 四个字符 |
星期(DayofWeek) | 1~7的整数或者 SUN-SAT (1=SUN) | , - * ? / L C # 八个字符 |
年(可选,不常用)(Year) | 1970~2099 | , - * / 四个字符 |
corn表达式示范
- 每隔5秒执行一次:*/5 * * * * ?
- 每隔1分钟执行一次:0 */1 * * * ?
- 每小时的20分执行一次:0 20 * * * ?
- 每天的两点35分执行一次:0 35 2 * * ?
- 每月的1日的凌晨2点调整任务:0 0 2 1 * ? *
- 每天上午10点,下午2点,4点 执行一次:0 0 10,14,16 * * ?
- 每周星期天凌晨1点实行一次 :0 0 1 ? * L
2.@Scheduled注解说明:
@Scheduled(
initialDelay = 5000, //第一次延迟多长时间后再执行
initialDelayString = "5000", //第一次延迟5秒后执行,值为String类型
fixedDelay = 5000, //上一次执行完毕时间点之后多长时间再执行
fixedDelayString = "5000", //上一次执行完毕时间点之后5秒再执行,值为String类型
fixedRate = 5000, //上一次开始执行时间点之后多长时间再执行
fixedRateString = "5000", //上一次开始执行时间点之后5s再执行,值为String类型
cron = "", //cron的表达式
zone = "" //时区,cron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区
)
3.springboot工程中使用
在springboot的主类上,加上注解@EnableScheduling
@SpringBootApplication
@EnableScheduling
public class MybatisplusdemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusdemoApplication.class, args);
}
}
编写测试类
package com.wyu.mybatisplusdemo.article.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Scheduled;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class Schedule {
Logger log = LoggerFactory.getLogger(Schedule.class);
//cron表达式:每隔5秒执行一次
@Scheduled(cron = "0/5 * * * * *")
public void scheduled(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh点mm分ss秒");
// 将date日期解析为字符串
String date = simpleDateFormat.format(new Date());
log.info("当前时间:" + date);
}
}
执行结果:
4.SpringBoot整合MybatisPlus
1.引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
2.添加配置:
server:
port: 8090
spring:
#------------------------MySql-----------------------------
datasource:
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
mybatis-plus:
mapper-locations: classpath:mapper/*/*Mapper.xml
type-aliases-package: com.wyu.tt13mybatisplus.*.model
global-config:
refresh-mapper: true
3.数据库表设计:
CREATE TABLE `article` (
`article_id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(128) DEFAULT NULL COMMENT '文章标题',
`content` longtext COMMENT '正文内容',
PRIMARY KEY (`article_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='文章表';
4.实体类:
@AllArgsConstructor
@NoArgsConstructor
@Accessors
@Data
@TableName("article")
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
//标识主键策略
@TableId
private Long articleId;
private String title;
private String content;
}
5.ArticleDao接口,另外也可以在这里自定义mybatis接口写sql
@Mapper
public interface ArticleDao extends BaseMapper<Article> {
}
6.ArticleService :
@Service
public class ArticleService {
@Autowired
private ArticleDao articleDao;
/**
* 1.新增 , insert方法
* @param article
* @return
*/
public boolean save(Article article){
return articleDao.insert(article) > 0;
}
/**
* 2.通过QueryWrapper查询数量
*/
public Integer selectArticleCount(){
return articleDao.selectCount(new QueryWrapper<Article>().eq("title","测试"));
}
/**
* 3.通过selectMaps查询list<Map<String, Object>>
*/
public List<Map<String, Object>> selectArticleMaps(){
QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("title", "测试");
List<Map<String, Object>> list = articleDao.selectMaps(queryWrapper);
return list;
}
/**
* 4.通过QueryWrapper查询list<Object>
*/
public List<Object> selectObjs()
{
List<Object> list = articleDao.selectObjs(new QueryWrapper<Article>().eq("title", "测试"));
return list;
}
/**
* 5.分页查询,笔者个人还是比较喜欢使用pagehelper来分页,毕竟比较简单
*/
public IPage<Article> selectPage()
{
QueryWrapper queryWrapper = new QueryWrapper<Article>().eq("title", "测试");
int count = articleDao.selectCount(queryWrapper);
IPage<Article> page = new Page(1,2);
IPage<Article> list = articleDao.selectPage(page, queryWrapper);
System.out.println("返回数据:"+ list.getRecords());
System.out.println("总条数:"+list.getTotal() + "当前页码:"+list.getCurrent()+ "总页码:"+list.getPages() + "每页显示条数:"+list.getSize());
System.out.println("返回的数据:"+page.getRecords());
return list;
}
/**
* 6,删除,根据articleId来删除
*/
public boolean delete(Long articleId)
{
return articleDao.deleteById(articleId) > 0;
}
/**
* 7,删除,根据QueryWrapper删除
*/
public boolean deleteByQueryWrapper()
{
return articleDao.delete(new QueryWrapper<Article>().eq("title", "测试")) > 0;
}
/**
* 8, 批量删除,把多个id存放到list中,再批量删除,其实很少会用到
*/
public boolean deleteBatchIds(List<Long> articleIdList)
{
return articleDao.deleteBatchIds(articleIdList) > 0;
}
/**
* 9,修改 封装方法中做了非空校验,如果该字段为null,则不进行更新
*/
public boolean updateById(Article article) {
return articleDao.updateById(article) > 0;
}
}
7.controller:
@RestController
public class ArticleController {
@Autowired
private ArticleService articleService;
@RequestMapping("/selectArticleCount")
public Integer selectArticleCount(){
return articleService.selectArticleCount();
}
@RequestMapping("/selectPage")
public String selectPage(){
return articleService.selectPage().toString();
}
}
5.springboot整合freemarker
1.引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.添加配置:
#------------------------freemarker-----------------------------
spring:
freemarker:
cache: false
suffix: .ftl
template-loader-path: classpath:/templates
content-type: text/html; charset=utf-8
settings:
number_format: 0 #数字格式,比较大的数字会带有逗号,如1,000
4.Freemarker表达式使用:
- 获取元素值:
<#if (msg)!="">
${msg}
</#if>
- 循环输出list,先判断list是否为空:
<#if students ?? && students ?size gt 0>
<#list students as student>
${student.name}
${student.age}
</#list>
</#if>
- 逻辑判断:
<#if type == 1>
type=1
<#elseif type == 2>
type=2
</#if>
- 格式化输出时间:
${createTime?string('yyyy-MM-dd hh:mm:ss')}
- include标签,引入其他页面
<#include "right.ftl">
6.springboot整合kafka
1.引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.添加配置:
spring:
kafka: # 指定kafka 代理地址,可以多个
bootstrap-servers: 192.168.211.137:9092,192.168.211.139:9092,192.168.211.140:9092
template: # 指定默认topic id
default-topic: producer
listener: # 指定listener 容器中的线程数,用于提高并发量
concurrency: 5
consumer:
group-id: myGroup # 指定默认消费者group id
client-id: 200
max-poll-records: 200
auto-offset-reset: earliest # 最早未被消费的offset
producer:
batch-size: 1000 # 每次批量发送消息的数量
retries: 3
client-id: 200
3.生产者
@Slf4j
@Component
public class KafkaProducer {
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Autowired
private ObjectMapper objectMapper;
public void send(String topic, Object body) {
Message<String> message = new Message<>();
message.setId(System.currentTimeMillis());
message.setMessage(body.toString());
message.setTime(new Date());
String content = null;
try {
content = objectMapper.writeValueAsString(message);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
kafkaTemplate.send(topic, content);
log.info("send {} to {} success!", message, topic);
System.out.println("send "+ message +" to "+ topic +" success!");
}
}
4.消费者
@Slf4j
@Component
public class KafkaConsumer {
/**
* 有消息就读取,读取消息topic,offset,key,value等信息
*/
@KafkaListener(topics = {"kafka1"})
public void listen(ConsumerRecord<?, ?> record) {
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
if (kafkaMessage.isPresent()) {
Object message = kafkaMessage.get();
log.info("详细消息读取-------------------->");
log.info("message:{} + record:{}", message, record);
}
}
/**
* 有消息就读取,批量读取消息
*/
@KafkaListener(topics = "kafka1")
public void onMessage(List<String> crs) {
for(String str : crs){
log.info("批量读取-------------------->");
log.info("kafka1:" + str);
}
}
/**
* 有消息就读取message
*/
@KafkaListener(topics = {"kafka1"})
public void receiveMessage(String message){
log.info("读取message-------------------->");
log.info("kafka1:" + message);
}
}
5.Controller:
@Slf4j
@RestController
public class KafkaController {
@Autowired
private KafkaProducer kafkaProducer;
@GetMapping("/kafka/{topic}")
public String send(@PathVariable("topic") String topic, @RequestParam String message) {
kafkaProducer.send(topic, message);
return "success";
}
}
7.未完待续。。。
转载:https://blog.csdn.net/weixin_39025362/article/details/106938581
查看评论