添加依赖:
<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";
}
}
编写拦截器实现类,实现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静态资源
);
}
}
1.拦截器与过滤器的区别
2.编写过滤器类:
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器初始化----------》");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("完成请求所需时间:"+(System.currentTimeMillis()-start));
}
@Override
public void destroy() {
System.out.println("过滤器销毁----------》");
}
}
3.配置过滤器类:
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new LogFilter());
registration.addUrlPatterns("/*");
registration.setName("LogFilter");
registration.setOrder(1); //配置多个过滤器时,执行的优先级
return registration;
}
}
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表达式示范
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);
}
}
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();
}
}
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>
<#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 "right.ftl">
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";
}
}
1.添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2.添加配置:
spring:
mail:
host: smtp.163.com
username: ****@163.com #自己的邮箱账号
password: ******* #这个不是登录密码而是163授权登录的密码
default-encoding: UTF-8
获取163授权的密码,到163的网页端,把以下两个开关打开
3.功能测试
@Autowired
private JavaMailSender javaMailSender;
//发送普通文本邮件
@RequestMapping(value = "/sendMail")
public String sendMail(Model model) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("654321***@163.com"); //发送者
message.setTo("123456***@qq.com"); //接受者
message.setCc("654321***@163.com"); //抄送,填发送者的邮箱即可
message.setSubject("今天天气真好"); //主题
message.setText("你好你好你好!"); //内容
try {
javaMailSender.send(message);
System.out.println("简单邮件已经发送");
} catch (Exception e) {
System.out.println("发送简单邮件时发生异常!"+e.toString());
}
model.addAttribute("msg", "");
return "login";
}
//也可以发送html形式的邮件
@RequestMapping("/sendHtmlMail")
public void sendHtmlMail() {
String content="\n" +
"\n" +
" 你好你好你好!
\n" +
"\n" +
"";
MimeMessage message = javaMailSender.createMimeMessage();
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
messageHelper.setFrom("654321***@163.com");
messageHelper.setTo("123456***@qq.com");
messageHelper.setSubject("今天天气真好");
messageHelper.setText(content, true);
javaMailSender.send(message);
System.out.println("邮件成功发送");
} catch (MessagingException e) {
System.out.println("发送邮件时发生异常!"+e.toString());
}
}
1.引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.添加配置:
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
#连接池最大连接数
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间 默认 -1 表示没有限制
spring.redis.jedis.pool.max-wait=-1ms
#连接池最大空闲连接数
spring.redis.jedis.pool.max-idle=8
#连接池最小空闲连接数
spring.redis.jedis.pool.min-idle=0
3.常用方法:
StringRedisTemplate:
//先引入StringRedisTemplate
@Autowired
private StringRedisTemplate stringRedisTemplate;
//向redis里存入数据和设置缓存时间
stringRedisTemplate.opsForValue().set("redis", "100", 60 * 10, TimeUnit.SECONDS);
//val做-1操作
stringRedisTemplate.boundValueOps("redis").increment(-1);
//根据key获取缓存中的val
stringRedisTemplate.opsForValue().get("redis")
//val +1
stringRedisTemplate.boundValueOps("redis").increment(1);
//根据key获取过期时间
stringRedisTemplate.getExpire("redis");
//根据key获取过期时间并换算成指定单位
stringRedisTemplate.getExpire("redis",TimeUnit.SECONDS);
//根据key删除缓存
stringRedisTemplate.delete("redis");
//检查key是否存在,返回boolean值
stringRedisTemplate.hasKey("redis");
//向指定key中存放set集合
stringRedisTemplate.opsForSet().add("redis", "1","2","3");
//设置过期时间
stringRedisTemplate.expire("redis",1000 , TimeUnit.MILLISECONDS);
//根据key查看集合中是否存在指定数据
stringRedisTemplate.opsForSet().isMember("redis", "1");
//根据key获取set集合
stringRedisTemplate.opsForSet().members("redis");
//验证有效时间
Long expire = stringRedisTemplate.boundHashOps("redis").getExpire();
System.out.println("redis有效时间:"+expire+"秒");
1.添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.添加如下配置:
itblog表示MongoDB中的itblog库
spring:
data:
mongodb:
uri: "mongodb://106.55.55.259:27017/itblog"
3.编写实体类
@Data
@Document("user")
public class User {
@Id
private String id;
@Field("name")
private String name;
@Field("password")
private String password;
@Field("address")
private String address;
@Field("create_time")
private Date createTime;
}
4.编写dao
public interface UserDao {
List<User> findAll();
User findById(String id);
User save(User user);
User insert(User user);
void deleteById(String id);
}
5.编写service
@Service
public class UserService implements UserDao {
@Autowired
private MongoTemplate template;
@Override
public List<User> findAll() {
return template.findAll(User.class);
}
@Override
public User findById(String id) {
return template.findById(id,User.class);
}
@Override
public User save(User user) {
return template.save(user);
}
@Override
public User insert(User user) {
return template.insert(user);
}
@Override
public void deleteById(String id) {
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
template.remove(query, User.class);
}
}
6.编写controller
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("")
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public User getByUserId(@PathVariable String userId) {
return userService.findById(userId);
}
@PostMapping("")
public User addNewUser(@RequestBody User user) {
if (user.getId() == null) {
return userService.insert(user);
}
return userService.save(user);
}
@DeleteMapping("/{id}")
public String delete(@PathVariable String id) {
User user = new User();
user.setId(id);
userService.deleteById(id);
return "deleted: " + id;
}
@PutMapping("")
public User update(@RequestBody User user) {
return userService.save(user);
}
}
1.引入依赖:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.swagger配置类:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
/**
* swagger通过配置会生成文档,包括接口名、请求方法、参数、返回信息等
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.wyu.tt08mongo"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("基于Swagger构建的Rest API文档")
.description("MongoDB 在线文档!")
.termsOfServiceUrl("https://blog.csdn.net/weixin_39025362/article/details/106938581")
.version("1.0")
.build();
}
}