最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于SpringBoot實(shí)現(xiàn)七天免登錄的完整流程

 更新時(shí)間:2026年01月14日 10:25:15   作者:天天摸魚的java工程師  
作為一名Java后端高級(jí)開發(fā),我敢說七天免登錄是業(yè)務(wù)系統(tǒng)里最常見的需求之一,這個(gè)需求看似簡(jiǎn)單,但實(shí)現(xiàn)不好很容易踩坑:要么免登錄失效影響用戶體驗(yàn),要么出現(xiàn)安全漏洞導(dǎo)致賬號(hào)被盜,今天這篇文章,我就結(jié)合實(shí)際工作經(jīng)驗(yàn),講透七天免登錄的標(biāo)準(zhǔn)實(shí)現(xiàn)方案

引言

作為一名Java后端高級(jí)開發(fā),我敢說“七天免登錄”是業(yè)務(wù)系統(tǒng)里最常見的需求之一——用戶登錄一次后,一周內(nèi)再次訪問系統(tǒng)無需重復(fù)輸入賬號(hào)密碼,直接就能進(jìn)入主頁。這個(gè)需求看似簡(jiǎn)單,但實(shí)現(xiàn)不好很容易踩坑:要么免登錄失效影響用戶體驗(yàn),要么出現(xiàn)安全漏洞導(dǎo)致賬號(hào)被盜。

很多初級(jí)開發(fā)會(huì)直接把用戶信息存Cookie,或者簡(jiǎn)單用Session過期時(shí)間控制,這些做法要么不安全,要么在分布式環(huán)境下失效。今天這篇文章,我就結(jié)合實(shí)際工作經(jīng)驗(yàn),講透“七天免登錄”的標(biāo)準(zhǔn)實(shí)現(xiàn)方案,從原理到代碼全拆解,看完就能直接落地。

一、先搞懂:七天免登錄的核心原理

免登錄的本質(zhì)很簡(jiǎn)單:用戶首次登錄成功后,服務(wù)器生成一個(gè)“身份憑證”返回給客戶端,客戶端持久化存儲(chǔ);后續(xù)用戶訪問時(shí),自動(dòng)攜帶這個(gè)憑證,服務(wù)器驗(yàn)證通過后就直接放行。

這里的關(guān)鍵是解決三個(gè)問題:

  • 憑證怎么生成?要唯一、不可偽造、帶過期時(shí)間;
  • 憑證存在哪?客戶端存儲(chǔ)方案要兼顧安全和可用性;
  • 怎么驗(yàn)證?服務(wù)器要快速校驗(yàn)憑證的合法性,還要支持分布式部署。

工作中最成熟的方案是:Cookie + JWT Token + Redis黑名單。為什么選這個(gè)組合?

核心優(yōu)勢(shì):JWT自帶過期時(shí)間和簽名機(jī)制,能避免偽造;Cookie自動(dòng)攜帶憑證,無需前端額外處理;Redis存儲(chǔ)黑名單,解決JWT無法主動(dòng)失效的問題,還能支撐分布式系統(tǒng)。

二、分步實(shí)現(xiàn):七天免登錄完整流程(附實(shí)戰(zhàn)代碼)

我們基于Spring Boot框架實(shí)現(xiàn),整體流程分為5步:用戶登錄生成憑證→客戶端存儲(chǔ)憑證→攔截器校驗(yàn)憑證→活躍續(xù)期→退出登錄失效。下面逐一拆解,代碼可直接復(fù)用。

1. 第一步:準(zhǔn)備依賴和核心配置

首先引入JWT和Redis依賴(如果是單體應(yīng)用,Redis可選,但分布式必須要):

<!-- JWT依賴 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

<!-- Redis依賴(分布式必選) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后在application.yml配置JWT密鑰、過期時(shí)間、Cookie參數(shù):

# JWT配置
jwt:
  secret: your-secret-key-32bytes-long-12345678 # 密鑰必須足夠長(建議32位),放配置中心,不要硬編碼
  expire: 604800000 # 7天過期(單位:毫秒)
  refresh-expire: 86400000 # 1天內(nèi)活躍自動(dòng)續(xù)期(單位:毫秒)

# Cookie配置
cookie:
  name: auto_login_token # Cookie名稱
  domain: localhost # 域名(生產(chǎn)環(huán)境填實(shí)際域名,如xxx.com)
  path: / # 作用路徑
  max-age: 604800 # 7天(單位:秒)
  http-only: true # 僅HTTP訪問,禁止JS操作(防XSS)
  secure: false # 生產(chǎn)環(huán)境開啟HTTPS后設(shè)為true(僅HTTPS傳輸)
  same-site: Lax # 防CSRF攻擊

2. 第二步:封裝JWT工具類(核心)

JWT負(fù)責(zé)生成和解析身份憑證,核心是“簽名防偽造”和“自帶過期時(shí)間”。工具類包含3個(gè)核心方法:生成Token、解析Token、驗(yàn)證Token合法性。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;

@Component
public class JwtUtil {
    // 注入JWT密鑰和過期時(shí)間
    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expire}")
    private long expire;

    // 生成JWT Token(傳入用戶信息,如userId、username)
    public String generateToken(Map<String, Object> claims) {
        // 密鑰編碼(必須和配置的密鑰長度匹配)
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.builder()
                .setClaims(claims) // 自定義載荷(存放用戶信息)
                .setIssuedAt(new Date()) // 簽發(fā)時(shí)間
                .setExpiration(new Date(System.currentTimeMillis() + expire)) // 過期時(shí)間
                .signWith(key) // 簽名
                .compact();
    }

    // 解析Token,獲取載荷信息
    public Claims parseToken(String token) {
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 驗(yàn)證Token是否合法(未過期+簽名正確)
    public boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            // 檢查是否過期
            return !claims.getExpiration().before(new Date());
        } catch (Exception e) {
            // 解析失?。ê灻e(cuò)誤、過期、格式錯(cuò)誤)都返回false
            return false;
        }
    }
}

3. 第三步:登錄接口生成憑證(核心流程)

用戶首次登錄成功后,生成JWT Token,然后通過Cookie返回給客戶端存儲(chǔ)。這里要注意:敏感信息(如密碼)不能放進(jìn)JWT載荷,只放非敏感的用戶標(biāo)識(shí)(如userId、username)。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
public class LoginController {
    @Autowired
    private UserService userService; // 自定義用戶服務(wù)(校驗(yàn)賬號(hào)密碼)
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate; // Redis模板(分布式用)

    // 注入Cookie配置
    @Value("${cookie.name}")
    private String cookieName;
    @Value("${cookie.domain}")
    private String cookieDomain;
    @Value("${cookie.path}")
    private String cookiePath;
    @Value("${cookie.max-age}")
    private int cookieMaxAge;
    @Value("${cookie.http-only}")
    private boolean cookieHttpOnly;
    @Value("${cookie.secure}")
    private boolean cookieSecure;
    @Value("${cookie.same-site}")
    private String cookieSameSite;

    @PostMapping("/login")
    public Result login(@RequestBody LoginDTO loginDTO, HttpServletResponse response) {
        // 1. 校驗(yàn)賬號(hào)密碼(實(shí)際業(yè)務(wù)中要加密校驗(yàn),如BCrypt)
        User user = userService.verifyUser(loginDTO.getUsername(), loginDTO.getPassword());
        if (user == null) {
            return Result.fail("賬號(hào)或密碼錯(cuò)誤");
        }

        // 2. 生成JWT Token(載荷放userId和username,非敏感信息)
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("username", user.getUsername());
        String token = jwtUtil.generateToken(claims);

        // 3. (分布式必做)將Token存入Redis(可選,用于黑名單校驗(yàn))
        // redisTemplate.opsForValue().set("auto_login:blacklist:" + token, user.getId(), jwtUtil.getExpire(), TimeUnit.MILLISECONDS);

        // 4. 生成Cookie,返回給客戶端
        Cookie cookie = new Cookie(cookieName, token);
        cookie.setDomain(cookieDomain);
        cookie.setPath(cookiePath);
        cookie.setMaxAge(cookieMaxAge); // 7天過期
        cookie.setHttpOnly(cookieHttpOnly); // 防XSS
        cookie.setSecure(cookieSecure); // 生產(chǎn)環(huán)境HTTPS開啟
        cookie.setAttribute("SameSite", cookieSameSite); // 防CSRF
        response.addCookie(cookie);

        return Result.success("登錄成功");
    }
}

4. 第四步:攔截器校驗(yàn)憑證(自動(dòng)登錄核心)

用戶后續(xù)訪問系統(tǒng)時(shí),瀏覽器會(huì)自動(dòng)攜帶Cookie中的Token。我們用Spring攔截器攔截所有請(qǐng)求,校驗(yàn)Token合法性——合法則放行,不合法則跳轉(zhuǎn)到登錄頁。

4.1 自定義攔截器

import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;

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

public class AutoLoginInterceptor implements HandlerInterceptor {
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Value("${cookie.name}")
    private String cookieName;
    @Value("${jwt.refresh-expire}")
    private long refreshExpire; // 1天內(nèi)活躍自動(dòng)續(xù)期

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 跳過登錄接口(避免攔截登錄請(qǐng)求)
        if (request.getRequestURI().contains("/login")) {
            return true;
        }

        // 2. 從Cookie中獲取Token
        String token = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookieName.equals(cookie.getName())) {
                    token = cookie.getValue();
                    break;
                }
            }
        }

        // 3. Token不存在,跳轉(zhuǎn)到登錄頁
        if (token == null) {
            response.sendRedirect("/login.html");
            return false;
        }

        // 4. 校驗(yàn)Token合法性(未過期+簽名正確)
        if (!jwtUtil.validateToken(token)) {
            response.sendRedirect("/login.html");
            return false;
        }

        // 5. (分布式必做)校驗(yàn)Token是否在黑名單(用戶退出登錄后失效)
        Boolean isBlack = redisTemplate.hasKey("auto_login:blacklist:" + token);
        if (Boolean.TRUE.equals(isBlack)) {
            response.sendRedirect("/login.html");
            return false;
        }

        // 6. 解析Token,獲取用戶信息,存入Request(后續(xù)業(yè)務(wù)可用)
        Claims claims = jwtUtil.parseToken(token);
        request.setAttribute("userId", claims.get("userId"));
        request.setAttribute("username", claims.get("username"));

        // 7. 活躍續(xù)期:如果Token剩余有效期小于1天,自動(dòng)刷新Token(提升用戶體驗(yàn))
        long remainTime = claims.getExpiration().getTime() - System.currentTimeMillis();
        if (remainTime < refreshExpire) {
            Map<String, Object> newClaims = new HashMap<>();
            newClaims.put("userId", claims.get("userId"));
            newClaims.put("username", claims.get("username"));
            String newToken = jwtUtil.generateToken(newClaims);

            // 更新Cookie中的Token
            Cookie newCookie = new Cookie(cookieName, newToken);
            newCookie.setDomain(request.getServerName());
            newCookie.setPath("/");
            newCookie.setMaxAge(cookieMaxAge);
            newCookie.setHttpOnly(true);
            newCookie.setSecure(false);
            newCookie.setAttribute("SameSite", "Lax");
            response.addCookie(newCookie);

            // 更新Redis中的Token(分布式必做)
            // redisTemplate.delete("auto_login:blacklist:" + token);
            // redisTemplate.opsForValue().set("auto_login:blacklist:" + newToken, claims.get("userId"), jwtUtil.getExpire(), TimeUnit.MILLISECONDS);
        }

        // 8. 校驗(yàn)通過,放行
        return true;
    }
}

4.2 注冊(cè)攔截器

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Resource
    private AutoLoginInterceptor autoLoginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(autoLoginInterceptor)
                .addPathPatterns("/**") // 攔截所有請(qǐng)求
                .excludePathPatterns("/login", "/login.html", "/static/**"); // 排除登錄頁和靜態(tài)資源
    }
}

5. 第五步:退出登錄(憑證失效)

用戶主動(dòng)退出登錄時(shí),需要清除客戶端的Cookie,同時(shí)將Token加入Redis黑名單(避免被盜用)。

@PostMapping("/logout")
public Result logout(HttpServletRequest request, HttpServletResponse response) {
    // 1. 從Cookie中獲取Token
    String token = null;
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if (cookieName.equals(cookie.getName())) {
                token = cookie.getValue();
                break;
            }
        }
    }

    // 2. 將Token加入Redis黑名單(分布式必做)
    if (token != null) {
        // 黑名單有效期和Token一致
        redisTemplate.opsForValue().set("auto_login:blacklist:" + token, 
                request.getAttribute("userId"), 
                jwtUtil.getExpire(), 
                TimeUnit.MILLISECONDS);
    }

    // 3. 清除Cookie(設(shè)置maxAge=0)
    Cookie cookie = new Cookie(cookieName, null);
    cookie.setDomain(cookieDomain);
    cookie.setPath(cookiePath);
    cookie.setMaxAge(0); // 立即過期
    cookie.setHttpOnly(true);
    cookie.setSecure(false);
    cookie.setAttribute("SameSite", "Lax");
    response.addCookie(cookie);

    return Result.success("退出成功");
}

三、高級(jí)開發(fā)必關(guān)注:安全防護(hù)細(xì)節(jié)

七天免登錄的核心風(fēng)險(xiǎn)是“憑證被盜用”,一旦Token被別人獲取,就能直接登錄用戶賬號(hào)。作為高級(jí)開發(fā),必須做好以下5點(diǎn)防護(hù):

1. Cookie安全屬性必須設(shè)對(duì)

  • HttpOnly=true:禁止JavaScript操作Cookie,防止XSS攻擊竊取Token;
  • Secure=true:僅在HTTPS協(xié)議下傳輸Cookie,避免HTTP協(xié)議被抓包竊??;
  • SameSite=Lax:限制Cookie僅在同站點(diǎn)請(qǐng)求中攜帶,防止CSRF攻擊;
  • Domain和Path精準(zhǔn)配置:不要設(shè)為頂級(jí)域名(如.com),避免Cookie被同域名下的其他應(yīng)用獲取。

2. JWT密鑰不能硬編碼

JWT的安全性依賴于密鑰,必須將密鑰放在配置中心(如Nacos、Apollo),禁止硬編碼在代碼里。密鑰長度至少32位,建議用隨機(jī)字符串生成(如UUID)。

3. 分布式環(huán)境必須用Redis黑名單

JWT本身是無狀態(tài)的,一旦生成無法主動(dòng)失效。用戶退出登錄后,必須將Token加入Redis黑名單,攔截器校驗(yàn)時(shí)先查黑名單,避免Token被復(fù)用。

4. 載荷不存敏感信息

JWT的載荷是Base64編碼的,不是加密的,任何人都能解碼查看。因此不能存放密碼、手機(jī)號(hào)、身份證等敏感信息,只放userId、username等非敏感標(biāo)識(shí)。

5. 可選:結(jié)合設(shè)備/IP驗(yàn)證

如果業(yè)務(wù)安全性要求高,可以在生成Token時(shí),將用戶的設(shè)備信息(如瀏覽器版本、系統(tǒng)版本)、IP地址存入載荷。校驗(yàn)時(shí)對(duì)比當(dāng)前請(qǐng)求的設(shè)備/IP,不一致則拒絕登錄(注意:IP可能動(dòng)態(tài)變化,需平衡安全性和用戶體驗(yàn))。

四、避坑指南:工作中常見問題解決

結(jié)合實(shí)際開發(fā)經(jīng)驗(yàn),我總結(jié)了3個(gè)常見坑,幫你快速避坑:

坑1:免登錄在分布式環(huán)境下失效

原因:不同服務(wù)節(jié)點(diǎn)生成的Token不同,或者Cookie沒有共享。

解決方案:

  • 所有服務(wù)使用相同的JWT密鑰(配置中心統(tǒng)一配置);
  • Cookie的Domain設(shè)為服務(wù)的統(tǒng)一域名(如api.xxx.com);
  • 用Redis統(tǒng)一存儲(chǔ)Token黑名單,所有服務(wù)共享黑名單。

坑2:Token過期前用戶活躍,卻被要求重新登錄

原因:沒有做活躍續(xù)期,Token到期后直接失效。

解決方案:在攔截器中判斷Token剩余有效期,小于1天(或其他閾值)時(shí),自動(dòng)生成新Token并更新Cookie,實(shí)現(xiàn)“無縫續(xù)期”。

坑3:Cookie跨域無法攜帶

原因:前后端分離項(xiàng)目中,前端和后端域名不同,Cookie跨域不攜帶。

解決方案:

  • 后端配置CORS,允許前端域名的跨域請(qǐng)求,同時(shí)設(shè)置allowCredentials=true;
  • 前端請(qǐng)求時(shí)設(shè)置withCredentials=true(如Axios、Fetch);
  • Cookie的Domain設(shè)為后端域名,確??缬蛘?qǐng)求時(shí)能攜帶。

五、總結(jié)

七天免登錄的核心實(shí)現(xiàn)邏輯很簡(jiǎn)單:登錄生成JWT Token→Cookie存儲(chǔ)→攔截器校驗(yàn)→活躍續(xù)期→退出加入黑名單。但關(guān)鍵在于“安全”和“兼容性”——既要防止Token被盜用,又要保證分布式環(huán)境下正常工作,還要兼顧用戶體驗(yàn)。

本文給出的方案是工作中的標(biāo)準(zhǔn)實(shí)現(xiàn),代碼可直接落地。核心要點(diǎn)總結(jié):

  1. 用JWT生成帶簽名和過期時(shí)間的憑證,避免偽造;
  2. 用Cookie存儲(chǔ)憑證,開啟HttpOnly、Secure等安全屬性;
  3. 用攔截器統(tǒng)一校驗(yàn)憑證,實(shí)現(xiàn)自動(dòng)登錄;
  4. 分布式環(huán)境必須用Redis維護(hù)黑名單,解決JWT無法主動(dòng)失效的問題;
  5. 做好活躍續(xù)期,提升用戶體驗(yàn)。

以上就是基于SpringBoot實(shí)現(xiàn)七天免登錄的完整流程的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot七天免登錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JVM雙親委派模型知識(shí)詳細(xì)總結(jié)

    JVM雙親委派模型知識(shí)詳細(xì)總結(jié)

    今天帶各位小伙伴學(xué)習(xí)Java虛擬機(jī)的相關(guān)知識(shí),文中對(duì)JVM雙親委派模型作了非常詳細(xì)的介紹,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • Java?file類中renameTo方法操作實(shí)例

    Java?file類中renameTo方法操作實(shí)例

    renameTo()方法是File類的一部分,renameTo()函數(shù)用于將文件的抽象路徑名重命名為給定的路徑名??,下面這篇文章主要給大家介紹了關(guān)于Java?file類中renameTo方法操作的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Spring實(shí)戰(zhàn)之ResourceLoaderAware加載資源用法示例

    Spring實(shí)戰(zhàn)之ResourceLoaderAware加載資源用法示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之ResourceLoaderAware加載資源用法,結(jié)合實(shí)例形式分析了spring使用ResourceLoaderAware加載資源相關(guān)配置與操作技巧,需要的朋友可以參考下
    2020-01-01
  • hibernate4快速入門實(shí)例詳解

    hibernate4快速入門實(shí)例詳解

    Hibernate是一個(gè)輕量級(jí)的ORMapping框架,本文重點(diǎn)給大家介紹hibernate4 入門實(shí)例詳細(xì),需要的朋友參考下吧
    2017-09-09
  • Java 實(shí)戰(zhàn)項(xiàng)目之精美物流管理系統(tǒng)的實(shí)現(xiàn)流程

    Java 實(shí)戰(zhàn)項(xiàng)目之精美物流管理系統(tǒng)的實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Vue+maven+Mysql實(shí)現(xiàn)一個(gè)精美的物流管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • 如何取消IDEA中的項(xiàng)目和Git倉庫的關(guān)聯(lián)

    如何取消IDEA中的項(xiàng)目和Git倉庫的關(guān)聯(lián)

    這篇文章介紹了一種取消已經(jīng)開啟代碼控制的項(xiàng)目與Git倉庫關(guān)聯(lián)的簡(jiǎn)單方法,首先,在IntelliJ IDEA中打開項(xiàng)目,刪除.idea目錄下的vcs.xml文件,這樣IDE界面上的Git圖標(biāo)就會(huì)消失,接下來,打開項(xiàng)目所在位置,通過文件管理器啟用“顯示隱藏的項(xiàng)目”選項(xiàng)
    2024-10-10
  • Struts2學(xué)習(xí)教程之Action類如何訪問WEB資源

    Struts2學(xué)習(xí)教程之Action類如何訪問WEB資源

    這篇文章主要給大家介紹了關(guān)于Struts2學(xué)習(xí)教程之Action類如何訪問WEB資源的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • springboot+maven快速構(gòu)建項(xiàng)目的示例代碼

    springboot+maven快速構(gòu)建項(xiàng)目的示例代碼

    本篇文章主要介紹了springboot+maven快速構(gòu)建項(xiàng)目的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java實(shí)現(xiàn)簡(jiǎn)單音樂播放器

    java實(shí)現(xiàn)簡(jiǎn)單音樂播放器

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單音樂播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決

    SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決

    這篇文章主要介紹了SpringBoot啟動(dòng)yaml報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論

平度市| 凌海市| 资溪县| 株洲市| 双桥区| 包头市| 都昌县| 双流县| 宿迁市| 上饶县| 宜阳县| 尉氏县| 吴桥县| 游戏| 苏尼特右旗| 佳木斯市| 堆龙德庆县| 东山县| 柳江县| 屏东市| 会昌县| 静宁县| 祁连县| 安康市| 翁牛特旗| 沁阳市| 政和县| 吉林市| 赣榆县| 株洲县| 昌黎县| 酉阳| 阜平县| 慈溪市| 克什克腾旗| 卓尼县| 望都县| 闽清县| 闻喜县| 韩城市| 宜兰市|