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

Spring Security自定義用戶名密碼登錄頁面全過程

 更新時間:2026年06月12日 14:34:46   作者:知遠漫談  
這篇文章主要介紹了Spring Security自定義用戶名密碼登錄頁面全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

在現(xiàn)代 Web 應用開發(fā)中,安全性是不可忽視的重要環(huán)節(jié)。Spring Security 作為 Spring 生態(tài)中最成熟、最廣泛使用的安全框架,為開發(fā)者提供了強大的認證(Authentication)與授權(quán)(Authorization)能力。默認情況下,Spring Security 會提供一個自動生成的登錄頁面,但在實際項目中,我們幾乎總是需要根據(jù)業(yè)務需求和 UI/UX 設計,定制屬于自己的登錄界面。

本文將深入探討如何在 Spring Boot 項目中使用 Spring Security 實現(xiàn)完全自定義的用戶名密碼登錄頁面。我們將從基礎配置開始,逐步構(gòu)建一個完整的登錄流程,涵蓋表單設計、后端處理、錯誤提示、記住我功能、CSRF 防護、登錄成功/失敗跳轉(zhuǎn)策略等核心內(nèi)容,并通過代碼示例和流程圖幫助你徹底掌握這一關(guān)鍵技能。

為什么需要自定義登錄頁面?

默認的 Spring Security 登錄頁面雖然功能完整,但存在以下問題:

  • 外觀簡陋:無法匹配企業(yè)級應用的 UI 風格;
  • 響應式缺失:不支持移動端適配;
  • 多語言困難:難以集成國際化(i18n);
  • 擴展性差:無法添加驗證碼、第三方登錄等額外功能;
  • 安全細節(jié)暴露:默認路徑和參數(shù)可能被攻擊者利用。

因此,自定義登錄頁面不僅是美觀需求,更是安全性和用戶體驗的必要實踐。

小知識:Spring Security 的默認登錄頁面路徑是 /login,提交表單的 action 是 /login,用戶名字段為 username,密碼字段為 password。這些都可以被覆蓋。

項目初始化

我們使用 Spring Boot 3.x(基于 Jakarta EE 9+,使用 jakarta.* 包而非 javax.*)來搭建項目。確保你的開發(fā)環(huán)境已安裝 JDK 17+ 和 Maven/Gradle。

依賴配置(Maven)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity6</artifactId>
    </dependency>
</dependencies>

Thymeleaf 官方文檔 提供了與 Spring Security 集成的詳細說明。

基礎安全配置

首先,我們需要禁用 Spring Security 的默認登錄頁面,并指定我們自己的登錄頁面路徑。

創(chuàng)建 SecurityConfig 類

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/login", "/css/**", "/js/**", "/images/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")          // 指定自定義登錄頁
                .loginProcessingUrl("/do-login") // 表單提交地址
                .usernameParameter("username")   // 用戶名參數(shù)名
                .passwordParameter("password")   // 密碼參數(shù)名
                .defaultSuccessUrl("/dashboard", true) // 登錄成功后跳轉(zhuǎn)
                .failureUrl("/login?error=true")     // 登錄失敗跳轉(zhuǎn)
                .permitAll()
            )
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout=true")
                .permitAll()
            );

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("123456")
            .roles("USER")
            .build();

        return new InMemoryUserDetailsManager(user);
    }
}

注意:User.withDefaultPasswordEncoder() 僅用于演示!生產(chǎn)環(huán)境必須使用強哈希算法(如 BCrypt)。

自定義登錄頁面(Thymeleaf)

我們在 src/main/resources/templates 目錄下創(chuàng)建 login.html 文件。

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="UTF-8">
    <title>用戶登錄</title>
    <link rel="stylesheet" th:href="@{/css/login.css}" rel="external nofollow" >
</head>
<body>
<div class="login-container">
    <h2>系統(tǒng)登錄</h2>
    <!-- 錯誤信息提示 -->
    <div th:if="${param.error}" class="alert alert-error">
        用戶名或密碼錯誤,請重試!
    </div>
    <!-- 成功登出提示 -->
    <div th:if="${param.logout}" class="alert alert-success">
        您已成功退出系統(tǒng)。
    </div>
    <form th:action="@{/do-login}" method="post">
        <!-- CSRF Token 自動注入 -->
        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
        <div class="form-group">
            <label for="username">用戶名</label>
            <input type="text" id="username" name="username" required autofocus/>
        </div>
        <div class="form-group">
            <label for="password">密碼</label>
            <input type="password" id="password" name="password" required/>
        </div>
        <div class="form-group remember-me">
            <input type="checkbox" id="remember-me" name="remember-me"/>
            <label for="remember-me">記住我</label>
        </div>
        <button type="submit">登錄</button>
    </form>
</div>
</body>
</html>

關(guān)鍵點說明

  • th:action="@{/do-login}":表單提交到 /do-login,與 loginProcessingUrl 一致;
  • CSRF Token 通過 Thymeleaf 自動注入,防止跨站請求偽造;
  • name="remember-me" 是 Spring Security “記住我”功能的默認參數(shù)名;
  • 使用 param.errorparam.logout 獲取 URL 參數(shù)以顯示提示。

靜態(tài)資源處理

為了讓登錄頁面樣式正常加載,需在 SecurityConfig 中放行靜態(tài)資源路徑:

.requestMatchers("/login", "/css/**", "/js/**", "/images/**", "/favicon.ico").permitAll()

并在 src/main/resources/static/css 下創(chuàng)建 login.css

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}
.login-container {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    width: 300px;
}
.form-group {
    margin-bottom: 1rem;
}
.form-group label {
    display: block;
    margin-bottom: 0.5rem;
}
.form-group input {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}
.remember-me {
    display: flex;
    align-items: center;
}
.remember-me input[type="checkbox"] {
    margin-right: 0.5rem;
}
button {
    width: 100%;
    padding: 0.75rem;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
button:hover {
    background-color: #0056b3;
}
.alert {
    padding: 0.75rem;
    margin-bottom: 1rem;
    border-radius: 4px;
}
.alert-error {
    background-color: #f8d7da;
    color: #721c24;
}
.alert-success {
    background-color: #d4edda;
    color: #155724;
}

登錄流程解析

理解 Spring Security 的登錄流程對調(diào)試和擴展至關(guān)重要。

關(guān)鍵組件說明

  • UsernamePasswordAuthenticationFilter:負責攔截 /do-login 請求;
  • UserDetailsService:加載用戶信息(可對接數(shù)據(jù)庫);
  • AuthenticationProvider:驗證密碼是否匹配;
  • 成功/失敗處理器決定跳轉(zhuǎn)邏輯。

實現(xiàn)數(shù)據(jù)庫用戶認證

前面我們使用了內(nèi)存用戶,現(xiàn)在將其替換為數(shù)據(jù)庫查詢。

1. 添加 JPA 依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

2. 創(chuàng)建 User 實體

import jakarta.persistence.*;

@Entity
@Table(name = "users")
public class AppUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    private String username;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private boolean enabled = true;

    // getters and setters
}

3. 創(chuàng)建 UserRepository

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<AppUser, Long> {
    AppUser findByUsername(String username);
}

4. 自定義 UserDetailsService

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public CustomUserDetailsService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        AppUser user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用戶不存在: " + username);
        }

        return org.springframework.security.core.userdetails.User.builder()
            .username(user.getUsername())
            .password(user.getPassword()) // 已加密
            .authorities("ROLE_USER")
            .accountExpired(false)
            .accountLocked(false)
            .credentialsExpired(false)
            .disabled(!user.isEnabled())
            .build();
    }
}

5. 更新 SecurityConfig

移除 userDetailsService() 方法,注入 CustomUserDetailsService

@Autowired
private CustomUserDetailsService customUserDetailsService;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // ... 其他配置不變
    http.userDetailsService(customUserDetailsService);
    return http.build();
}

6. 密碼編碼器配置

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

安全建議:永遠不要存儲明文密碼!BCrypt 是目前推薦的密碼哈希算法。

處理登錄成功與失敗

Spring Security 允許我們自定義登錄成功和失敗的行為,而不僅僅是跳轉(zhuǎn)。

自定義成功處理器

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        // 可記錄日志、更新最后登錄時間等
        System.out.println("用戶 " + authentication.getName() + " 登錄成功");

        // 默認跳轉(zhuǎn)
        response.sendRedirect("/dashboard");
    }
}

自定義失敗處理器

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        System.out.println("登錄失敗: " + exception.getMessage());

        // 可記錄失敗次數(shù)、鎖定賬戶等
        response.sendRedirect("/login?error=" + exception.getClass().getSimpleName());
    }
}

在 SecurityConfig 中注冊

@Autowired
private CustomAuthenticationSuccessHandler successHandler;

@Autowired
private CustomAuthenticationFailureHandler failureHandler;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .formLogin(form -> form
            .loginPage("/login")
            .loginProcessingUrl("/do-login")
            .successHandler(successHandler)
            .failureHandler(failureHandler)
            .permitAll()
        );
    // ...
}

應用場景

  • 成功時記錄 IP、設備信息;
  • 失敗時限制嘗試次數(shù),防止暴力.破 解;
  • 根據(jù)角色跳轉(zhuǎn)不同首頁。

“記住我”功能實現(xiàn)

“記住我”允許用戶在關(guān)閉瀏覽器后仍保持登錄狀態(tài)(通常通過持久化 Cookie 實現(xiàn))。

1. 數(shù)據(jù)庫表結(jié)構(gòu)

CREATE TABLE persistent_logins (
    username VARCHAR(64) NOT NULL,
    series VARCHAR(64) PRIMARY KEY,
    token VARCHAR(64) NOT NULL,
    last_used TIMESTAMP NOT NULL
);

2. 配置 RememberMeServices

@Bean
public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(dataSource);
    // 自動建表(僅首次)
    // tokenRepository.setCreateTableOnStartup(true);
    return tokenRepository;
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .rememberMe(remember -> remember
            .key("myAppKey") // 必須設置,用于加密
            .tokenRepository(persistentTokenRepository())
            .tokenValiditySeconds(7 * 24 * 3600) // 7天
            .userDetailsService(customUserDetailsService)
        );
    // ...
}

原理:登錄時勾選“記住我”,服務器生成 seriestoken 存入數(shù)據(jù)庫,并設置 Cookie。下次訪問時,通過 Cookie 中的憑證自動登錄。

CSRF 防護與自定義表單

Spring Security 默認啟用 CSRF(跨站請求偽造)防護,要求每個修改狀態(tài)的請求(POST/PUT/DELETE)攜帶有效的 CSRF Token。

在 Thymeleaf 表單中,我們通過以下方式自動注入:

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>

如果你使用的是純 HTML 或 AJAX,需手動處理:

AJAX 示例(JavaScript)

// 從 meta 標簽獲取 CSRF Token
var csrfToken = document.querySelector("meta[name='_csrf']").getAttribute("content");
var csrfHeader = document.querySelector("meta[name='_csrf_header']").getAttribute("content");
// 發(fā)送請求時添加 Header
fetch('/do-login', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        [csrfHeader]: csrfToken
    },
    body: 'username=admin&password=123456'
});

對應的 HTML 需添加:

<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

重要:不要禁用 CSRF!除非你明確知道自己在做什么(如 REST API 使用 JWT)。

國際化(i18n)支持

為了讓登錄頁面支持多語言,我們可以集成 Spring 的 MessageSource。

1. 創(chuàng)建 messages.properties

# src/main/resources/messages.properties
login.title=用戶登錄
login.username=用戶名
login.password=密碼
login.remember=記住我
login.button=登錄
error.bad.credentials=用戶名或密碼錯誤

2. messages_zh_CN.properties

login.title=用戶登錄
login.username=用戶名
login.password=密碼
login.remember=記住我
login.button=登錄
error.bad.credentials=用戶名或密碼錯誤

3. 在 Thymeleaf 中使用

<h2 th:text="#{login.title}">用戶登錄</h2>
<label for="username" th:text="#{login.username}">用戶名</label>
<!-- 其他類似 -->
<div th:if="${param.error}" class="alert alert-error" th:text="#{error.bad.credentials}"></div>

4. 配置 LocaleResolver

@Bean
public LocaleResolver localeResolver() {
    AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
    resolver.setDefaultLocale(Locale.CHINA);
    return resolver;
}

提示:瀏覽器通過 Accept-Language 頭自動選擇語言。

登錄驗證碼集成(可選)

雖然 Spring Security 本身不提供驗證碼,但我們可以輕松集成。

1. 添加 Kaptcha 依賴(示例)

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

2. 配置 Kaptcha

@Bean
public DefaultKaptcha kaptcha() {
    DefaultKaptcha kaptcha = new DefaultKaptcha();
    Properties props = new Properties();
    props.setProperty("kaptcha.border", "no");
    props.setProperty("kaptcha.textproducer.font.color", "black");
    props.setProperty("kaptcha.textproducer.char.space", "10");
    kaptcha.setConfig(new Config(props));
    return kaptcha;
}

3. 驗證碼 Controller

@GetMapping("/captcha")
public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    String capText = kaptcha.createText();
    request.getSession().setAttribute("captcha", capText);
    BufferedImage image = kaptcha.createImage(capText);
    ImageIO.write(image, "jpg", response.getOutputStream());
}

4. 修改登錄表單

<img th:src="@{/captcha}" onclick="this.src='/captcha?' + Math.random()" alt="驗證碼"/>
<input type="text" name="captcha" placeholder="請輸入驗證碼" required/>

5. 自定義 AuthenticationFilter

繼承 UsernamePasswordAuthenticationFilter,在 attemptAuthentication 中校驗驗證碼。

注意:驗證碼校驗應在密碼校驗之前,避免無效請求消耗資源。

常見問題與調(diào)試技巧

1. 登錄后無限重定向

原因:defaultSuccessUrl 指向的頁面未放行,導致再次跳轉(zhuǎn)到登錄頁。

? 解決:確保 /dashboardauthenticated() 保護,且用戶有權(quán)限訪問。

2. CSRF Token 無效

現(xiàn)象:提交表單報 403 Forbidden。

? 檢查:

  • 表單是否包含 <input type="hidden" th:name="${_csrf.parameterName}" ... />
  • 是否使用了正確的 POST 方法;
  • Session 是否過期(Token 綁定 Session)。

3. 密碼不匹配

? 檢查:

  • 數(shù)據(jù)庫存儲的密碼是否經(jīng)過 BCrypt 加密;
  • PasswordEncoder 是否與加密時一致;
  • 不要使用 User.withDefaultPasswordEncoder()。

4. 日志調(diào)試

application.properties 中開啟安全日志:

logging.level.org.springframework.security=DEBUG

安全最佳實踐

強制 HTTPS:生產(chǎn)環(huán)境務必使用 HTTPS,防止密碼嗅探。

http.requiresChannel(channel -> channel.anyRequest().requiresSecure());
  1. 密碼策略:前端+后端雙重校驗(長度、復雜度)。

  2. 賬戶鎖定:多次失敗后臨時鎖定(可通過 DaoAuthenticationProvider 擴展)。

Session 管理

http.sessionManagement(session -> session
    .maximumSessions(1)
    .expiredUrl("/login?expired=true")
);

安全頭設置

http.headers(headers -> headers
    .frameOptions().deny()
    .contentTypeOptions().and()
    .xssProtection().and()
    .cacheControl()
);

OWASP Top 10 是 Web 安全的權(quán)威指南,值得每位開發(fā)者閱讀。

總結(jié)

通過本文,我們系統(tǒng)地學習了如何在 Spring Security 中實現(xiàn)完全自定義的用戶名密碼登錄頁面。從基礎配置、頁面設計、數(shù)據(jù)庫集成,到高級功能如“記住我”、CSRF 防護、國際化和驗證碼,每一步都配有可運行的代碼示例。

自定義登錄頁面不僅是 UI 的替換,更是安全架構(gòu)的重要組成部分。合理的錯誤處理、日志記錄、會話管理和輸入驗證,能顯著提升應用的安全性與用戶體驗。

記?。?strong>安全不是功能,而是持續(xù)的過程。隨著業(yè)務發(fā)展,不斷審視和加固你的認證機制,才能抵御日益復雜的網(wǎng)絡威脅。

下一步建議

  • 集成 OAuth2 / 微信登錄;
  • 實現(xiàn)多因素認證(MFA);
  • 使用 JWT 替代表單登錄(適用于前后端分離)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot整合通用Mapper簡化單表操作詳解

    springboot整合通用Mapper簡化單表操作詳解

    這篇文章主要介紹了springboot整合通用Mapper簡化單表操作,通用Mapper是一個基于Mybatis,將單表的增刪改查通過通用方法實現(xiàn),來減少SQL編寫的開源框架,需要的朋友可以參考下
    2019-06-06
  • Java注解的簡單入門小案例

    Java注解的簡單入門小案例

    這篇文章主要介紹了Java注解的簡單入門小案例,注解是干什么的?怎么使用?注解的簡單用法,需要的朋友可以參考下
    2023-04-04
  • 使用原生JDBC動態(tài)解析并獲取表格列名和數(shù)據(jù)的方法

    使用原生JDBC動態(tài)解析并獲取表格列名和數(shù)據(jù)的方法

    這篇文章主要介紹了使用原生JDBC動態(tài)解析并獲取表格列名和數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • 詳解使用spring cloud config來統(tǒng)一管理配置文件

    詳解使用spring cloud config來統(tǒng)一管理配置文件

    這篇文章主要介紹了詳解使用spring cloud config來統(tǒng)一管理配置文件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java中工具Jstack的使用實例

    Java中工具Jstack的使用實例

    jstack用于生成java虛擬機當前時刻的線程快照,下面這篇文章主要給大家介紹了關(guān)于Java中工具Jstack使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • Quarkus的Spring擴展快速改造Spring項目

    Quarkus的Spring擴展快速改造Spring項目

    這篇文章主要為大家介紹了Quarkus的Spring項目擴展,帶大家快速改造Spring項目示例演繹,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02
  • Java解析照片拿到GPS位置數(shù)據(jù)的詳細步驟

    Java解析照片拿到GPS位置數(shù)據(jù)的詳細步驟

    這篇文章主要介紹了Java解析照片拿到GPS位置數(shù)據(jù),本文給大家介紹代碼環(huán)境及核心代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • java 裝飾模式(Decorator Pattern)詳解

    java 裝飾模式(Decorator Pattern)詳解

    這篇文章主要介紹了java 裝飾模式(Decorator Pattern)詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Java?Bean?Validation使用示例詳解

    Java?Bean?Validation使用示例詳解

    這篇文章主要為大家介紹了Java?Bean?Validation的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 基于springioc bean 的幾個屬性介紹

    基于springioc bean 的幾個屬性介紹

    下面小編就為大家?guī)硪黄趕pringioc bean 的幾個屬性介紹。小編覺得挺不錯的,現(xiàn)在就想給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論

阿巴嘎旗| 图们市| 郑州市| 喜德县| 沙雅县| 吉木萨尔县| 高青县| 亚东县| 阿克苏市| 隆安县| 饶平县| 增城市| 怀化市| 三明市| 德惠市| 裕民县| 星座| 文安县| 大同市| 苗栗市| 双峰县| 松原市| 宁陕县| 韩城市| 辰溪县| 赤峰市| 富平县| 屏山县| 泊头市| 新田县| 棋牌| 丹凤县| 武城县| 嘉义市| 湘乡市| 龙井市| 广汉市| 喀喇沁旗| 双桥区| 塔城市| 鄂托克旗|