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

Java實(shí)現(xiàn)Token登錄驗(yàn)證的項(xiàng)目實(shí)踐

 更新時(shí)間:2023年03月16日 11:16:46   作者:普通網(wǎng)友  
本文主要介紹了Java實(shí)現(xiàn)Token登錄驗(yàn)證的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、JWT是什么?

在介紹JWT之前,我們先來回顧一下利用token進(jìn)行用戶身份驗(yàn)證的流程:

1、客戶端使用用戶名和密碼請(qǐng)求登錄

2、服務(wù)端收到請(qǐng)求,驗(yàn)證用戶名和密碼

3、驗(yàn)證成功后,服務(wù)端會(huì)簽發(fā)一個(gè)token,再把這個(gè)token返回給客戶端

4、客戶端收到token后可以把它存儲(chǔ)起來,比如放到cookie中

5、客戶端每次向服務(wù)端請(qǐng)求資源時(shí)需要攜帶服務(wù)端簽發(fā)的token,可以在cookie或者h(yuǎn)eader中攜帶

6、服務(wù)端收到請(qǐng)求,然后去驗(yàn)證客戶端請(qǐng)求里面帶著的token,如果驗(yàn)證成功,就向客戶端返回請(qǐng)求數(shù)據(jù)

這種基于token的認(rèn)證方式相比傳統(tǒng)的session認(rèn)證方式更節(jié)約服務(wù)器資源,并且對(duì)移動(dòng)端和分布式更加友好。其優(yōu)點(diǎn)如下

支持跨域訪問:cookie是無法跨域的,而token由于沒有用到cookie(前提是將token放到請(qǐng)求頭中),所以跨域后不會(huì)存在信息丟失問題
無狀態(tài):token機(jī)制在服務(wù)端不需要存儲(chǔ)session信息,因?yàn)閠oken自身包含了所有登錄用戶的信息,所以可以減輕服務(wù)端壓力
更適用CDN:可以通過內(nèi)容分發(fā)網(wǎng)絡(luò)請(qǐng)求服務(wù)端的所有資料
更適用于移動(dòng)端:當(dāng)客戶端是非瀏覽器平臺(tái)時(shí),cookie是不被支持的,此時(shí)采用token認(rèn)證方式會(huì)簡單很多
無需考慮CSRF:由于不再依賴cookie,所以采用token認(rèn)證方式不會(huì)發(fā)生CSRF,所以也就無需考慮CSRF的防御

而JWT就是上述流程當(dāng)中token的一種具體實(shí)現(xiàn)方式,其全稱是JSON Web Token,官網(wǎng)地址:https://jwt.io/

通俗地說,JWT的本質(zhì)就是一個(gè)字符串,它是將用戶信息保存到一個(gè)Json字符串中,然后進(jìn)行編碼后得到一個(gè)JWT token,并且這個(gè)JWT token帶有簽名信息,接收后可以校驗(yàn)是否被篡改,所以可以用于在各方之間安全地將信息作為Json對(duì)象傳輸。JWT的認(rèn)證流程如下:

1、首先,前端通過Web表單將自己的用戶名和密碼發(fā)送到后端的接口,這個(gè)過程一般是一個(gè)POST請(qǐng)求。建議的方式是通過SSL加密的傳輸(HTTPS),從而避免敏感信息被嗅探

2、后端核對(duì)用戶名和密碼成功后,將包含用戶信息的數(shù)據(jù)作為JWT的Payload,將其與JWT Header分別進(jìn)行Base64編碼拼接后簽名,形成一個(gè)JWT Token,形成的JWT Token就是一個(gè)如同lll.zzz.xxx的字符串
3、后端將JWT Token字符串作為登錄成功的結(jié)果返回給前端。前端可以將返回的結(jié)果保存在瀏覽器中,退出登錄時(shí)刪除保存的JWT Token即可

4、前端在每次請(qǐng)求時(shí)將JWT Token放入HTTP請(qǐng)求頭中的Authorization屬性中(解決XSS和XSRF問題)

5、后端檢查前端傳過來的JWT Token,驗(yàn)證其有效性,比如檢查簽名是否正確、是否過期、token的接收方是否是自己等等

6、驗(yàn)證通過后,后端解析出JWT Token中包含的用戶信息,進(jìn)行其他邏輯操作(一般是根據(jù)用戶信息得到權(quán)限等),返回結(jié)果

在這里插入圖片描述

最后:說白了,JWT:JSON Web Token,其實(shí)token就是一段字符串,由三部分組成:Header,Payload,Signature

二、使用步驟

1.項(xiàng)目結(jié)構(gòu)

在這里插入圖片描述

2.相關(guān)依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.21</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.3.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.18.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>

3.數(shù)據(jù)庫

這里進(jìn)行測(cè)試,所以用戶類只有用戶名密碼,自行創(chuàng)建

在這里插入圖片描述

4.相關(guān)代碼

1、annotation包
PassToken:

package com.geesun.annotation;

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

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:26
 * @description:用來跳過驗(yàn)證的 PassToken
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

UserLoginToken:

package com.geesun.annotation;

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

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:26
 * @description:用于登錄后才能操作的token
 */
/*RetentionPolicy.RUNTIME:這種類型的Annotations將被JVM保留,
所以他們能在運(yùn)行時(shí)被JVM或其他使用反射機(jī)制的代碼所讀取和使用。*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}

2、common包
CodeMsg:

package com.geesun.common;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:26
 * @description:返回提示
 */
public class CodeMsg {
    private int retCode;
    private String message;
    // 按照模塊定義CodeMsg
    // 通用異常
    public static CodeMsg SUCCESS = new CodeMsg(0,"success");
    public static CodeMsg SERVER_EXCEPTION = new CodeMsg(500100,"服務(wù)端異常");
    public static CodeMsg PARAMETER_ISNULL = new CodeMsg(500101,"輸入?yún)?shù)為空");
    // 業(yè)務(wù)異常
    public static CodeMsg USER_NOT_EXSIST = new CodeMsg(500102,"用戶不存在");
    public static CodeMsg ONLINE_USER_OVER = new CodeMsg(500103,"在線用戶數(shù)超出允許登錄的最大用戶限制。");
    public static CodeMsg SESSION_NOT_EXSIST =  new CodeMsg(500104,"不存在離線session數(shù)據(jù)");
    public static CodeMsg NOT_FIND_DATA = new CodeMsg(500105,"查找不到對(duì)應(yīng)數(shù)據(jù)");
    public static CodeMsg USER_OR_PASS_ERROR = new CodeMsg(500102,"賬號(hào)或者密碼錯(cuò)誤,請(qǐng)重試!");


    private CodeMsg(int retCode, String message) {
        this.retCode = retCode;
        this.message = message;
    }

    public int getRetCode() {
        return retCode;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

Result:

package com.geesun.common;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:26
 * @description:返回統(tǒng)一結(jié)果集
 */
public class Result<T> {

    private String message;
    private int retCode;
    private T data;

    private Result(T data) {
        this.retCode = 200;
        this.message = "成功";
        this.data = data;
    }

    private Result(CodeMsg cm) {
        if(cm == null){
            return;
        }
        this.retCode = cm.getRetCode();
        this.message = cm.getMessage();
    }

    /**
     * 成功時(shí)候的調(diào)用
     * @return
     */
    public static <T> Result<T> success(T data){
        return new Result<T>(data);
    }

    /**
     * 成功,不需要傳入?yún)?shù)
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> Result<T> success(){
        return (Result<T>) success("");
    }
    /**
     * 失敗時(shí)候的調(diào)用
     * @return
     */
    public static <T> Result<T> error(CodeMsg cm){
        return new Result<T>(cm);
    }
    /**
     * 失敗時(shí)候的調(diào)用,擴(kuò)展消息參數(shù)
     * @param cm
     * @param msg
     * @return
     */
    public static <T> Result<T> error(CodeMsg cm,String msg){
        cm.setMessage(cm.getMessage()+"--"+msg);
        return new Result<T>(cm);
    }
    public T getData() {
        return data;
    }
    public String getMessage() {
        return message;
    }
    public int getRetCode() {
        return retCode;
    }
}

3、config包
InterceptorConfig:

package com.geesun.config;

import com.geesun.Interceptor.AuthenticationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import java.util.List;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:25
 * @description:新建Token攔截器
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");    // 攔截所有請(qǐng)求,通過判斷是否有 @LoginRequired 注解 決定是否需要登錄
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void addCorsMappings(CorsRegistry arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void addFormatters(FormatterRegistry arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void addViewControllers(ViewControllerRegistry arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configurePathMatch(PathMatchConfigurer arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void configureViewResolvers(ViewResolverRegistry arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public MessageCodesResolver getMessageCodesResolver() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public Validator getValidator() {
        // TODO Auto-generated method stub
        return null;
    }

}

4、Interceptor包
AuthenticationInterceptor:

package com.geesun.Interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.geesun.annotation.PassToken;
import com.geesun.annotation.UserLoginToken;
import com.geesun.pojo.User;
import com.geesun.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:24
 * @description:攔截器
 */
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 從 http 請(qǐng)求頭中取出 token
        // 如果不是映射到方法直接通過
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //檢查是否有passtoken注釋,有則跳過認(rèn)證
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //檢查有沒有需要用戶權(quán)限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 執(zhí)行認(rèn)證
                if (token == null) {
                    throw new RuntimeException("無token,請(qǐng)重新登錄");
                }
                // 獲取 token 中的 user id
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用戶不存在,請(qǐng)重新登錄");
                }
                // 驗(yàn)證 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

5、utils包
TokenUtil:

package com.geesun.utils;

import com.auth0.jwt.JWT;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:24
 * @description:
 */
public class TokenUtil {

    public static String getTokenUserId() {
        String token = getRequest().getHeader("token");// 從 http 請(qǐng)求頭中取出 token
        String userId = JWT.decode(token).getAudience().get(0);
        return userId;
    }

    /**
     * 獲取request
     * @return
     */
    public static HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        return requestAttributes == null ? null : requestAttributes.getRequest();
    }

}

6、pojo包
User:

package com.geesun.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "`user`")
public class User implements Serializable {
    @TableId(value = "id", type = IdType.NONE)
    private String id;

    @TableField(value = "username")
    private String username;

    @TableField(value = "password")
    private String password;

    private static final long serialVersionUID = 1L;
}

7、controller包
UserController:

package com.geesun.controller;

import cn.hutool.json.JSONObject;
import com.geesun.annotation.UserLoginToken;
import com.geesun.common.CodeMsg;
import com.geesun.common.Result;
import com.geesun.pojo.User;
import com.geesun.service.UserService;
import com.geesun.service.impl.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/26 10:47
 * @description:
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    /**
     * 查詢用戶信息
     * @return
     */
    @UserLoginToken
    @GetMapping("/list")
    public Result<Object> list(){
        return Result.success(userService.list());
    }


    /**
     * 登錄驗(yàn)證
     * @param user
     * @param response
     * @return
     */
    @RequestMapping(value = "/login" ,method = RequestMethod.GET)
    public Result<Object> login(User user, HttpServletResponse response) {
        JSONObject jsonObject = new JSONObject();
        //獲取用戶賬號(hào)密碼
        User userForBase = new User();
        userForBase.setId(userService.findByUsername(user).getId());
        userForBase.setUsername(userService.findByUsername(user).getUsername());
        userForBase.setPassword(userService.findByUsername(user).getPassword());
        //判斷賬號(hào)或密碼是否正確
        if (!userForBase.getPassword().equals(user.getPassword())) {
            return Result.error(CodeMsg.USER_OR_PASS_ERROR);
        } else {
            String token = tokenService.getToken(userForBase);
            jsonObject.put("token", token);
            Cookie cookie = new Cookie("token", token);
            cookie.setPath("/");
            response.addCookie(cookie);
            return Result.success(jsonObject);
        }
    }
    
}

8、service包
UserService接口:

package com.geesun.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.geesun.pojo.User;

public interface UserService extends IService<User> {


    int deleteByIds(Long[] ids);

    int addUser(User user);

    User findByUsername(User user);

    User findUserById(String userId);
}

UserServiceImpl實(shí)現(xiàn)類:

package com.geesun.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geesun.mapper.UserMapper;
import com.geesun.pojo.User;
import com.geesun.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;
    
    /**
     * 判斷用戶名
     * @param user
     * @return
     */
    public User findByUsername(User user){
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername,user.getUsername()));
    }

    public User findUserById(String userId) {
        return userMapper.selectById(userId);
    }

}

TokenService:

package com.geesun.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.geesun.pojo.User;
import org.springframework.stereotype.Service;
import java.util.Date;

/**
 * @author :Mr.ZJW
 * @date :Created 2022/2/28 10:20
 * @description:
 */
@Service
public class TokenService {

    public String getToken(User user) {
        Date start = new Date();
        long currentTime = System.currentTimeMillis() + 60* 60 * 1000;//一小時(shí)有效時(shí)間
        Date end = new Date(currentTime);
        String token = "";

        token = JWT.create().withAudience(user.getId()).withIssuedAt(start).withExpiresAt(end)
                .sign(Algorithm.HMAC256(user.getPassword()));
        return token;
    }
}

9、mapper包

package com.geesun.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.geesun.pojo.User;

public interface UserMapper extends BaseMapper<User> {

}

三、測(cè)試結(jié)果

1、登錄驗(yàn)證

在這里插入圖片描述

2、查詢用戶信息
這個(gè)方法加上了@UserLoginToken,所以要token才能查詢

在這里插入圖片描述

在這里插入圖片描述

3、不加上Token進(jìn)行測(cè)試就會(huì)出錯(cuò)提示

在這里插入圖片描述

出錯(cuò)提示:

在這里插入圖片描述

到此這篇關(guān)于Java實(shí)現(xiàn)Token登錄驗(yàn)證的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Java Token登錄驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 通過spring boot 設(shè)置tomcat解決 post參數(shù)限制問題

    通過spring boot 設(shè)置tomcat解決 post參數(shù)限制問題

    這篇文章主要介紹了通過spring boot 設(shè)置tomcat解決 post參數(shù)限制問題,需要的朋友可以參考下
    2019-05-05
  • Mybatis批處理、Mysql深分頁操作

    Mybatis批處理、Mysql深分頁操作

    這篇文章主要介紹了Mybatis批處理、Mysql深分頁操作,Mybatis批量操作包括Foreach方式和ExecutorType.BATCH插入操作,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java kafka如何實(shí)現(xiàn)自定義分區(qū)類和攔截器

    Java kafka如何實(shí)現(xiàn)自定義分區(qū)類和攔截器

    這篇文章主要介紹了Java kafka如何實(shí)現(xiàn)自定義分區(qū)類和攔截器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • JDK的命令詳解

    JDK的命令詳解

    JDK的命令詳解...
    2006-12-12
  • Java并發(fā)之AQS與自旋鎖詳解

    Java并發(fā)之AQS與自旋鎖詳解

    這篇文章主要介紹了Java并發(fā)之AQS與自旋鎖詳解,類如其名,抽象的隊(duì)列式的同步器,AQS定義了一套多線程訪問共享資源的同步器框架,許多同步類實(shí)現(xiàn)都依賴于它,如常用的ReentrantLock/Semaphore/CountDownLatch,需要的朋友可以參考下
    2023-10-10
  • spring框架下@value注解屬性static無法獲取值問題

    spring框架下@value注解屬性static無法獲取值問題

    這篇文章主要介紹了spring框架下@value注解屬性static無法獲取值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringBoot使用AOP實(shí)現(xiàn)統(tǒng)一角色權(quán)限校驗(yàn)

    SpringBoot使用AOP實(shí)現(xiàn)統(tǒng)一角色權(quán)限校驗(yàn)

    這篇文章主要介紹了SpringBoot如何使用AOP實(shí)現(xiàn) 統(tǒng)一角色權(quán)限校驗(yàn),文中有詳細(xì)的代碼示例講解和操作流程,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-07-07
  • java實(shí)現(xiàn)Excel轉(zhuǎn)換為圖片

    java實(shí)現(xiàn)Excel轉(zhuǎn)換為圖片

    在實(shí)際開發(fā)過程中,經(jīng)常會(huì)有這樣的需求,需要將Excel表格或特定區(qū)域轉(zhuǎn)換為圖片,所以小編今天就來為大家介紹一下如何使用Java將Excel轉(zhuǎn)化為圖片吧
    2023-10-10
  • 分布式Netty源碼分析概覽

    分布式Netty源碼分析概覽

    這篇文章主要為大家介紹了分布式Netty源碼分析概覽,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • SWT(JFace)體驗(yàn)之ViewForm的使用

    SWT(JFace)體驗(yàn)之ViewForm的使用

    SWT(JFace)體驗(yàn)之ViewForm的使用
    2009-06-06

最新評(píng)論