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

基于SpringBoot + Android實(shí)現(xiàn)登錄功能

 更新時(shí)間:2024年11月26日 08:52:14   作者:繁依Fanyi  
在移動(dòng)互聯(lián)網(wǎng)的今天,許多應(yīng)用需要通過移動(dòng)端實(shí)現(xiàn)與服務(wù)器的交互功能,其中登錄是最常見且基礎(chǔ)的一種功能,本篇博客將詳細(xì)介紹如何使用 Spring Boot 和 Android 實(shí)現(xiàn)一個(gè)完整的登錄功能,需要的朋友可以參考下

引言

在移動(dòng)互聯(lián)網(wǎng)的今天,許多應(yīng)用需要通過移動(dòng)端實(shí)現(xiàn)與服務(wù)器的交互功能,其中登錄是最常見且基礎(chǔ)的一種功能。通過登錄,用戶可以獲得獨(dú)特的身份標(biāo)識(shí),從而訪問特定的資源或服務(wù)。本篇博客將詳細(xì)介紹如何使用 Spring Boot 和 Android 實(shí)現(xiàn)一個(gè)完整的登錄功能,從后端 API 的構(gòu)建到 Android 端的交互,旨在為讀者提供一套完整的解決方案。

1. 簡(jiǎn)單分析

在討論如何實(shí)現(xiàn)登錄功能之前,我們需要明確需求。通常情況下,登錄功能會(huì)包含以下幾個(gè)需求:

  • 用戶登錄:用戶通過輸入用戶名(或手機(jī)號(hào)、郵箱)和密碼進(jìn)行登錄。
  • 身份驗(yàn)證:服務(wù)器需要驗(yàn)證用戶身份是否合法,是否擁有訪問權(quán)限。
  • Token 授權(quán):為了避免頻繁的登錄操作,服務(wù)器可以返回一個(gè) token,客戶端持有該 token 后,能夠在一段時(shí)間內(nèi)免除再次登錄。
  • 安全性:需要防止常見的攻擊手段,如密碼泄露、暴力 破解等。

在本項(xiàng)目中,我們將采用基于 JWT(JSON Web Token) 的方式來實(shí)現(xiàn)無狀態(tài)的登錄功能,Spring Boot 作為后端框架,Android 作為前端實(shí)現(xiàn)登錄頁面及 Token 管理。

2. 項(xiàng)目環(huán)境配置

2.1 后端:Spring Boot 配置

首先,我們需要在后端使用 Spring Boot 作為服務(wù)端框架,選擇 Spring Security 進(jìn)行用戶身份驗(yàn)證,并使用 JWT 實(shí)現(xiàn)無狀態(tài)的登錄管理。

  1. 創(chuàng)建 Spring Boot 項(xiàng)目
    可以通過 Spring Initializr 快速生成項(xiàng)目骨架,選擇如下依賴:

    • Spring Web
    • Spring Security
    • Spring Data JPA
    • MySQL(或其他數(shù)據(jù)庫)
    • JWT(通過 Maven 手動(dòng)引入依賴)
  2. JWT 依賴引入
    在 pom.xml 文件中添加 JWT 的依賴:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
</dependency>

2.2 前端:Android 項(xiàng)目配置

在 Android 中,我們可以使用 Retrofit 作為網(wǎng)絡(luò)請(qǐng)求庫,并通過 SharedPreferences 來存儲(chǔ) token 信息。

  • Retrofit 依賴引入
    在 Android 項(xiàng)目的 build.gradle 文件中添加 Retrofit 及其相關(guān)依賴:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  • 設(shè)計(jì)用戶登錄界面登錄界面是用戶進(jìn)行身份驗(yàn)證的入口,通常包含用戶名(或手機(jī)號(hào))、密碼輸入框,以及登錄按鈕。

3. Spring Boot 后端開發(fā)

在這一部分,我們將重點(diǎn)介紹后端的開發(fā),首先從用戶模型的設(shè)計(jì)開始,然后是 Spring Security 的配置,接著是 JWT 的集成與登錄 API 的實(shí)現(xiàn)。

3.1 用戶模型設(shè)計(jì)

為了保存用戶信息,我們首先需要設(shè)計(jì)一個(gè)用戶模型。在這里,我們使用 JPA(Java Persistence API)來定義用戶實(shí)體,并將其持久化到數(shù)據(jù)庫中。

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String email;
    
    // other fields, getters and setters
}

同時(shí),使用 UserRepository 進(jìn)行數(shù)據(jù)操作:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

3.2 Spring Security 配置

Spring Security 是 Spring 框架提供的強(qiáng)大的安全管理模塊。在這里,我們需要對(duì) Spring Security 進(jìn)行配置,使其與 JWT 配合使用,來實(shí)現(xiàn)無狀態(tài)的身份驗(yàn)證。

3.2.1 安全配置類

創(chuàng)建一個(gè) SecurityConfig 類,用于配置 Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
            .passwordEncoder(passwordEncoder());
    }

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

這里我們禁用了 CSRF 保護(hù),因?yàn)槲覀儗⑹褂?JWT 進(jìn)行身份驗(yàn)證。我們也配置了 jwtAuthenticationFilter,它將在每次請(qǐng)求時(shí)驗(yàn)證 JWT。

3.3 JWT 的集成

JWT 是一種用于在網(wǎng)絡(luò)應(yīng)用之間安全傳輸信息的緊湊令牌。每個(gè) JWT 都由三部分組成:Header、Payload 和 Signature。下面,我們來實(shí)現(xiàn)生成和解析 JWT 的邏輯。

3.3.1 JwtTokenUtil 工具類

創(chuàng)建一個(gè) JwtTokenUtil 工具類,用于生成和驗(yàn)證 JWT。

@Component
public class JwtTokenUtil {

    private static final String SECRET_KEY = "your_secret_key";

    public String generateToken(UserDetails userDetails) {
        return Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }

    private boolean isTokenExpired(String token) {
        final Date expiration = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getExpiration();
        return expiration.before(new Date());
    }
}

3.3.2 JwtAuthenticationFilter

JwtAuthenticationFilter 用于攔截請(qǐng)求并驗(yàn)證 token,確保只有經(jīng)過身份驗(yàn)證的用戶可以訪問受保護(hù)的資源。

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtTokenUtil.extractUsername(jwt);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwt, userDetails)) {

                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        filterChain.doFilter(request, response);
    }
}

3.4 登錄 API 實(shí)現(xiàn)

在服務(wù)器端,我們需要提供一個(gè)登錄的 API,用戶通過該 API 發(fā)送用戶名和密碼,服務(wù)器驗(yàn)證后生成 JWT 返回給客戶端。

@RestController
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @PostMapping("/login")
    public ResponseEntity<?> createAuthenticationToken

(@RequestBody AuthRequest authRequest) throws Exception {

        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
            );
        } catch (BadCredentialsException e) {
            throw new Exception("Incorrect username or password", e);
        }

        final UserDetails userDetails = userDetailsService
                .loadUserByUsername(authRequest.getUsername());

        final String jwt = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new AuthResponse(jwt));
    }
}

這里,AuthRequest 是用戶登錄時(shí)發(fā)送的請(qǐng)求對(duì)象,包含用戶名和密碼。而 AuthResponse 是服務(wù)器返回的響應(yīng)對(duì)象,包含生成的 JWT。

4. Android 前端開發(fā)

接下來,我們將在 Android 中實(shí)現(xiàn)登錄頁面,并與 Spring Boot 后端進(jìn)行交互。

4.1 使用 Retrofit 進(jìn)行網(wǎng)絡(luò)請(qǐng)求

Retrofit 是 Android 平臺(tái)上廣泛使用的網(wǎng)絡(luò)請(qǐng)求庫。首先,我們定義一個(gè)接口用于請(qǐng)求登錄 API。

public interface ApiService {

    @POST("login")
    Call<AuthResponse> login(@Body AuthRequest authRequest);
}

AuthRequest 類對(duì)應(yīng)后端的登錄請(qǐng)求體,AuthResponse 類則用來接收服務(wù)器返回的 JWT。

public class AuthRequest {
    private String username;
    private String password;

    // Constructor, getters and setters
}

public class AuthResponse {
    private String jwt;

    // Constructor, getters and setters
}

4.2 登錄頁面設(shè)計(jì)與實(shí)現(xiàn)

接下來,我們?cè)O(shè)計(jì)一個(gè)簡(jiǎn)單的登錄界面,包括兩個(gè) EditText 組件用于輸入用戶名和密碼,外加一個(gè) Button 進(jìn)行登錄操作。

<EditText
    android:id="@+id/etUsername"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Username" />

<EditText
    android:id="@+id/etPassword"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Password"
    android:inputType="textPassword" />

<Button
    android:id="@+id/btnLogin"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Login" />

在 MainActivity.java 中實(shí)現(xiàn)登錄邏輯:

public class MainActivity extends AppCompatActivity {

    private EditText etUsername;
    private EditText etPassword;
    private Button btnLogin;

    private ApiService apiService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etUsername = findViewById(R.id.etUsername);
        etPassword = findViewById(R.id.etPassword);
        btnLogin = findViewById(R.id.btnLogin);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://your-server-url/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        apiService = retrofit.create(ApiService.class);

        btnLogin.setOnClickListener(v -> login());
    }

    private void login() {
        String username = etUsername.getText().toString();
        String password = etPassword.getText().toString();

        AuthRequest authRequest = new AuthRequest(username, password);
        Call<AuthResponse> call = apiService.login(authRequest);

        call.enqueue(new Callback<AuthResponse>() {
            @Override
            public void onResponse(Call<AuthResponse> call, Response<AuthResponse> response) {
                if (response.isSuccessful()) {
                    String jwt = response.body().getJwt();
                    // Store JWT in SharedPreferences
                    SharedPreferences preferences = getSharedPreferences("my_prefs", MODE_PRIVATE);
                    preferences.edit().putString("jwt", jwt).apply();

                    // Navigate to another activity
                } else {
                    // Handle failure
                }
            }

            @Override
            public void onFailure(Call<AuthResponse> call, Throwable t) {
                // Handle network failure
            }
        });
    }
}

4.3 Token 的存儲(chǔ)和管理

為了在后續(xù)的請(qǐng)求中使用 JWT,我們可以將其存儲(chǔ)在 Android 的 SharedPreferences 中。這樣,用戶登錄后,應(yīng)用在關(guān)閉再打開時(shí)依然可以保持登錄狀態(tài)。

            (Call<AuthResponse> call, Response<AuthResponse> response) {
                if (response.isSuccessful()) {
                    AuthResponse authResponse = response.body();
                    String token = authResponse.getJwt();
                    
                    // Store the token using SharedPreferences
                    SharedPreferences sharedPreferences = getSharedPreferences("MyApp", MODE_PRIVATE);
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("JWT_TOKEN", token);
                    editor.apply();
                    
                    Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
                    
                    // Navigate to another activity after successful login
                    Intent intent = new Intent(MainActivity.this, DashboardActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(MainActivity.this, "Login failed", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<AuthResponse> call, Throwable t) {
                Toast.makeText(MainActivity.this, "Network error", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

在上面的代碼中,login() 方法負(fù)責(zé)發(fā)送登錄請(qǐng)求并處理服務(wù)器的響應(yīng)。如果登錄成功,我們將獲取到服務(wù)器返回的 JWT 并將其存儲(chǔ)在 SharedPreferences 中,以便在后續(xù)的請(qǐng)求中使用該 Token 進(jìn)行身份驗(yàn)證。

4.3 Token 的存儲(chǔ)和管理

為了保證用戶登錄后的身份驗(yàn)證,客戶端需要將服務(wù)器返回的 JWT 存儲(chǔ)起來。SharedPreferences 是 Android 中一種輕量級(jí)的數(shù)據(jù)存儲(chǔ)方式,非常適合保存類似于 Token 這樣的配置信息。

SharedPreferences sharedPreferences = getSharedPreferences("MyApp", MODE_PRIVATE);
String token = sharedPreferences.getString("JWT_TOKEN", null);

在需要身份驗(yàn)證的請(qǐng)求中,我們可以從 SharedPreferences 中讀取保存的 Token,并在請(qǐng)求頭中添加該 Token。

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(chain -> {
        Request originalRequest = chain.request();
        String token = sharedPreferences.getString("JWT_TOKEN", null);
        if (token != null) {
            Request newRequest = originalRequest.newBuilder()
                    .header("Authorization", "Bearer " + token)
                    .build();
            return chain.proceed(newRequest);
        }
        return chain.proceed(originalRequest);
    })
    .build();

通過上述代碼,所有發(fā)送的請(qǐng)求將攜帶 JWT,服務(wù)端能夠通過驗(yàn)證 Token 來判斷用戶是否具有訪問權(quán)限。

5. 完整登錄流程分析

  1. 用戶在 Android 客戶端輸入用戶名和密碼,點(diǎn)擊登錄按鈕。
  2. 客戶端發(fā)送 POST 請(qǐng)求到服務(wù)器的 /login 接口,請(qǐng)求體中包含用戶名和密碼。
  3. 服務(wù)器驗(yàn)證用戶的身份,如果驗(yàn)證成功,則生成 JWT 并返回給客戶端。
  4. 客戶端接收到 JWT 后,將其存儲(chǔ)在 SharedPreferences 中。
  5. 后續(xù)請(qǐng)求時(shí),客戶端將 JWT 附加在請(qǐng)求頭中,服務(wù)器根據(jù) JWT 來判斷用戶是否有權(quán)限訪問資源。

6. 安全性及優(yōu)化策略

6.1 HTTPS 加密傳輸

為了確保數(shù)據(jù)傳輸?shù)陌踩?,建議在實(shí)際項(xiàng)目中使用 HTTPS 進(jìn)行加密傳輸,避免用戶的敏感信息(如密碼)被竊取。

6.2 密碼加密存儲(chǔ)

在服務(wù)器端,用戶的密碼不應(yīng)該以明文形式存儲(chǔ)。通常,我們會(huì)使用 BCrypt 等加密算法對(duì)用戶密碼進(jìn)行加密后再存儲(chǔ)到數(shù)據(jù)庫中。

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

6.3 Token 的過期管理

JWT 通常會(huì)設(shè)置一個(gè)過期時(shí)間,以確保 Token 不會(huì)被長(zhǎng)期濫用??蛻舳嗽跈z測(cè)到 Token 過期時(shí),應(yīng)提示用戶重新登錄。

6.4 防止暴力 破解

為了防止惡意用戶通過暴力 破解獲取用戶密碼,建議在登錄接口上增加防護(hù)機(jī)制,如使用驗(yàn)證碼,或在多次登錄失敗后暫時(shí)鎖定用戶賬號(hào)。

7. 總結(jié)

本篇博客介紹了如何使用 Spring Boot 和 Android 實(shí)現(xiàn)一個(gè)完整的登錄功能。從用戶模型的設(shè)計(jì)、Spring Security 的配置、JWT 的集成,到 Android 客戶端的登錄頁面實(shí)現(xiàn)、網(wǎng)絡(luò)請(qǐng)求和 Token 管理,涵蓋了從后端到前端的所有關(guān)鍵步驟。登錄功能雖然看似簡(jiǎn)單,但其背后涉及的安全性和可擴(kuò)展性都是我們需要重點(diǎn)關(guān)注的。

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

相關(guān)文章

  • mybatis查詢語句揭秘之封裝數(shù)據(jù)

    mybatis查詢語句揭秘之封裝數(shù)據(jù)

    這篇文章主要給大家介紹了關(guān)于mybatis查詢語句揭秘之封裝數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringBoot中AOP的動(dòng)態(tài)匹配和靜態(tài)匹配詳解

    SpringBoot中AOP的動(dòng)態(tài)匹配和靜態(tài)匹配詳解

    這篇文章主要介紹了SpringBoot中AOP的動(dòng)態(tài)匹配和靜態(tài)匹配詳解,在創(chuàng)建代理的時(shí)候?qū)δ繕?biāo)類的每個(gè)連接點(diǎn)使用靜態(tài)切點(diǎn)檢查,如果僅通過靜態(tài)切點(diǎn)檢查就可以知道連接點(diǎn)是不匹配的,則在運(yùn)行時(shí)就不再進(jìn)行動(dòng)態(tài)檢查了,需要的朋友可以參考下
    2023-09-09
  • 使用eclipse 實(shí)現(xiàn)將springboot項(xiàng)目打成jar包

    使用eclipse 實(shí)現(xiàn)將springboot項(xiàng)目打成jar包

    這篇文章主要介紹了使用eclipse 實(shí)現(xiàn)將springboot項(xiàng)目打成jar包的流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解Java中格式化日期的DateFormat與SimpleDateFormat類

    詳解Java中格式化日期的DateFormat與SimpleDateFormat類

    DateFormat其本身是一個(gè)抽象類,SimpleDateFormat 類是DateFormat類的子類,一般情況下來講DateFormat類很少會(huì)直接使用,而都使用SimpleDateFormat類完成,下面我們具體來看一下兩個(gè)類的用法:
    2016-05-05
  • 一篇文章弄懂Mybatis中#和$的區(qū)別

    一篇文章弄懂Mybatis中#和$的區(qū)別

    mybatis為我們提供了兩種支持動(dòng)態(tài)sql的語法#{}以及${},兩者都是動(dòng)態(tài)的向sql語句中傳入需要的參數(shù),下面這篇文章主要給大家介紹了如何通過一篇文章弄懂Mybatis中#和$區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • Netty粘包拆包及使用原理詳解

    Netty粘包拆包及使用原理詳解

    Netty是由JBOSS提供的一個(gè)java開源框架,現(xiàn)為?Github上的獨(dú)立項(xiàng)目。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序,這篇文章主要介紹了Netty粘包拆包及使用原理
    2022-08-08
  • SpringBoot整合java診斷工具Arthas解讀

    SpringBoot整合java診斷工具Arthas解讀

    這篇文章主要介紹了SpringBoot整合java診斷工具Arthas,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 淺析git server“丟失”commit問題

    淺析git server“丟失”commit問題

    這篇文章主要介紹了git server“丟失”commit問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 沒有編輯器的環(huán)境下是如何創(chuàng)建Servlet(Tomcat+Java)項(xiàng)目的?

    沒有編輯器的環(huán)境下是如何創(chuàng)建Servlet(Tomcat+Java)項(xiàng)目的?

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著在沒有編輯器的環(huán)境下如何創(chuàng)建Servlet(Tomcat+Java)項(xiàng)目展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Springboot apollo原理及使用方法詳解

    Springboot apollo原理及使用方法詳解

    這篇文章主要介紹了Springboot apollo原理及使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06

最新評(píng)論