SpringMVC之JSR303使用及拦截器使用(带你探索SpringMVC的新领域)

2023-11-18

目录

前言

一、探索JSR303的世界

1. JSR303简介

1.1 什么是JSR303

 1.2 JSR303的重要性及使用原因

重要性:

原因:

1.3 JSR303的常用注解

扩展

2. JSR303快速入门(基本使用) 

2.1 导入依赖

 2.2 配置效验规则

 实体类属性设置

对应控制器的方法

 对应JSP页面编写

2.3 测试结果

二、研究拦截器奥秘(拦截器的使用) 

2.1 什么是拦截器

2.2 拦截器与过滤器的区别

2.3.应用场景

2.4 拦截器之快速入门

2.4.1 创建一个拦截器

2.4.2 配置拦截器(在spring-mvc.xml中配置)

 2.4.3 将拦截器类中的preHandle的返回值改为false的测试结果

2.5 拦截器运行经脉(工作原理)

原理图

 工作原理详细描述

2.6 拦截器链的秘密(讲解拦截器链)

2.6.1 再创建一个拦截器

2.6.2 配置两个拦截器(在spring-mvc.xml中配置)

2.6.3 测试结果

情况一:测试clz下的请求

情况二:测试不是clz下的请求 

2.6.4 注意

三、拦截器究极奥秘(案例模拟使用)

1. 创建案例所需拦截器

2.配置案例所需拦截器

3. 创建案例所需控制器

4. 创建模拟案例jsp页面

测试结果

模拟测试登陆

退出登陆

​编辑 


前言

         今天来给大家继续分享有关SpringMVC的知识点,今天带大家探索SpringMVC的新领域,让我们一起来学习了解吧。

一、探索JSR303的世界

1. JSR303简介

1.1 什么是JSR303

        JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。 JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint(约束) 的实现,除此之外还有一些附加的 constraint。

        它定义了一套用于验证Java Bean对象的标准注解和API。通过使用JSR 303的注解,可以对Java Bean的属性进行各种验证,例如检查字段是否为空、是否满足特定的格式、是否在指定范围内等。这样可以在数据绑定和有效性验证时,提供方便且统一的验证机制。

        注:

验证数据是一项常见任务,它发生在从表示层到持久层的所有应用程序层中。通常在每一层都实现相同的验证逻辑,这既耗时又容易出错。为了避免重复这些验证,开发人员经常将验证逻辑直接捆绑到域模型中,将域类与验证代码混在一起,而验证代码实际上是关于类本身的元数据。

 1.2 JSR303的重要性及使用原因

重要性
  • 数据有效性验证:JSR 303允许开发人员对Java Bean属性的值进行验证,以确保数据的合法性。通过使用预定义的验证注解,可以轻松地对属性进行验证,例如检查是否为空、是否满足指定的格式、是否在合理的范围内等。

  • 统一验证规范:使用JSR 303可以定义一套统一的验证规范,比如校验器的注解列表,这样整个团队就可以遵循相同的验证规则,提高代码的一致性和可读性。

  • 减少重复代码:使用JSR 303可以减少手动编写和维护的验证逻辑代码,因为验证逻辑已经由注解定义并集成到验证框架中。这样可以减少重复代码的编写,提高开发效率。

  • 功能强大的验证:JSR 303提供了多种预定义的验证注解,如@NotNull、@Size、@Email等,可以满足大部分常见的验证需求。此外,它还支持自定义验证注解,可以根据具体业务需求创建特定的验证规则。

  • 兼容性和可移植性:JSR 303是Java EE的一部分,并且被广泛支持和应用于各种Java框架和平台,如Spring、Hibernate等。因此,使用JSR 303可以获得良好的兼容性和可移植性,可以在不同的项目和环境中重复使用验证规则。

原因
  1. 假如说前端代码校验没写好又或者是对于会一点编程的人来说,直接绕过前端发请求(通过类似Postman这样的测试工具进行非常数据请求),把一些错误的参数传过来,你后端代码不就危险了嘛。所以我们一般都是前端一套校验,后端在一套校验,这样安全性就能够大大得到提升了。

  2. JSR 303提供了一种简单、一致和可扩展的方式来验证Java Bean对象的数据有效性,提高开发效率和代码质量。通过使用JSR 303,可以减少手动编写验证逻辑的工作量,提高代码的可读性和可维护性。

1.3 JSR303的常用注解

注解 说明
@Null 用于验证对象为null
@NotNull 用于对象不能为null,无法查检长度为0的字符串
@NotBlank 只用于String类型上,不能为null且trim()之后的size>0
@NotEmpty 用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来
@Size 用于对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length 用于String对象的大小必须在指定的范围内
@Pattern 用于String对象是否符合正则表达式的规则
@Email 用于String对象是否符合邮箱格式
@Min 用于Number和String对象是否大等于指定的值
@Max 用于Number和String对象是否小等于指定的值
@AssertTrue 用于Boolean对象是否为true
@AssertFalse 用于Boolean对象是否为false
扩展

@Validated与@Valid区别 :

 @Validated:

  • Spring提供的

  • 支持分组校验

  • 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

  • 由于无法加在成员属性(字段)上,所以无法单独完成级联校验,需要配合@Valid

@Valid:

  • JDK提供的(标准JSR-303规范)

  • 不支持分组校验

  • 可以用在方法、构造函数、方法参数和成员属性(字段)上

  • 可以加在成员属性(字段)上,能够独自完成级联校验

2. JSR303快速入门(基本使用) 

2.1 导入依赖

 2.2 配置效验规则

 实体类属性设置
package com.yx.model;

import lombok.ToString;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.NotNull;

@ToString
public class Clazz {
    @NotNull(message = "班级编号不能为空")
//    @Size(max = 100,min = 10,message = "大小必须在10至100之间"),不注解测会影响代码运行
    protected Integer cid;

    @NotBlank(message = "班级名不能为空")
    protected String cname;

    @NotBlank(message = "班级教员老师不能为空")
    protected String cteacher;


    private String pic;

    public Clazz(Integer cid, String cname, String cteacher, String pic) {
        this.cid = cid;
        this.cname = cname;
        this.cteacher = cteacher;
        this.pic = pic;
    }

    public Clazz() {
        super();
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getCteacher() {
        return cteacher;
    }

    public void setCteacher(String cteacher) {
        this.cteacher = cteacher;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }
}
对应控制器的方法
//    给数据添加服务端校验
    @RequestMapping("/valiAdd")
    public String valiAdd(@Validated Clazz clazz, BindingResult result, HttpServletRequest req){
//        如果服务端验证不通过,有错误
        if(result.hasErrors()){
//            服务端验证了实体类的多个属性,多个属性都没有验证通过
            List<FieldError> fieldErrors = result.getFieldErrors();
            Map<String,Object> map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
//                将多个属性的验证失败信息输送到控制台
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            req.setAttribute("errorMap",map);
        }else {
            this.clazzBiz.insertSelective(clazz);
            return "redirect:list";
        }
        return "clz/edit";
    }

 对应JSP页面编写
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>电影编辑界面</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/${empty c ? 'clz/valiAdd' : 'clz/edit'}" method="post">
    班级编号:<input type="text" name="cid" value="${c.cid }"><span style="color: red;">${errorMap.cid}</span><br>
    班级名称:<input type="text" name="cname" value="${c.cname }"><span style="color: red;">${errorMap.cname}</span><br>
    教员:<input type="text" name="cteacher" value="${c.cteacher }"><span style="color: red;">${errorMap.cteachcer}</span><br>
    图片:<input type="text" name="pic" value="${c.pic }"><br>
    <input type="submit">
</form>
</body>
</html>

2.3 测试结果

二、研究拦截器奥秘(拦截器的使用) 

2.1 什么是拦截器

        拦截器(Interceptor)是一种常见的设计模式,在软件开发中用于拦截和处理请求、响应或方法调用的组件。拦截器可以允许开发人员在特定的时间点对请求进行预处理、后处理或进行额外的操作。

        在Web开发中,拦截器通常用于拦截HTTP请求和响应,以在处理请求之前或之后执行一些操作。例如,可以使用拦截器进行身份验证、日志记录、性能监控、异常处理等。拦截器在框架和平台中广泛使用,如Java的Servlet过滤器、Spring框架的拦截器、Android框架中的拦截器等。它们提供了一种可插拔、可重用和可扩展的方式来处理各种请求和操作。

         SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。依赖于web框架,在实现上基于Java的反射机制,属于面向切面编(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 controller生命周期之内可以多次调用。

2.2 拦截器与过滤器的区别

  • 作用范围不同:拦截器通常是在应用程序内部的某一层中使用,在MVC框架中用于拦截请求和处理;过滤器则是在Servlet容器级别上使用,用于拦截HTTP请求和响应。
  • 处理位置不同:拦截器位于特定处理程序的周围;过滤器位于请求链的前后
  • 功能不同:拦截器更多地用于对请求进行预处理和后处理,以及在请求处理过程中进行额外的操作;过滤器则更多地用于在请求和响应之间修改或转换数据
  • 实现接口不同:拦截器通常需要实现特定的接口,如Spring框架中的HandlerInterceptor接口;过滤器则需要实现javax.servlet.Filter接口
  • 导入依赖不同:拦截器通常与MVC框架或特定的请求处理框架(如Spring MVC)结合使用,因此可能依赖于这些框架的上下文和功能;过滤器则是在Servlet容器级别上执行的,与特定的框架无关。

2.3.应用场景

  1. 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

  2. 权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

  3. 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

  4. 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

2.4 拦截器之快速入门

2.4.1 创建一个拦截器

public class OneInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【OneInterceptor】:preHandle...");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【OneInterceptor】:postHandle...");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【OneInterceptor】:afterCompletion...");
    }
}

2.4.2 配置拦截器(在spring-mvc.xml中配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--1) 扫描com.zking.zf及子子孙孙包下的控制器(扫描范围过大,耗时)-->
    <context:component-scan base-package="com.yx"/>

    <!--2) 此标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    <mvc:annotation-driven />

    <!--3) 创建ViewResolver视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- viewClass需要在pom中引入两个包:standard.jar and jstl.jar -->
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4) 单独处理图片、样式、js等资源 -->
     <mvc:resources location="/static/" mapping="/static/**"/>

<!--    处理文件的上传下载的问题-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 文件最大大小(字节) 1024*1024*50=50M-->
        <property name="maxUploadSize" value="52428800"></property>
        <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
        <property name="resolveLazily" value="true"/>
    </bean>

<!--    配置拦截器-->
    <mvc:interceptors>
        <bean class="com.yx.interceptor.OneInterceptor"></bean>
    </mvc:interceptors>

     <aop:aspectj-autoproxy/>
</beans>

 配置结果

 如上图所示,如果不进行进一步配置则拦截器会拦截所有的请求,接下来会进测试

 当我们进行发送请求时,如下图

则拦截器会进行拦截(因为前面未进行进一不配置则会拦截所有),控制台输出如下

它会先经过来拦截器进行预处理,然后做出输出;在经过控制器调用指定的方法;然后在经过拦截器进行控制台输出;接着回显到页面上,拦截器做出最后处理。

 2.4.3 将拦截器类中的preHandle的返回值改为false的测试结果

 发送请求时则会对该请求进行拦截,阻止方法请求的方法,导致无法访问到数据库,从而数据无法显示到页面上去,也不会进行执行后续代码操作。效果如下

页面效果

控制台输出 

2.5 拦截器运行经脉(工作原理)

原理图

 工作原理详细描述
  1. 定义拦截器:首先,需要定义一个或多个拦截器,并实现对应的拦截器接口或类。这些拦截器将包含要执行的操作的逻辑。

  2. 设置拦截器链:在需要使用拦截器的地方,例如MVC框架的控制器层,会存在一个拦截器链(Interceptor Chain)用于存储所有拦截器的实例。拦截器链按照一定的顺序组织,决定了拦截器的执行顺序。

  3. 执行拦截器逻辑:当请求到达拦截器链所在的位置时,每个拦截器将按照顺序依次执行。拦截器在请求处理的不同阶段会被调用,如请求前、请求后、视图渲染前、视图渲染后等。

  4. 拦截器的前置处理:每个拦截器在执行之前可以进行一些预处理操作,例如身份验证、参数验证、日志记录等。这些操作可以在请求到达目标处理程序之前进行,以确保请求的有效性和安全性。

  5. 处理程序执行:在拦截器链的最后一个拦截器执行后,请求将传递给目标处理程序,例如MVC框架中的控制器方法。处理程序执行特定的业务逻辑,并返回一个结果。

  6. 拦截器的后置处理:在处理程序执行完毕后,拦截器链会按照相反的顺序执行拦截器的后置处理操作。这些操作可以处理处理程序的返回结果、记录日志、清理资源等。

注:

        拦截器能够在请求的不同阶段执行预定义的操作,并对请求进行干预和处理。拦截器的工作原理以及具体的拦截器接口和方法可能有所差异,具体取决于所使用的框架和应用程序架构。

2.6 拦截器链的秘密(讲解拦截器链)

2.6.1 再创建一个拦截器
public class TwoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【TwoInterceptor】:preHandle...");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【TwoInterceptor】:postHandle...");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【TwoInterceptor】:afterCompletion...");
    }
}
2.6.2 配置两个拦截器(在spring-mvc.xml中配置)
 <mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.yx.interceptor.OneInterceptor"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/clz/**"/>
        <bean class="com.yx.interceptor.TwoInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

将上述代码添加到spring-mvc.xml文件中,将原有的注释掉。

2.6.3 测试结果
情况一:测试clz下的请求

页面

因为preHandle的返回值未改为false,所以能访问到界面

控制台

情况二:测试不是clz下的请求 

2.6.4 注意

 当我们去访问图片或者静态资源映射的时候是不经过拦截器的,

三、拦截器究极奥秘(案例模拟使用)

1. 创建案例所需拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【implements】:preHandle...");
        StringBuffer url = request.getRequestURL();
        if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
            //        如果是 登录、退出 中的一种
            return true;
        }
//            代表不是登录,也不是退出
//            除了登录、退出,其他操作都需要判断是否 session 登录成功过
        String uname = (String) request.getSession().getAttribute("uname");
        if (uname == null || "".equals(uname)){
            response.sendRedirect("/page/login");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

2.配置案例所需拦截器

<mvc:interceptors>
        <bean class="com.yx.interceptor.LoginInterceptor"></bean>
    </mvc:interceptors>

3. 创建案例所需控制器

package com.yx.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:25
 */
@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(HttpServletRequest req){
        String uname = req.getParameter("uname");
        HttpSession session = req.getSession();
        if ("zs".equals(uname)){
            session.setAttribute("uname",uname);
        }
        return "redirect:/clz/list";
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest req){
        req.getSession().invalidate();
        return "redirect:/clz/list";
    }
}

4. 创建模拟案例jsp页面

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/13
  Time: 0:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登陆界面</h1>
<form action="/login" method="post">
    用户名:<input name="uname">
    <input type="submit">

</form>
</body>
</html>

测试结果

模拟测试登陆

退出登陆

今天对新知识的探索就到这了,希望老铁能够三连夹关注支持一波 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC之JSR303使用及拦截器使用(带你探索SpringMVC的新领域) 的相关文章

随机推荐

  • 【Linux】Linux和Window下\r与\n的区别、git命令行的使用

    作者 小卢 专栏 Linux Git 喜欢的话 世间因为少年的挺身而出 而更加瑰丽 人民日报 目录 1 回车换行符在Window下和在Linux下的区别 1 1回车换行符 1 2 行缓冲区打印 1 3进度条小程序 2 git命令行的使用 2
  • JAVA SM2 数字证书生成

    文章目录 Before Start Build with Maven QuickStart 生成自签名公私钥对 证书签名算法算法提供者 设置证书信息 标识信息构造 DN 获取扩展密钥用途构造 可选 证书信息构造 X 509格式证书对象生成
  • C语言版通讯录——动态存储(进阶版)

    前言 之前 我出了一期关于通讯录管理系统的项目实现 里面可以实现通讯录人员的增添改查显示以及排序统计功能 但那种只是以静态开辟内存的方式进行编写 大小固定死 若是达到上限便不可以再进行添加 这次优化 我会将静态存储改为动态存储 达到可以永久
  • idea双击启动无效,idea卡顿问题

    idea双击启动无效 大概率是关机时没有正确关闭idea 再次开机导致无法正常启动idea 1 通过任务管理器杀死idea进程后重启idea 2 需要修改配置 打开 以各自电脑实际为准 C Program Files JetBrains I
  • OpenResty简介、编译安装、新增 sticky模块(再编译)、升级

    OpenResty 也被称为 ngx openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 其内部集成了大量精良的 Lua 库 第三方的Nginx模块和大部分系统依赖包 用于方便地搭建能够处理超高并发 扩展性极高的
  • 找不到boost/noncopyable.hpp问题

    本人在vs2013使用boost库的时候 提示找不到boost noncopyable hpp文件 在百度和贴吧上找了很多资料 安装没出问题 只是在包含include的路径是为D boost 1 56 0 boost 本人将boost库直接
  • c++ 友元

    c 类中可以用friend关键字来声明友元 友元可以是另一个类或者类外的其他函数 友元只具有单向性例如 在类A中将类B声明为友元B可以查看A中的所有成员 而A不能查看B的私有成员 同理将一个函数声明为友元时这个函数也可以访问类中的所有成员
  • 6、微信小程序的布局

    文章目录 前言 一 传统基本布局 1 盒子模型 2 显示方式Display 3 定位position 4 溢出属性Overflow 5 浮动Float 6 对齐 二 Flex弹性布局 1 基本属性 2 使用示例 前言 wxss 指的是 We
  • (转)42个超实用的Google Chrome 插件,值得你拥有,建议收藏!

    每日英文 When friends ignore you don t be sad everyone has his own life who can not always be with you 当朋友忽略你时 不要伤心 每个人都有自己的
  • MySql语句查询某一级节点的所有子节点

    MySql语句查询某一级节点的所有子节点 在日常项目中 我们总能用到树型结构的数据 我们用代码去进行查询是比较麻烦的 这里提供一种sql语句查询父节点和子节点的方法 说明 只能当前节点查出所有子节点 不包含与当前节点平级的节点 且子节点是全
  • 事务,不只ACID

    1 什么是事务 应用在运行时可能会发生数据库 硬件的故障 应用与数据库的网络连接断开或多个客户端端并发修改数据导致预期之外的数据覆盖问题 为了提高应用的可靠性和数据的一致性 事务应运而生 从概念上讲 事务是应用程序将多个读写操作组合成一个逻
  • 微信h5分享好友和朋友圈功能

    在开发公众号H5项目时 如果想和小程序一样有分享朋友圈和好友功能时发现会不一样 开发微信小程序时做分享有会有onShareAppMessage 这个方法 因为H5有许多限制 所以在做微信H5分享时就比较麻烦了 首先明确一点 微信H5分享是没
  • Disruptor 详解

    Disruptor 详解 想了解一个项目 最好的办法就是 把它的源码搞到本地自己捣鼓 在网上看了 N 多人对 Disruptor 速度的吹捧 M 多人对它的机制分析 就连 Disruptor 官方文档中 也 NB 哄哄自诩 At LMAX
  • Netty学习17-Netty的可视化

    学习第41节 Netty 可视化方案 Console 日志定时输出 JMX 实时展示 ELKK TIG etc ChannelHandler Sharable public class MetricsHandler extends Chan
  • 08-----查找某个文件的路径

    1 使用find命令查找 关于find这个命令 非常强大 它可以根据文件大小 属性 用户 文件名等去查找匹配的文件 这里不再解释 这里只是列出常用的方法 查找某个文件并不输出错误 find name GetInfo 2 gt dev nul
  • 【Arthas】Arthas retransform动态重新加载类

    1 概述 转载 Arthas retransform动态重新加载类 2 开篇 Arthas提供retransform命令来重新加载已加载的类 通过该命令可以在有限制的反编译已加载的类重新修改后生成class文件重新加载 在测试环境中可以尝试
  • springboot参数配置

    全局配置文件 application properties 配置文件 先准备两个pojo实体类Pet和Person Component 用于将Person类作为Bean注入到spring容器中 ConfigurationProperties
  • 【js小游戏&案例】纯前端实现飞机大战,附带源码

    技能 使用html js css实现飞机大战小游戏 需求 我军飞机左右移动 并且按空格 可以发射炮弹 敌方飞机从上往下飞 接触到我方炮弹 飞机被歼灭 我军接触到敌军飞机也将会被歼灭 我方飞机吃到道具可以增加弹道 思路 初始化 初始创建我方飞
  • enum一个最不像class的class

    enum一个最不像class的classjava枚举类型是jdk5出现的 它的出现主要为了解决一些有特殊意义 已经确定的 长度不会改变的集合 月份描述 public class Month 月份名称 private final String
  • SpringMVC之JSR303使用及拦截器使用(带你探索SpringMVC的新领域)

    目录 前言 一 探索JSR303的世界 1 JSR303简介 1 1 什么是JSR303 1 2 JSR303的重要性及使用原因 重要性 原因 1 3 JSR303的常用注解 扩展 2 JSR303快速入门 基本使用 2 1 导入依赖 2