Loading

开发常用工具类Utils

常用工具类Utils

1.RespBean 返回值对象

/**
 * @author ANTIA1
 * @date 2021/7/12 15:20
 */
public class RespBean {
    private Integer status;
    private String msg;
    private Object obj;

    public static RespBean build() {
        return new RespBean();
    }

    public static RespBean ok(String msg) {
        return new RespBean(200, msg, null);
    }

    public static RespBean ok(String msg, Object obj) {
        return new RespBean(200, msg, obj);
    }

    public static RespBean error(String msg) {
        return new RespBean(500, msg, null);
    }

    public static RespBean error(String msg, Object obj) {
        return new RespBean(500, msg, obj);
    }

    private RespBean() {
    }

    private RespBean(Integer status, String msg, Object obj) {
        this.status = status;
        this.msg = msg;
        this.obj = obj;
    }

    public Integer getStatus() {
        return status;
    }

    public RespBean setStatus(Integer status) {
        this.status = status;
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public RespBean setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public Object getObj() {
        return obj;
    }

    public RespBean setObj(Object obj) {
        this.obj = obj;
        return this;
    }
}

2.DBUtils 数据库连接类

import java.sql.Connection;
import java.sql.DriverManager;

public class DBUtils {
    private static Connection connection;

    private static Connection getConnection(){
        return connection;
    }

    public static Connection initDb(DB db){
        if (connection == null){
            try {
                Class.forName("com.mysql.jdbc.Driver");
                connection = DriverManager.getConnection(db.getUrl(),db.getUsername(),db.getPassword());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return connection;
    }
}

3.Maven 静态资源过滤

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
</resources>

4.把扁平数据转成树形数据

function treeData(source, id, parentId, children){   
    let cloneData = JSON.parse(JSON.stringify(source))
    return cloneData.filter(father=>{
        let branchArr = cloneData.filter(child => father[id] == child[parentId]);
        branchArr.length>0 ? father[children] = branchArr : ''
        return father[parentId] == 0        // 如果第一层不是parentId=0,请自行修改
    })
}
// 调用时,字段名以字符串的形式传参,如treeData(source, 'id', 'parentId', 'children')

test.vue

<template>
  <el-tree
    :data="treeData"
    :props="defaultProps"
    accordion
    @node-click="handleNodeClick">
  </el-tree>
</template>
 
<script>
    export default {
        name: "Test",
      data(){
        return {
          data : [
            {id:1,parentId:0,name:"一级菜单A",rank:1},
            {id:2,parentId:0,name:"一级菜单B",rank:1},
            {id:3,parentId:0,name:"一级菜单C",rank:1},
            {id:4,parentId:1,name:"二级菜单A-A",rank:2},
            {id:5,parentId:1,name:"二级菜单A-B",rank:2},
            {id:6,parentId:2,name:"二级菜单B-A",rank:2},
            {id:7,parentId:4,name:"三级菜单A-A-A",rank:3},
            {id:8,parentId:7,name:"四级菜单A-A-A-A",rank:4},
            {id:9,parentId:8,name:"五级菜单A-A-A-A-A",rank:5},
            {id:10,parentId:9,name:"六级菜单A-A-A-A-A-A",rank:6},
            {id:11,parentId:10,name:"七级菜单A-A-A-A-A-A-A",rank:7},
            {id:12,parentId:11,name:"八级菜单A-A-A-A-A-A-A-A",rank:8},
            {id:13,parentId:12,name:"九级菜单A-A-A-A-A-A-A-A-A",rank:9},
            {id:14,parentId:13,name:"十级菜单A-A-A-A-A-A-A-A-A-A",rank:10},
          ],
          defaultProps: {
            children: 'children',
            label: 'name'
          }
        }
      },
      computed:{
        treeData(){
          let cloneData = JSON.parse(JSON.stringify(this.data))    // 对源数据深度克隆
          return cloneData.filter(father=>{               
            let branchArr = cloneData.filter(child=>father.id == child.parentId)    //返回每一项的子级数组
            branchArr.length>0 ? father.children = branchArr : ''   //如果存在子级,则给父级添加一个children属性,并赋值
            return father.parentId==0;      //返回第一层
          });
        }
      },
      methods:{
        handleNodeClick(data){
          // console.log(data)
          console.log(this.treeData)
        }
      },
      mounted(){
      }
    }
</script>
 
<style scoped>
 
</style>

5.树形数据转成扁平数据

利用递归的方法循环树形数组,当遇到有children的对象再次调用递归函数循环children数组,每次循环的数据放入一个提前声明好的数组里,等所有递归函数执行完,这个数组即是想要得到的扁平数据数组。

let res = []
const fn = (source)=>{
    source.forEach(el=>{
        res.push(el)
        el.children && el.children.length>0 ? fn(el.children) : ""
    })
}

test.js

let res = []        // 用于存储递归结果(扁平数据)
// 递归函数
const fn = (source)=>{
    source.forEach(el=>{
        res.push(el)
        el.children && el.children.length>0 ? fn(el.children) : ""        // 子级递归
    })
}
 
// 树形数据
const arr = [
    { id: "1", rank: 1 },
    { id: "2", rank: 1,
        children:[ 
            { id: "2.1", rank: 2 },
            { id: "2.2", rank: 2 } 
        ] 
    },
    { id: "3", rank:1,
        children:[ 
            { id: "3.1", rank:2, 
                children: [ 
                    { id:'3.1.1', rank:3,
                        children:[ 
                            { id: "3.1.1.1", rank: 4, 
                                children:[
                                    { id: "3.1.1.1.1", rank: 5 }
                                ] 
                            } 
                        ] 
                    } 
                ] 
            } 
        ] 
    }
]
fn(arr)             // 执行递归函数
console.log(res)    // 查看结果

6.VO对象

package com.zhuantai.community.controller;

import com.zhuantai.community.entity.DiscussPost;
import com.zhuantai.community.entity.User;
import com.zhuantai.community.service.DiscussPostService;
import com.zhuantai.community.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ANTIA1
 * @date 2021/7/22 18:47
 */
@Controller
public class HomeController {
    @Autowired
    DiscussPostService discussPostService;
    @Autowired
    UserService userService;

    @RequestMapping(path = "/index",method = RequestMethod.GET)
    public String getIndexPage(Model model){
        //查到的对象中的userid仅仅是id,没有完整的信息
        List<DiscussPost> list = discussPostService.findDiscussPosts(0, 0, 10);
        //用来装discusspost和user对象的具合对象
        List<Map<String,Object>> discussPosts = new ArrayList<>();
        if (list !=null){
            //遍历post集合
            for (DiscussPost post : list) {
                Map<String,Object> map = new HashMap<>();
                map.put("post",post);
                //根据post对象中存在的用户id查询出用户信息放入map中,最后在装入list中。
                User user = userService.findUserById(post.getUserId());
                map.put("user",user);
                discussPosts.add(map);
            }
        }

        return "index";
    }
}

7.分页工具类

/**
 * 分页工具类
 * @author ANTIA1
 * @date 2021/7/22 19:25
 */
public class Page {
    //当前的页码
    private Integer currentPage = 1;
    //显示多少条数据
    private Integer size = 10;
    //数据的总数(用于计算总页数)
    private Integer total;
    //查询路径(用于复用分页链接)
    private String path;

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        if (currentPage >= 1){
            this.currentPage = currentPage;
        }
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        if (size >= 1 && size <= 100){
            this.size = size;
        }
    }

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        if (total >= 0){
            this.total = total;
        }
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    /**
     * 获取页码
     * @return
     */
    public Integer getPageNum(){
        return (currentPage - 1) * size;
    }

    /**
     * 获取总页数
     * @return
     */
    public Integer getPageTotal(){
        if (total % size == 0){
            return total / size;
        }else{
            return total / size + 1;
        }
    }

    /**
     * 获取起始页码
     * @return
     */
    public Integer getFrom(){
        int from = currentPage - 1;
        return from < 1 ? 1 : from;
    }

    /**
     * 获取结束页码
     * @return
     */
    public Integer getTo(){
        int to = currentPage + 2;
        int total = getPageTotal();
        return to > total ? total : to;
    }
}

调用:

@Controller
public class HomeController {
    @Autowired
    DiscussPostService discussPostService;
    @Autowired
    UserService userService;

    @RequestMapping(path = "/index",method = RequestMethod.GET)
    public String getIndexPage(Model model, Page page){
        //方法调用前,SpringMVC会自动实例化ModelPage,并将Page注入Model.
        //所以,在thymeleaf中可以直接访问Page对象中的数据。
        //获取有多少条数据
        page.setTotal(discussPostService.findDiscussPostRows(0));
        //用于在分页复用数据
        page.setPath("/index");
        
        return "index";
    }
}
<!-- 分页 -->
<nav class="mt-5" th:if="${page.total > 0}">
	<ul class="pagination justify-content-center">

		<li class="page-item">
		<!-- th:href="@{${page.path}(current=1,size=10)}" = /index/current=1&size=5 -->
			<a class="page-link" th:href="@{${page.path}(current=1)}">首页</a>
		</li>

		<li th:class="|page-item ${page.current==1?'disabled':''}|">
			<a class="page-link" th:href="@{${page.path}(current=${page.current - 1})}">上一页</a>
		</li>

		<!--#numbers.sequence(p1,p2) 会产生一个数字连续的数组-->
		<li th:class="|page-item ${i==page.current?'active':''}|" th:each="i:${#numbers.sequence(page.from,page.to)}">
			<a class="page-link" th:href="@{${page.path}(current=${i})}" th:text="${i}">1</a>
		</li>

		<li th:class="|page-item ${page.current==page.total?'disabled':''}|">
			<a class="page-link" th:href="@{${page.path}(current=${page.current + 1})}">下一页</a>
		</li>

		<li class="page-item">
			<a class="page-link" th:href="@{${page.path}(current=${page.pageTotal})}">末页</a>
		</li>

	</ul>
</nav>

8.邮件发送工具类

package com.zhuantai.community.uitls;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

/**
 * 邮件发送工具类
 * @author ANTIA1
 * @date 2021/7/23 18:24
 */
@Component
public class MailClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(MailClient.class);

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;

    public void sendMail(String to,String subject,String content){
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content,true);
            mailSender.send(helper.getMimeMessage());
        } catch (MessagingException e) {
            LOGGER.error("发送邮件失败:"+e.getMessage());
            e.printStackTrace();
        }
    }

}

调用发送:

/**
 * @author ANTIA1
 * @date 2021/7/23 18:33
 */
@SpringBootTest
public class MailTest {

    @Autowired
    MailClient mailClient;

    @Autowired
    TemplateEngine templateEngine;


    @Test
    public void testHtmlMail(){
        Context context = new Context();
        context.setVariable("username","朱安泰");//设置变量数据
        String content = templateEngine.process("/mail/demo", context);
        
        mailClient.sendMail("antia11@163.com","测试邮件",content);
    }
}

9.加密工具类

package com.zhuantai.community.uitls;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
 * @author ANTIA1
 * @date 2021/7/23 19:03
 */
public class CommunityUtil {

    //生成随机字符串
    public static String generateUUID(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    /**
     * md5加密
     * @param key = password + salt
     * @return
     */
    public static String md5(String key){
        if (StringUtils.isBlank(key)){
            return null;
        }
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }
}

10.验证码生成

<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>
package com.zhuantai.community.config;

import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * 验证码生成工具
 * @author ANTIA1
 * @date 2021/7/23 23:34
 */
@Configuration
public class KaptchaConfig {

    @Bean
    public Producer kaptchaProducer(){
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width","100");//宽度 px
        properties.setProperty("kaptcha.image.height","40");//高度 px
        properties.setProperty("kaptcha.textproducer.font.size","32");//字体大小
        properties.setProperty("kaptcha.textproducer.font.color","0.0.0");//颜色
        //properties.setProperty("kaptcha.textproducer.char.string","0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm");//字符范围
        //properties.setProperty("kaptcha.textproducer.char.length","4");//多少个字符
        properties.setProperty("kaptcha.textproducer.char.length","1");//多少个字符
        properties.setProperty("kaptcha.textproducer.char.string","A");//字符范围
        properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");//干扰


        DefaultKaptcha kaptcha = new DefaultKaptcha();
        Config config = new Config(properties);
        kaptcha.setConfig(config);
    }
}

调用

@Autowired
private Producer kaptcha;

@RequestMapping(value = "/kaptcha",method = RequestMethod.GET)
public void getKaptcha(HttpServletResponse response, HttpSession session){
    //生成验证码
    String text = kaptcha.createText();//根据配置生成字符串
    BufferedImage image = kaptcha.createImage(text);//根据字符串生成的图片

    //将验证码存入session
    session.setAttribute("kaptcha",text);

    //将图片输出给浏览器
    response.setContentType("image/png");
    try {
        OutputStream os = response.getOutputStream();
        ImageIO.write(image,"png",os);
    } catch (IOException e) {
        LOGGER.error("响应验证码失败:"+e.getMessage());
    }
}

11.获取Cookie值

package com.zhuantai.community.uitls;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * 获取Cookie简单方法
 * @author ANTIA1
 * @date 2021/7/24 16:06
 */
public class CookieUtil {

    public static String getValue(HttpServletRequest request,String name){
        if (request == null || name ==null){
            throw new IllegalArgumentException("参数为空");
        }

        Cookie[] cookies = request.getCookies();
        if (cookies != null){
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)){
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
}

12.通过注解注解实现检查登录状态

注解

package com.zhuantai.community.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 该注解标注某个方式是否需要登录后才能访问
 * @author ANTIA1
 * @date 2021/7/24 17:18
 */
@Target(ElementType.METHOD)//这个注解写在哪
@Retention(RetentionPolicy.RUNTIME)//有效的时长
public @interface LoginRequired {
}

拦截器

package com.zhuantai.community.controller.interceptor;

import com.zhuantai.community.annotation.LoginRequired;
import com.zhuantai.community.uitls.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author ANTIA1
 * @date 2021/7/24 17:22
 */
@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {

    @Autowired
    private HostHolder hostHolder;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();//获取拦截到的方法对象
            LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);//获取注解
            //该方法需要登录才能访问
            if (loginRequired != null && hostHolder.getUser() == null){//用户为空说明未登录
                //未登录处理
                response.sendRedirect(request.getContextPath() + "/login");//重定向到登录页面
                return false;
            }
        }
        return true;
    }
}

拦截器注册

package com.zhuantai.community.config;

import com.zhuantai.community.controller.interceptor.AlphaInterceptor;
import com.zhuantai.community.controller.interceptor.LoginRequiredInterceptor;
import com.zhuantai.community.controller.interceptor.LoginTicketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author ANTIA1
 * @date 2021/7/24 12:55
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    LoginRequiredInterceptor loginRequiredInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginRequiredInterceptor)
                .excludePathPatterns("/**/*.css","/**/*.js","/**/*.png","/**/*.jpg","/**/*.jpeg");
    }
}

13.敏感词过滤

package com.zhuantai.community.uitls;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;


/**
 * 敏感词过滤工具类
 * @Author: ANTIA1
 * @Date: 2021/2/13 14:43
 */
@Component
public class SensitiveFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(SensitiveFilter.class);

    //替换符
    private static final String REPLACEMENT = "***";

    //根节点
    private TrieNode rootNode = new TrieNode();

    @PostConstruct//这个注解表示这是一个初始化方法,这个方法会在服务启动时被调用
    public void init(){
        try(
                InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        )
        {
            String keyword;
            while ((keyword = reader.readLine())!=null){
                // 添加到前缀树
                this.addKeyword(keyword);
            }
        } catch (Exception e) {
            LOGGER.error("加载敏感词文件失败:"+e.getMessage());
        }
    }

    /**
     * 把敏感词添加到前缀树中
     * @param keyword
     */
    private void addKeyword(String keyword){
        TrieNode tempNode = rootNode;
        for (int i=0;i<keyword.length();i++){
            char c = keyword.charAt(i);
            TrieNode subNode = tempNode.getSubNode(c);

            if (subNode == null){
                // 初始化子节点
                subNode = new TrieNode();
                tempNode.addSubNode(c,subNode);
            }

            // 指向子节点,进入下一轮循环
            tempNode = subNode;

            // 设置结束的标识
            if (i ==keyword.length()-1){
                tempNode.setKeywordEnd(true);
            }
        }
    }

    /**
     * 过滤敏感词
     * @param text 待过滤文本
     * @return
     */
    public String filter(String text){
        if (StringUtils.isBlank(text)){
            return null;
        }

        // 指针1
        TrieNode tempNode = rootNode;
        // 指针2
        int begin = 0;
        // 指针3
        int position = 0;
        // 结果
        StringBuilder sb = new StringBuilder();

        while (position < text.length()){
            char c = text.charAt(position);

            // 跳过符号
            if (isSymbol(c)){
                // 若指针1属于根节点,将此符号计入结果,让指针2向下走一步
                if (tempNode == rootNode){
                    sb.append(c);
                    begin ++;
                }
                // 无论符号在开头或中间,指针3都向下走一步
                position ++;
                continue;
            }

            //检查下级节点
            tempNode = tempNode.getSubNode(c);
            if (tempNode == null){
                // 以begin开头的字符串不是敏感词
                sb.append(text.charAt(begin));
                // 进入下一个位置
                position = ++begin;
                // 重新指向根节点
                tempNode = rootNode;
            }else if(tempNode.isKeywordEnd()){
                // 发现敏感词,将begin~position字符串替换掉
                sb.append(REPLACEMENT);
                //进入下一个位置
                begin = ++position;
                // 重新指向根节点
                tempNode = rootNode;
            }else {
                // 检查下一个字符
                position ++;
            }
        }

        //将最后一批字符计入结果
        sb.append(text.substring(begin));
        return sb.toString();
    }

    /**
     * 判断是否为符号
     * @param c
     * @return
     */
    private boolean isSymbol(Character c){
        //东亚文字范围 (c<0x2E80 || c > 0x9FFF)
        return !CharUtils.isAsciiAlphanumeric(c) && (c<0x2E80 || c > 0x9FFF);
    }

    /**
     * 前缀树
     */
    private class TrieNode{
        // 关键词结束标识
        private boolean isKeywordEnd = false;

        //子节点<key是下级字符,value是下级节点>
        private Map<Character,TrieNode> subNods = new HashMap<>();


        // 添加子节点
        public void addSubNode(Character c,TrieNode node){
            subNods.put(c,node);
        }

        // 获取子节点
        public TrieNode getSubNode(Character c){
            return subNods.get(c);
        }


        //get & set
        public boolean isKeywordEnd() {
            return isKeywordEnd;
        }

        public void setKeywordEnd(boolean keywordEnd) {
            isKeywordEnd = keywordEnd;
        }
    }

}

14.全局日志记录

package com.zhuantai.community.controller.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ANTIA1
 * @date 2021/7/27 20:13
 */
@Component
@Aspect
public class ServiceLogAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLogAspect.class);

    @Pointcut("execution(* com.zhuantai.community.service.*.*(..))")
    public void pointcut(){
    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        //用户[ip],在[date],访问了[com.zhuantai.community.service.xxx()]
        //获取ip
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip  = request.getRemoteHost();
        //获取时间
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //获取方法
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        LOGGER.info(String.format("用户[%s],在[%s],访问了[%s()].",ip,now,target));
    }
}

15.全局异常处理

package com.zhuantai.voa.exception;

import com.zhuantai.voa.utils.RespBean;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理
 * @author ANTIA1
 * @date 2021/7/13 19:28
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(SQLException.class)
    public RespBean sqlException(SQLException e){
        if (e instanceof SQLIntegrityConstraintViolationException){
            return RespBean.error("该数据有关联数据,操作失败!");
        }
        return RespBean.error("数据库异常,操作失败!");
    }
}

16.日期区间范围判断

package com.zhuantai.ex02.utils;

import java.util.Calendar;
import java.util.Date;

public class MyDateUtils {
    /**
     * 判断当前时间是否在[startTime, endTime]区间,注意时间格式要一致
     *
     * @param nowTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }
}
posted @ 2021-08-02 22:54  ANTIA11  阅读(87)  评论(0编辑  收藏  举报