欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringMVC中的JSR303與攔截器的使用方法

 更新時(shí)間:2023年10月10日 11:01:41   作者:Love-Java.  
JSR303是Java中的一個(gè)標(biāo)準(zhǔn),用于驗(yàn)證和校驗(yàn)JavaBean對(duì)象的屬性的合法性,本文主要介紹了SpringMVC中的JSR303與攔截器的使用方法,感興趣的可以了解一下

一,JSR303的概念

JSR303是Java中的一個(gè)標(biāo)準(zhǔn),用于驗(yàn)證和校驗(yàn)JavaBean對(duì)象的屬性的合法性。它提供了一組用于定義驗(yàn)證規(guī)則的注解,如@NotNull、@Min、@Max等。在Spring MVC中,可以使用JSR303注解對(duì)請(qǐng)求參數(shù)進(jìn)行校驗(yàn)。

1.2 為什么要使用JSR303?(更加理解)

前端不是已經(jīng)校驗(yàn)過(guò)數(shù)據(jù)了嗎?為什么我們還要做校驗(yàn)?zāi)?,直接用不就好了?草率了,假如說(shuō)前端代碼校驗(yàn)沒(méi)寫(xiě)好又或者是對(duì)于會(huì)一點(diǎn)編程的人來(lái)說(shuō),直接繞過(guò)前端發(fā)請(qǐng)求(通過(guò)類(lèi)似Postman這樣的測(cè)試工具進(jìn)行非常數(shù)據(jù)請(qǐng)求),把一些錯(cuò)誤的參數(shù)傳過(guò)來(lái),你后端代碼不就危險(xiǎn)了嘛

所以我們一般都是前端一套校驗(yàn),后端在一套校驗(yàn),這樣安全性就能夠大大得到提升了。

1.3 常用的注解

在上面JSR303的概念中也指到了一些注解,以下是注解的詳細(xì)概述

注解說(shuō)明
@Null用于驗(yàn)證對(duì)象為null
@NotNull用于對(duì)象不能為null,無(wú)法查檢長(zhǎng)度為0的字符串
@NotBlank只用于String類(lèi)型上,不能為null且trim()之后的size>0
@NotEmpty用于集合類(lèi)、String類(lèi)不能為null,且size>0。但是帶有空格的字符串校驗(yàn)不出來(lái)
@Size用于對(duì)象(Array,Collection,Map,String)長(zhǎng)度是否在給定的范圍之內(nèi)
@Length用于String對(duì)象的大小必須在指定的范圍內(nèi)
@Pattern用于String對(duì)象是否符合正則表達(dá)式的規(guī)則
@Email用于String對(duì)象是否符合郵箱格式
@Min用于Number和String對(duì)象是否大等于指定的值
@Max用于Number和String對(duì)象是否小等于指定的值
@AssertTrue用于Boolean對(duì)象是否為true
@AssertFalse用于Boolean對(duì)象是否為false

1.4 @Validated與@Valid區(qū)別

@Validated:

  • Spring提供的

  • 支持分組校驗(yàn)

  • 可以用在類(lèi)型、方法和方法參數(shù)上。但是不能用在成員屬性(字段)上

  • 由于無(wú)法加在成員屬性(字段)上,所以無(wú)法單獨(dú)完成級(jí)聯(lián)校驗(yàn),需要配合@Valid

@Valid:

  • JDK提供的(標(biāo)準(zhǔn)JSR-303規(guī)范)

  • 不支持分組校驗(yàn)

  • 可以用在方法、構(gòu)造函數(shù)、方法參數(shù)和成員屬性(字段)上

  • 可以加在成員屬性(字段)上,能夠獨(dú)自完成級(jí)聯(lián)校驗(yàn)

 二,JSR303使用

2.1 導(dǎo)入pom.xml依賴(lài)

<!-- JSR303 -->
<hibernate.validator.version>6.0.7.Final</hibernate.validator.version>
<!-- JSR303 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>${hibernate.validator.version}</version>
</dependency>

2.2 配置校驗(yàn)規(guī)則

package com.Bingzy.model;
import lombok.ToString;
import org.hibernate.validator.constraints.NotBlank;
@ToString
public class Tbook {
    @ToString
    public class Clazz {
        @NotNull(message = "書(shū)籍編號(hào)不能為空")
        protected Integer bid;
        @NotBlank(message = "書(shū)籍名不能為空")
        protected String bname;
        @NotBlank(message = "書(shū)籍價(jià)格不能為空")
        protected Float price;
        public Clazz(String bid, String bname, Float price) {
            this.bid = bid;
            this.bname = bname;
            this.price = price;
        }
        public String getBid() {
            return bid;
        }
        public void setBid(String bid) {
            this.bid = bid;
        }
        public String getBname() {
            return bname;
        }
        public void setBname(String bname) {
            this.bname = bname;
        }
        public Float getPrice() {
            return price;
        }
        public void setPrice(Float price) {
            this.price = price;
        }
        @Override
        public String toString() {
            return "Clazz{" +
                    "bid='" + bid + '\'' +
                    ", bname='" + bname + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
}

2.3 入門(mén)案例

在請(qǐng)求處理方法中,使用@Validated或@Valid注解要驗(yàn)證的對(duì)象,并根據(jù)BindingResult判斷校驗(yàn)是否通過(guò)。

   //    給數(shù)據(jù)添加服務(wù)端校驗(yàn)
    @RequestMapping("/valiAdd")
    public String valiAdd(@Validated Tbook tbook,
                          BindingResult result,
                          HttpServletRequest req){
//        如果服務(wù)端驗(yàn)證不通過(guò),有錯(cuò)誤
        if(result.hasErrors()){
//            服務(wù)端驗(yàn)證了實(shí)體類(lèi)的多個(gè)屬性,多個(gè)屬性都沒(méi)有驗(yàn)證通過(guò)
            List<FieldError> fieldErrors = result.getFieldErrors();
            Map<String,Object> map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
//                將多個(gè)屬性的驗(yàn)證失敗信息輸送到控制臺(tái)
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            req.setAttribute("errorMap",map);
        }else {
            this.tbookBiz.insertSelective(tbook);
            return "redirect:list";
        }
        return "book/edit";
    }

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>
<center>
    編輯界面
    <form action="${pageContext.request.contextPath }/${empty b ? 'book/valiAdd' : 'book/edit'}" method="post"><br>
        書(shū)籍id:<input type="text" name="bid" value="${b.bid }"><span style="color: red">${errorMap.bid}</span><br>
        書(shū)籍名稱(chēng):<input type="text" name="bname" value="${b.bname }"><span style="color: red">${errorMap.bname}</span><br>
        書(shū)籍價(jià)格:<input type="text" name="price" value="${b.price }"><span style="color: red">${errorMap.price}</span><br>
        <input type="submit">
    </form>
</center>
</body>
</html>

運(yùn)行結(jié)果:

點(diǎn)擊新增或修改,進(jìn)入頁(yè)面后點(diǎn)擊提交顯示相對(duì)應(yīng)的提示語(yǔ)句 

 三,攔截器

3.1 什么是攔截器?

Spring MVC攔截器是Spring框架中的一個(gè)組件,用于攔截請(qǐng)求并在請(qǐng)求處理之前或之后執(zhí)行一些額外的操作。它可以用于實(shí)現(xiàn)一些通用的、與業(yè)務(wù)無(wú)關(guān)的功能,如日志記錄、權(quán)限驗(yàn)證、異常處理、跨域請(qǐng)求處理等。

攔截器在請(qǐng)求到達(dá)DispatcherServlet之后,但在具體的Controller方法執(zhí)行之前,提供了一個(gè)攔截點(diǎn),可以對(duì)請(qǐng)求進(jìn)行處理和干預(yù)。攔截器可以攔截請(qǐng)求、響應(yīng)或會(huì)話(huà)的各個(gè)階段,并在每個(gè)階段執(zhí)行預(yù)定義的操作。

3.2 什么是過(guò)濾器

依賴(lài)于servlet容器。在實(shí)現(xiàn)上基于函數(shù)回調(diào),可以對(duì)幾乎所有請(qǐng)求進(jìn)行過(guò)濾,但是缺點(diǎn)是一個(gè)過(guò)濾器實(shí)例只能在容器初始化時(shí)調(diào)用一次。使用過(guò)濾器的目的是用來(lái)做一些過(guò)濾操作,比如:在過(guò)濾器中修改字符編碼;在過(guò)濾器中修改HttpServletRequest的一些參數(shù),包括:過(guò)濾低俗文字、危險(xiǎn)字符等

3.3 攔截器與過(guò)濾器的區(qū)別?

  • 過(guò)濾器(filter)

    1.filter屬于Servlet技術(shù),只要是web工程都可以使用

  • 2.filter主要由于對(duì)所有請(qǐng)求過(guò)濾

    3.filter的執(zhí)行時(shí)機(jī)早于Interceptor

  • 攔截器(interceptor)

    1.interceptor屬于SpringMVC技術(shù),必須要有SpringMVC環(huán)境才可以使用

    2.interceptor通常由于對(duì)處理器Controller進(jìn)行攔截

    3.interceptor只能攔截dispatcherServlet處理的請(qǐng)求

3.4 應(yīng)用場(chǎng)景

  • 日志記錄:記錄請(qǐng)求信息的日志,以便進(jìn)行信息監(jiān)控、信息統(tǒng)計(jì)、計(jì)算PV(Page View)等。

  • 權(quán)限檢查:如登錄檢測(cè),進(jìn)入處理器檢測(cè)是否登錄,如果沒(méi)有直接返回到登錄頁(yè)面;

  • 性能監(jiān)控:有時(shí)候系統(tǒng)在某段時(shí)間莫名其妙的慢,可以通過(guò)攔截器在進(jìn)入處理器之前記錄開(kāi)始時(shí)間,在處理完后記錄結(jié)束時(shí)間,從而得到該請(qǐng)求的處理時(shí)間(如果有反向代理,如apache可以自動(dòng)記錄);

  • 通用行為:讀取cookie得到用戶(hù)信息并將用戶(hù)對(duì)象放入請(qǐng)求,從而方便后續(xù)流程使用,還有如提取Locale、Theme信息等,只要是多個(gè)Controller中的處理方法都需要的,我們就可以使用攔截器實(shí)現(xiàn)

四,攔截器快速入門(mén)

定義一個(gè)包并創(chuàng)建OneInterceptor類(lèi)

攔截器(interceptor):

package com.Bingzy.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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...");
    }
}
  • spring-mvc.xml配置自定義攔截器

<mvc:interceptors>
        <bean class="com.Bingzy.interceptor.OneInterceptor"></bean>
</mvc:interceptors>

攔截器(interceptor)中的preHandle()方法中的返回值為true未攔截的情況:

攔截器(interceptor)中的preHandle()方法中的返回值為false攔截的情況: 

 注意:攔截器會(huì)根據(jù)preHandle()方法返回值進(jìn)行攔截判斷,返回了一個(gè)true值。這個(gè)返回值表示該攔截器已經(jīng)處理了當(dāng)前的請(qǐng)求,并且可以繼續(xù)向下傳遞請(qǐng)求。如果返回false,則表示該攔截器不處理當(dāng)前請(qǐng)求,請(qǐng)求將被終止 

4.1 攔截器原理圖

  • preHandle:用于對(duì)攔截到的請(qǐng)求進(jìn)行預(yù)處理,方法接收布爾(true,false)類(lèi)型的返回值,返回true:放行,false:不放行。

    執(zhí)行時(shí)機(jī):在處理器方法執(zhí)行前執(zhí)行

    方法參數(shù)

    參數(shù)說(shuō)明
    request請(qǐng)求對(duì)象
    response響應(yīng)對(duì)象
    handler攔截到的方法處理
  • postHandle:用于對(duì)攔截到的請(qǐng)求進(jìn)行后處理,可以在方法中對(duì)模型數(shù)據(jù)和視圖進(jìn)行修改

    執(zhí)行時(shí)機(jī):在處理器的方法執(zhí)行后,視圖渲染之前

    方法參數(shù)

    參數(shù)說(shuō)明
    request請(qǐng)求對(duì)象
    response響應(yīng)對(duì)象
    handler攔截到的處理器方法
    ModelAndView處理器方法返回的模型和視圖對(duì)象,可以在方法中修改模型和視圖
  • afterCompletion:用于在整個(gè)流程完成之后進(jìn)行最后的處理,如果請(qǐng)求流程中有異常,可以在方法中獲取對(duì)象

    執(zhí)行時(shí)機(jī):視圖渲染完成后(整個(gè)流程結(jié)束之后)

    方法參數(shù)

    參數(shù)說(shuō)明
    request請(qǐng)求參數(shù)
    response響應(yīng)對(duì)象
    handler攔截到的處理器方法
    ex異常對(duì)象

4.2 攔截器鏈

    如果多個(gè)攔截器能夠?qū)ο嗤恼?qǐng)求進(jìn)行攔截,則多個(gè)攔截器會(huì)形成一個(gè)攔截器鏈,主要理解攔截器鏈中各個(gè)攔截器的執(zhí)行順序。攔截器鏈中多個(gè)攔截器的執(zhí)行順序,根攔截器的配置順序有關(guān),先配置的先執(zhí)行

攔截器(interceptor)

package com.Bingzy.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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...");
    }
}

spring-mvc.xml配置自定義攔截器

<mvc:interceptors>
        <!--2) 多攔截器(攔截器鏈)-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.Bingzy.interceptor.OneInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/book/**"/>
            <bean class="com.Bingzy.interceptor.TwoInterceptor"/>
        </mvc:interceptor>
</mvc:interceptors>

運(yùn)行展示:

五,用戶(hù)登錄權(quán)限案例 

登入攔截器(interceptor):

package com.Bingzy.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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 登錄成功過(guò)
        String bname = (String) request.getSession().getAttribute("bname");
        if (bname == null || "".equals(bname)){
            response.sendRedirect("/page/book/login");
            return false;
        }
        return true;
    }
}

spring-mvc.xml配置自定義登入攔截器

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

Controller層(web):

package com.Bingzy.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
    @RequestMapping("/login")
    public String login(HttpServletRequest req){
        String bname = req.getParameter("bname");
        HttpSession session = req.getSession();
        if ("zs".equals(bname)){
            session.setAttribute("bname",bname);
        }
        return "redirect:/book/list";
    }
    @RequestMapping("/logout")
    public String logout(HttpServletRequest req){
        req.getSession().invalidate();
        return "redirect:/book/list";
    }
}

login.jsp:

簡(jiǎn)單的測(cè)試布局,可自行布局

測(cè)試結(jié)果:

總結(jié):

如果用戶(hù)發(fā)送URL中的后綴包含"/login"或"/logout",則表示當(dāng)前請(qǐng)求是登錄或退出操作,直接返回true表示繼續(xù)處理請(qǐng)求,后端進(jìn)行判斷“uname”是否為“zs”,如果不是zs則域?qū)ο蟛粫?huì)保存,從而到攔截器判斷域?qū)ο鬄榭談t會(huì)重定向到登良頁(yè)面,如果不為空就執(zhí)行后端返回的字符串到視圖解析器解析跳轉(zhuǎn)指定頁(yè)面

到此這篇關(guān)于SpringMVC中的JSR303與攔截器的使用方法的文章就介紹到這了,更多相關(guān)SpringMVC JSR303與攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot+mybatis實(shí)現(xiàn)多數(shù)據(jù)源支持操作

    SpringBoot+mybatis實(shí)現(xiàn)多數(shù)據(jù)源支持操作

    這篇文章主要介紹了SpringBoot+mybatis實(shí)現(xiàn)多數(shù)據(jù)源支持操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • java 反射getClass .class 的使用方法示例

    java 反射getClass .class 的使用方法示例

    這篇文章主要介紹了java 反射getClass .class 的使用方法,結(jié)合實(shí)例形式分析了java類(lèi)反射機(jī)制的相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • Spring實(shí)戰(zhàn)之@Autowire注解用法詳解

    Spring實(shí)戰(zhàn)之@Autowire注解用法詳解

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之@Autowire注解用法,結(jié)合實(shí)例形式詳細(xì)分析了Spring @Autowire注解具體實(shí)現(xiàn)步驟與相關(guān)使用技巧,需要的朋友可以參考下
    2019-12-12
  • Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng)的方法

    Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng)的方法

    Spring Cloud Security是Spring Security的擴(kuò)展,它提供了對(duì)Spring Cloud體系中的服務(wù)認(rèn)證和授權(quán)的支持,包括OAuth2、JWT等,這篇文章主要介紹了Spring Boot集成Spring Cloud Security進(jìn)行安全增強(qiáng),需要的朋友可以參考下
    2024-11-11
  • 最新評(píng)論