精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringBoot與Apache Ignite整合,實現廣告實時競拍系統

開發 前端
傳統的廣告投放方式往往依賴于人工操作和簡單的規則引擎,無法高效地處理大規模的廣告競拍請求。因此,我們需要一個智能高效的廣告競拍系統來解決這個問題。

傳統的廣告投放方式往往依賴于人工操作和簡單的規則引擎,無法高效地處理大規模的廣告競拍請求。因此,我們需要一個智能高效的廣告競拍系統來解決這個問題。

哪些公司使用Apache Ignite?

  • AdColony:移動廣告平臺,使用 Ignite 實現廣告投放的高效管理和優化。
  • eBay:在線拍賣網站,使用 Ignite 加速搜索和推薦系統。
  • US Department of Energy (DOE):美國能源部,使用 Ignite 進行科學研究和大數據分析。
  • NASA Jet Propulsion Laboratory:美國國家航空航天局噴氣推進實驗室,利用 Ignite 支持航天任務的數據處理。
  • Coinbase:加密貨幣交易所,使用 Ignite 提高交易速度和安全性。
  • Blockchain.com:區塊鏈技術和金融服務提供商,利用 Ignite 實現高效的數據存儲和處理。
  • Wayfair:家居用品零售商,利用 Ignite 提供高效的庫存管理和個性化推薦。
  • The Trade Desk:廣告交易平臺,利用 Ignite 支持實時競價和廣告效果分析。
  • Santander Bank:西班牙第二大銀行,利用 Ignite 提升支付系統的性能和可靠性。
  • Barclays Bank:英國大型銀行,采用 Ignite 實現低延遲的市場數據分析。

Apache Ignite的優勢

1. 高性能

  • 內存計算:Apache Ignite是一個內存數據庫,數據存放在內存中,提供了極低的延遲訪問速度。
  • 分布式架構:支持水平擴展,通過集群化部署,可以顯著提升系統的吞吐量和處理能力。

2. 靈活性

  • 多種數據模型:支持鍵值存儲、SQL查詢、流處理等多種數據模型,能夠滿足不同場景下的需求。
  • ACID事務支持:確保數據的一致性和完整性,適合需要強一致性的應用。

3. 易用性

  • 豐富的API:提供Java、C++、.NET、Python等多種語言的API接口,方便開發者快速集成。
  • 易于部署:可以通過簡單的配置文件進行設置,并且支持自動發現和負載均衡。

4. 強大的功能特性

  • 緩存與持久化:結合了內存緩存的優勢和磁盤持久化的穩定性,能夠在性能和耐久性之間取得平衡。
  • 實時分析:內置的數據網格技術允許在內存中進行復雜的分析操作,而無需額外的數據移動或轉換。
  • 機器學習加速:與MLlib等機器學習庫集成良好,可以加速訓練過程并提高預測準確性。

代碼實操

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>ad-auction-system</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
    </parent>

    <properties>
        <java.version>11</java.version>
        <ignite.version>2.15.0</ignite.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Apache Ignite -->
        <dependency>
            <groupId>org.apache.ignite</groupId>
            <artifactId>ignite-core</artifactId>
            <version>${ignite.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ignite</groupId>
            <artifactId>ignite-spring-data_2.3</artifactId>
            <version>${ignite.version}</version>
        </dependency>

        <!-- Lombok for concise code -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- Spring Boot Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- 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>

        <!-- AspectJ for AOP -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.yml

server:
  port:8080

logging:
level:
    root:INFO
    org.springframework.web:DEBUG
    com.example.adauctionsystem:DEBUG

spring:
security:
    user:
      name:admin
      password:admin

app:
jwtSecret:yourJwtSecretKey
jwtExpirationMs:86400000# 24 hours

data:
sql:
    init-mode:always

ignite-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="cacheConfiguration">
            <list>
                <bean class="org.apache.ignite.configuration.CacheConfiguration">
                    <property name="name" value="UserProfiles"/>
                    <property name="cacheMode" value="REPLICATED"/>
                </bean>
                <bean class="org.apache.ignite.configuration.CacheConfiguration">
                    <property name="name" value="BidRequests"/>
                    <property name="cacheMode" value="PARTITIONED"/>
                </bean>
                <bean class="org.apache.ignite.configuration.CacheConfiguration">
                    <property name="name" value="WinningBids"/>
                    <property name="cacheMode" value="PARTITIONED"/>
                </bean>
            </list>
        </property>
    </bean>
</beans>

AdAuctionApplication.java

package com.example.adauctionsystem;

import org.apache.ignite.Ignition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
publicclass AdAuctionApplication {

    public static void main(String[] args) {
        SpringApplication.run(AdAuctionApplication.class, args);
    }

    @Bean
    public void igniteInstance() {
        Ignition.start("classpath:ignite-config.xml");
    }
}

IgniteConfig.java

package com.example.adauctionsystem.config;

import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
publicclass IgniteConfig {

    @Bean
    public Ignite igniteInstance() {
        return Ignition.start("classpath:ignite-config.xml");
    }
}

SecurityConfig.java

package com.example.adauctionsystem.config;

import com.example.adauctionsystem.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
publicclass SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

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

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        returnsuper.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        returnnew BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        returnnew JwtAuthenticationFilter();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated();

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

WebConfig.java

package com.example.adauctionsystem.config;

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

@Configuration
publicclass WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true);
    }
}

UserProfile.java

package com.example.adauctionsystem.model;

import lombok.Data;

@Data
public class UserProfile {
    private Integer id; // 用戶ID
    private String name; // 用戶名
    private String interests; // 用戶興趣
}

BidRequest.java

package com.example.adauctionsystem.model;

import lombok.Data;

@Data
public class BidRequest {
    private String requestId; // 競價請求ID
    private Double bidAmount; // 競價金額
    private String adContent; // 廣告內容
    private Integer userId; // 用戶ID
}

WinningBid.java

package com.example.adauctionsystem.model;

import lombok.Data;

@Data
public class WinningBid {
    private String requestId; // 競價請求ID
    private Double bidAmount; // 勝出的競價金額
    private String adContent; // 勝出的廣告內容
    private Integer winningUserId; // 勝出的用戶ID
}

UserRepository.java

package com.example.adauctionsystem.repository;

import com.example.adauctionsystem.model.UserProfile;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends IgniteRepository<UserProfile, Integer> {
}

BidRepository.java

package com.example.adauctionsystem.repository;

import com.example.adauctionsystem.model.BidRequest;
import org.apache.ignite.springdata.repository.IgniteRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BidRepository extends IgniteRepository<BidRequest, String> {
}

UserProfileService.java

package com.example.adauctionsystem.service;

import com.example.adauctionsystem.model.UserProfile;
import com.example.adauctionsystem.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
publicclass UserProfileService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 保存用戶畫像
     *
     * @param userProfile 用戶畫像對象
     */
    public void saveUserProfile(UserProfile userProfile) {
        userRepository.save(userProfile);
    }

    /**
     * 根據用戶ID獲取用戶畫像
     *
     * @param userId 用戶ID
     * @return 用戶畫像對象
     */
    public UserProfile getUserProfileById(int userId) {
        return userRepository.findById(userId).orElse(null);
    }
}

AdBiddingService.java

package com.example.adauctionsystem.service;

import com.example.adauctionsystem.model.BidRequest;
import com.example.adauctionsystem.model.WinningBid;
import com.example.adauctionsystem.repository.BidRepository;
import com.example.adauctionsystem.util.AuctionUtils;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;

@Service
publicclass AdBiddingService {

    @Autowired
    private Ignite ignite;

    @Autowired
    private BidRepository bidRepository;

    private IgniteCache<String, BidRequest> bidCache;
    private IgniteCache<String, WinningBid> winningBidCache;

    @PostConstruct
    public void init() {
        bidCache = ignite.getOrCreateCache("BidRequests");
        winningBidCache = ignite.getOrCreateCache("WinningBids");
    }

    /**
     * 提交競價請求
     *
     * @param bidRequest 競價請求對象
     */
    public void placeBid(BidRequest bidRequest) {
        bidCache.put(bidRequest.getRequestId(), bidRequest);
        processAuction(bidRequest.getRequestId());
    }

    /**
     * 處理拍賣過程
     *
     * @param requestId 競價請求ID
     */
    private void processAuction(String requestId) {
        List<BidRequest> bids = bidCache.values().stream()
                .filter(b -> b.getRequestId().equals(requestId))
                .toList();

        if (bids.isEmpty()) return;

        BidRequest highestBid = AuctionUtils.findHighestBid(bids);

        WinningBid winningBid = new WinningBid();
        winningBid.setRequestId(highestBid.getRequestId());
        winningBid.setBidAmount(highestBid.getBidAmount());
        winningBid.setAdContent(highestBid.getAdContent());
        winningBid.setWinningUserId(highestBid.getUserId());

        winningBidCache.put(winningBid.getRequestId(), winningBid);
    }

    /**
     * 獲取勝出的競價
     *
     * @param requestId 競價請求ID
     * @return 勝出的競價對象
     */
    public WinningBid getWinningBidForRequest(String requestId) {
        return winningBidCache.get(requestId);
    }
}

AuthService.java

package com.example.adauctionsystem.service;

import com.example.adauctionsystem.dto.AuthResponseDTO;
import com.example.adauctionsystem.dto.LoginRequestDTO;
import com.example.adauctionsystem.dto.SignUpRequestDTO;
import com.example.adauctionsystem.security.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
publicclass AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 認證用戶并生成JWT令牌
     *
     * @param loginRequest 登錄請求對象
     * @return 包含JWT令牌的響應對象
     */
    public AuthResponseDTO authenticateUser(LoginRequestDTO loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));

        SecurityContextHolder.getContext().setAuthentication(authentication);

        String jwt = tokenProvider.generateToken(authentication);
        returnnew AuthResponseDTO(jwt);
    }

    /**
     * 注冊新用戶
     *
     * @param signUpRequest 注冊請求對象
     */
    public void registerUser(SignUpRequestDTO signUpRequest) {
        // 這里通常會在數據庫中創建一個新的用戶
        // 為了簡化示例,我們僅模擬注冊過程
    }
}

AuctionUtils.java

package com.example.adauctionsystem.util;

import com.example.adauctionsystem.model.BidRequest;

import java.util.Comparator;
import java.util.List;

publicclass AuctionUtils {

    /**
     * 查找最高競價
     *
     * @param bids 競價列表
     * @return 最高競價對象
     */
    public static BidRequest findHighestBid(List<BidRequest> bids) {
        return bids.stream()
                .max(Comparator.comparingDouble(BidRequest::getBidAmount))
                .orElse(null);
    }
}

LoggingAspect.java

package com.example.adauctionsystem.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
publicclass LoggingAspect {

    privatefinal Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 方法執行前的日志記錄
     *
     * @param joinPoint 連接點對象
     */
    @Before("execution(* com.example.adauctionsystem.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        logger.info("Entering method {} with arguments {}", joinPoint.getSignature().getName(), joinPoint.getArgs());
    }

    /**
     * 方法執行后的日志記錄
     *
     * @param joinPoint 連接點對象
     * @param result 返回結果
     */
    @AfterReturning(pointcut = "execution(* com.example.adauctionsystem.service.*.*(..))", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        logger.info("Exiting method {} with result {}", joinPoint.getSignature().getName(), result);
    }
}

UserProfileController.java

package com.example.adauctionsystem.controller;

import com.example.adauctionsystem.model.UserProfile;
import com.example.adauctionsystem.service.UserProfileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
publicclass UserProfileController {

    @Autowired
    private UserProfileService userProfileService;

    /**
     * 創建用戶畫像
     *
     * @param userProfile 用戶畫像對象
     * @return 成功響應
     */
    @PostMapping("/")
    public ResponseEntity<Void> createUserProfile(@RequestBody UserProfile userProfile) {
        userProfileService.saveUserProfile(userProfile);
        return ResponseEntity.ok().build();
    }

    /**
     * 根據用戶ID獲取用戶畫像
     *
     * @param userId 用戶ID
     * @return 用戶畫像對象或404錯誤
     */
    @GetMapping("/{userId}")
    public ResponseEntity<UserProfile> getUserProfile(@PathVariable int userId) {
        UserProfile userProfile = userProfileService.getUserProfileById(userId);
        if (userProfile == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(userProfile);
    }
}

AdController.java

package com.example.adauctionsystem.controller;

import com.example.adauctionsystem.model.BidRequest;
import com.example.adauctionsystem.model.WinningBid;
import com.example.adauctionsystem.service.AdBiddingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/bids")
publicclass AdController {

    @Autowired
    private AdBiddingService adBiddingService;

    /**
     * 提交競價請求
     *
     * @param bidRequest 競價請求對象
     * @return 成功響應
     */
    @PostMapping("/")
    public ResponseEntity<Void> placeBid(@RequestBody BidRequest bidRequest) {
        adBiddingService.placeBid(bidRequest);
        return ResponseEntity.ok().build();
    }

    /**
     * 獲取勝出的競價
     *
     * @param requestId 競價請求ID
     * @return 勝出的競價對象或404錯誤
     */
    @GetMapping("/{requestId}/winning")
    public ResponseEntity<WinningBid> getWinningBid(@PathVariable String requestId) {
        WinningBid winningBid = adBiddingService.getWinningBidForRequest(requestId);
        if (winningBid == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(winningBid);
    }
}

AuthController.java

package com.example.adauctionsystem.controller;

import com.example.adauctionsystem.dto.AuthResponseDTO;
import com.example.adauctionsystem.dto.LoginRequestDTO;
import com.example.adauctionsystem.dto.SignUpRequestDTO;
import com.example.adauctionsystem.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/auth")
publicclass AuthController {

    @Autowired
    private AuthService authService;

    /**
     * 用戶登錄并獲取JWT令牌
     *
     * @param loginRequest 登錄請求對象
     * @return 包含JWT令牌的響應對象
     */
    @PostMapping("/signin")
    public ResponseEntity<AuthResponseDTO> authenticateUser(@RequestBody LoginRequestDTO loginRequest) {
        AuthResponseDTO response = authService.authenticateUser(loginRequest);
        return ResponseEntity.ok(response);
    }

    /**
     * 用戶注冊
     *
     * @param signUpRequest 注冊請求對象
     * @return 成功響應
     */
    @PostMapping("/signup")
    public ResponseEntity<Void> registerUser(@RequestBody SignUpRequestDTO signUpRequest) {
        authService.registerUser(signUpRequest);
        return ResponseEntity.ok().build();
    }
}

GlobalExceptionHandler.java

package com.example.adauctionsystem.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
publicclass GlobalExceptionHandler {

    /**
     * 處理資源未找到異常
     *
     * @param ex 異常對象
     * @return 404錯誤響應
     */
    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        returnnew ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }

    /**
     * 處理通用異常
     *
     * @param ex 異常對象
     * @return 500錯誤響應
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleException(Exception ex) {
        returnnew ResponseEntity<>("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

ResourceNotFoundException.java

package com.example.adauctionsystem.exception;

/**
 * 自定義資源未找到異常類
 */
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

AuthResponseDTO.java

package com.example.adauctionsystem.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 認證響應數據傳輸對象
 */
@Data
@AllArgsConstructor
public class AuthResponseDTO {
    private String accessToken; // JWT訪問令牌
}

LoginRequestDTO.java

package com.example.adauctionsystem.dto;

import lombok.Data;

/**
 * 登錄請求數據傳輸對象
 */
@Data
public class LoginRequestDTO {
    private String username; // 用戶名
    private String password; // 密碼
}

SignUpRequestDTO.java

package com.example.adauctionsystem.dto;

import lombok.Data;

/**
 * 注冊請求數據傳輸對象
 */
@Data
public class SignUpRequestDTO {
    private String username; // 用戶名
    private String password; // 密碼
}

JwtAuthenticationFilter.java

package com.example.adauctionsystem.security;

import com.example.adauctionsystem.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * JWT認證過濾器
 */
publicclass JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private AuthService authService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            String jwt = getJwtFromRequest(request);

            if (jwt != null && tokenProvider.validateToken(jwt)) {
                Long userId = tokenProvider.getUserIdFromJWT(jwt);

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userId, null, authService.loadUserById(userId).getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception ex) {
            logger.error("Could not set user authentication in security context", ex);
        }

        filterChain.doFilter(request, response);
    }

    /**
     * 從請求頭中提取JWT令牌
     *
     * @param request HTTP請求對象
     * @return JWT令牌字符串
     */
    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7, bearerToken.length());
        }
        returnnull;
    }
}

JwtTokenProvider.java

package com.example.adauctionsystem.security;

import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * JWT令牌提供者
 */
@Component
publicclass JwtTokenProvider {

    @Value("${app.jwtSecret}")
    private String jwtSecret;

    @Value("${app.jwtExpirationMs}")
    privateint jwtExpirationMs;

    /**
     * 生成JWT令牌
     *
     * @param authentication 認證對象
     * @return JWT令牌字符串
     */
    public String generateToken(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();

        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationMs);

        return Jwts.builder()
                .setSubject(Long.toString(((UserDetailsImpl) userDetails).getId()))
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }

    /**
     * 從JWT令牌中提取用戶ID
     *
     * @param token JWT令牌字符串
     * @return 用戶ID
     */
    public Long getUserIdFromJWT(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtSecret)
                .parseClaimsJws(token)
                .getBody();

        return Long.parseLong(claims.getSubject());
    }

    /**
     * 驗證JWT令牌有效性
     *
     * @param authToken JWT令牌字符串
     * @return 是否有效
     */
    public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            returntrue;
        } catch (MalformedJwtException ex) {
            logger.error("Invalid JWT token");
        } catch (ExpiredJwtException ex) {
            logger.error("Expired JWT token");
        } catch (UnsupportedJwtException ex) {
            logger.error("Unsupported JWT token");
        } catch (IllegalArgumentException ex) {
            logger.error("JWT claims string is empty.");
        }
        returnfalse;
    }
}

UserDetailsServiceImpl.java

package com.example.adauctionsystem.security;

import com.example.adauctionsystem.model.UserProfile;
import com.example.adauctionsystem.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * 用戶詳細信息服務實現類
 */
@Service
publicclass UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 根據用戶名加載用戶詳情
     *
     * @param username 用戶名
     * @return 用戶詳情對象
     * @throws UsernameNotFoundException 用戶未找到異常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserProfile user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));

        return UserDetailsImpl.build(user);
    }

    /**
     * 根據用戶ID加載用戶詳情
     *
     * @param id 用戶ID
     * @return 用戶詳情對象
     * @throws UsernameNotFoundException 用戶未找到異常
     */
    public UserDetails loadUserById(Long id) {
        UserProfile user = userRepository.findById(id.intValue())
                .orElseThrow(() -> new UsernameNotFoundException("User Not Found with id: " + id));

        return UserDetailsImpl.build(user);
    }
}

data.sql

INSERT INTO UserProfiles (id, name, interests) VALUES (1, 'John Doe', 'sports,travel');
INSERT INTO UserProfiles (id, name, interests) VALUES (2, 'Jane Smith', 'music,gaming');

測試

創建用戶畫像

POST http://localhost:8080/api/users/request Body:

{
    "id": 1,
    "name": "John Doe",
    "interests": "sports,travel"
}

Respons Code: 200 OK。

獲取用戶畫像

GET http://localhost:8080/api/users/1Respons:

{
    "id": 1,
    "name": "John Doe",
    "interests": "sports,travel"
}

提交競價請求

POST  http://localhost:8080/api/bids/

request Body:

{
    "requestId": "req1",
    "bidAmount": 10.0,
    "adContent": "Ad Content 1",
    "userId": 1
}

Respons Code: 200 OK

獲取勝出競價

GET http://localhost:8080/api/bids/req1/winning

Respons:

{
    "requestId": "req1",
    "bidAmount": 10.0,
    "adContent": "Ad Content 1",
    "winningUserId": 1
}

責任編輯:武曉燕 來源: Java知識日歷
相關推薦

2025-09-26 08:46:30

2024-05-17 08:07:46

Spring廣告推薦系統

2025-03-17 08:39:08

SpringApache數據

2025-04-01 08:38:41

2025-04-23 08:50:00

SpringBootCurator分布式鎖

2025-05-20 09:00:04

SpringGeoHash派單

2025-03-31 08:43:34

SpringTika優化

2025-03-03 07:30:00

SpringBootJGraphT網絡建模

2025-05-09 08:34:57

RSocketSpringBoot聊天系統

2025-05-06 08:40:21

SpringPostGIS系統

2025-02-28 08:40:28

ZooKeeperSpringBoot計費系統

2025-04-08 08:50:37

SpringCamel系統

2025-06-03 02:10:00

SpringInfluxDB數據

2020-02-12 09:00:48

數據網格Apache Igni數據管理

2025-04-29 08:36:28

SpringCanal數據庫

2025-07-10 08:46:21

ConnectSpringBoot數據

2025-03-26 01:55:00

Spring協議物聯網

2025-02-26 09:24:54

SpringMySQLMyBatis

2025-04-21 03:00:00

2025-08-08 02:11:00

SpringFunctions流處理
點贊
收藏

51CTO技術棧公眾號

精品999在线观看| 最近中文字幕2019免费| 欧美国产视频一区| 欧美 日韩 国产 精品| 欧美一区=区| xxxxx91麻豆| 私密视频在线观看| 国产精品久久久久久久久免费高清| 亚洲色图制服诱惑| 久久久久久久有限公司| 一级做a爱片性色毛片| 亚洲经典视频在线观看| 日韩中文在线不卡| 免费在线观看你懂的| 日韩一区二区三区高清在线观看| 在线影院国内精品| 91.com在线| 男人影院在线观看| 91色porny| 成人动漫在线观看视频| 99re热视频| 亚洲激情自拍| 欧洲亚洲一区二区三区| 无吗不卡中文字幕| 伊人网在线免费| 黄色影院在线播放| 99在线热播精品免费| 91久久夜色精品国产网站| www.com国产| 一本精品一区二区三区| 一区二区在线视频播放| 毛茸茸多毛bbb毛多视频| 日韩精品一区二区三区中文字幕| 欧美视频三区在线播放| 国产视频一视频二| 黄色在线看片| 亚洲毛片av在线| 在线天堂一区av电影| yourporn在线观看视频| 久久久亚洲精品石原莉奈| 国产精品推荐精品| 性生交大片免费看女人按摩| 久久精品国产99久久6| 国产精品久久久久久亚洲调教| 日本天堂网在线观看| 国产一区二区三区四区三区四 | 国产91精品久久久久久| 国产亚洲小视频| 黑人一区二区三区四区五区| 欧美巨乳在线观看| 欧美黄色一区二区三区| 欧美体内she精视频在线观看| 欧美成人激情视频免费观看| 91狠狠综合久久久| 午夜国产精品视频免费体验区| 美日韩精品免费观看视频| 欧美视频一区二区在线| 97精品一区二区| 久久亚洲私人国产精品va| 国产精品免费人成网站酒店| 亚洲国产精品91| 欧美精品video| 亚洲 欧美 日韩 综合| 国产一区二区三区三州| 在线成人h网| 欧美亚洲国产视频小说| 欧美一区二区三区不卡视频| 久久国产精品久久w女人spa| 国产成人精品网站| 最近中文字幕在线视频| 国产在线视频不卡二| 99理论电影网| 日本护士...精品国| 久久精品在线免费观看| 影音先锋男人的网站| 亚洲电影视频在线| 狠狠躁夜夜躁人人爽天天天天97| 一本久道中文无码字幕av| 国产精品久久久久久妇女| 欧美精选一区二区| 人妻激情偷乱频一区二区三区| 亚洲另类av| 日韩在线观看免费高清| 精品无码久久久久| 视频一区在线播放| 成人免费午夜电影| 天天色综合av| 中文字幕一区二区不卡| 黄网站欧美内射| 亚洲成人激情社区| 91精品麻豆日日躁夜夜躁| 美女搡bbb又爽又猛又黄www| 国产一区二区亚洲| 久久精品国产成人| 欧美亚洲精品天堂| 国产一区视频网站| 蜜桃传媒视频麻豆第一区免费观看 | www.av88| av亚洲精华国产精华| 视频一区视频二区视频三区视频四区国产 | 在线免费视频一区| 欧美变态网站| 麻豆国产精品va在线观看不卡| 成人毛片18女人毛片| 久久精品国产**网站演员| 国产伦精品一区二区三区视频免费| 国产一级在线| 午夜影视日本亚洲欧洲精品| 亚洲最大成人在线观看| 国产精品chinese在线观看| 视频一区视频二区国产精品| 欧美三级韩国三级日本三斤在线观看| 久久精品国内一区二区三区| 久久精彩视频| 日本在线观看高清完整版| 91成人在线精品| 2一3sex性hd| 久久精品免费一区二区三区| 日韩免费在线播放| 香港一级纯黄大片| 亚洲一区视频在线| 超碰人人cao| 91精品啪在线观看国产18| 国产精品高精视频免费| 天堂网www中文在线| 亚洲男人的天堂在线观看| 蜜臀视频一区二区三区| 免费视频亚洲| 68精品国产免费久久久久久婷婷| 性一交一乱一精一晶| 亚洲欧美区自拍先锋| 亚洲国产日韩欧美在线观看| 美女网站一区| 日本人成精品视频在线| 亚洲欧美丝袜中文综合| 午夜精品福利一区二区三区av | 国产精品久久综合| 国产wwwxx| 成人亚洲一区| 国产精品一区电影| 91在线看片| 欧美色偷偷大香| 卡一卡二卡三在线观看| 丝袜国产日韩另类美女| 日本三级中国三级99人妇网站| 黑人巨大精品| 在线视频中文亚洲| 亚洲系列在线观看| 亚洲人成精品久久久久久| 色婷婷一区二区三区av免费看| 日韩精品中文字幕第1页| 国产精品男女猛烈高潮激情| 成a人v在线播放| 欧美日韩视频在线第一区| av在线免费播放网址| 久久99九九99精品| 精品国产一区二区三区在线| 欧美激情三级| 国内成人精品一区| 天堂资源最新在线| 欧美怡红院视频| 国产尤物在线播放| 国产成人午夜电影网| 国产在线播放观看| 少妇精品久久久| 91精品国产自产在线老师啪| av网站免费在线观看| 欧美va天堂va视频va在线| 午夜影院在线看| 久久久国产精品午夜一区ai换脸| 538任你躁在线精品免费| 91精品天堂福利在线观看| 99视频在线| 中文字幕色婷婷在线视频| 国产一区二区三区在线| 国产女人高潮时对白| 亚洲成a人片综合在线| 国产精品300页| 久久se这里有精品| 国产精品第157页| 欧美禁忌电影网| 1卡2卡3卡精品视频| 蜜桃视频在线观看免费视频| 伊人精品在线观看| 亚洲成熟女性毛茸茸| 色综合久久九月婷婷色综合| 欧美日韩国产一二三区| 成人免费高清视频在线观看| 中文字幕无码不卡免费视频| 68国产成人综合久久精品| 国产一区二区三区av在线| 蜜桃视频成人m3u8| 久久久久久久国产| 色开心亚洲综合| 国产视频精品在线| 99热这里只有精品1| 一本到一区二区三区| 欧美亚洲日本在线| 久久久久亚洲蜜桃| 动漫av在线免费观看| 日韩不卡在线观看日韩不卡视频| 真实国产乱子伦对白视频| 少妇精品久久久一区二区| 草莓视频一区| 99tv成人影院| 国产精品 欧美在线| 免费看电影在线| 日韩小视频网址| 日本福利午夜视频在线| 日韩欧美电影一区| 91精品国自产| 在线观看91视频| 午夜精品久久久久久久久久久久久蜜桃 | 国产91综合一区在线观看| 美女少妇一区二区| 久久久久看片| 久久在线中文字幕| 综合国产精品| 日本高清xxxx| 久久综合99| 天堂资源在线亚洲视频| 亚洲最好看的视频| 精品乱码一区二区三区| 中文字幕一区图| 91国产在线播放| 日韩一区二区三区四区五区 | 九九热hot精品视频在线播放| 91香蕉国产在线观看| 久久青草免费| 国产精品无av码在线观看| 黑人巨大精品欧美一区二区桃花岛| 久久人人看视频| www555久久| 欧美激情国内偷拍| 污视频网站在线免费| 久久成人在线视频| 调教一区二区| 欧美激情第一页xxx| 久色国产在线| 欧美国产极速在线| 91美女精品| 97在线视频精品| 在线观看网站免费入口在线观看国内| 国内成人精品一区| 在线看的毛片| 国产99久久久欧美黑人| 欧美一级二级视频| 国产一区二区在线免费| 亚洲一区有码| 91国产丝袜在线放| 国产一区二区三区亚洲| 国产一区在线免费| 美女久久久久| 亚洲精品影院| 在线观看国产精品入口| 欧美另类videosbestsex日本| 女主播福利一区| cao在线观看| 久久av一区二区三区| 久久久精品三级| 国产在线视视频有精品| 国产综合内射日韩久| 2020国产精品| 三区四区在线观看| 亚洲欧美日韩在线| 国产又大又黑又粗免费视频| 欧美日韩免费在线观看| 成人午夜精品视频| 日韩一区二区在线看片| 黄色aaa大片| 国产亚洲欧美另类中文| 超碰在线网址| 97久久精品视频| 欧美激情三区| 国产精品入口免费| 欧美日韩国产传媒| 亚洲小视频在线播放| 国产色综合网| av免费网站观看| 久久99蜜桃精品| 日b视频在线观看| 国产精品私人影院| 日韩熟女精品一区二区三区| 欧洲精品中文字幕| 成 人 黄 色 片 在线播放| 精品一区二区亚洲| 成人ww免费完整版在线观看| 4438全国成人免费| 在线观看亚洲精品福利片| 国产精品视频免费一区| 日韩一区二区在线免费| 国产av麻豆mag剧集| 开心九九激情九九欧美日韩精美视频电影| 日本女人性视频| 国产三级三级三级精品8ⅰ区| 国产精品九九九九九九| 色婷婷激情综合| 国产77777| www.久久色.com| 精品91久久| 国产欧美一区二区三区不卡高清| 日韩片欧美片| 日韩中文字幕二区| 国模大尺度一区二区三区| 国产精品三级在线观看无码| 亚洲男人的天堂一区二区| 中文字幕一区二区人妻电影| 日韩一区二区三区四区 | 成人欧美一区二区三区1314| 日韩欧美成人一区二区三区| 日韩欧美久久久| 欧美极品另类| 国产精品久久久久久久久久ktv | 亚洲国产精品视频一区| 亚洲国产日本| 日本人妻一区二区三区| 亚洲丝袜另类动漫二区| 亚洲精品一区二区二区| 亚洲精品一区二区三区婷婷月 | 国产成人在线精品| 极品束缚调教一区二区网站| 免费观看黄色大片| 免费观看日韩电影| 微拍福利一区二区| 欧美三级xxx| 亚洲欧洲国产综合| 2019中文字幕在线免费观看| 白嫩白嫩国产精品| 福利视频免费在线观看| 国产精品影视天天线| 在线日韩国产网站| 欧美日韩高清在线播放| 91精彩视频在线观看| 国产精品99导航| 精品日韩在线| 日韩爱爱小视频| 国产精品国产三级国产有无不卡| 国产情侣免费视频| 在线免费观看羞羞视频一区二区| 另类专区亚洲| 欧美性大战久久久久| 久久久国产亚洲精品| 成人免费毛片糖心| 欧美午夜精品理论片a级按摩| 韩国福利在线| 国产美女搞久久| 天天综合一区| 香蕉视频在线观看黄| 亚洲一二三区不卡| 天堂网在线观看视频| 91成人天堂久久成人| 亚洲精品播放| 丁香婷婷激情网| 亚洲欧美综合另类在线卡通| 国产精品毛片一区二区在线看舒淇| 久久婷婷国产麻豆91天堂| 国产一区一区| 精品视频在线观看一区| 99re这里只有精品首页| 人人妻人人爽人人澡人人精品| 国产一区二区美女视频| 国产精品久久久久久久久久久久久久久 | 少女频道在线观看免费播放电视剧| 97碰碰视频| 国产欧美激情| 日本黄色激情视频| 日韩三级av在线播放| 僵尸再翻生在线观看| 日本10禁啪啪无遮挡免费一区二区| 日韩精品一二三区| 日韩va亚洲va欧美va清高| 精品国产乱码久久久久久老虎| 2001个疯子在线观看| 日韩三级电影| 风流少妇一区二区| 亚洲 日本 欧美 中文幕| 日韩视频第一页| 精品深夜福利视频| 久久久精品麻豆| 亚洲一区二区精品视频| 国产小视频在线| 51成人做爰www免费看网站| 亚洲视频大全| 小早川怜子一区二区的演员表| 亚洲二区在线播放视频| 99久久亚洲国产日韩美女| 国产成年人在线观看| 99精品国产一区二区三区不卡| 伊人网站在线观看| 91精品国产777在线观看| 色135综合网| 中文字幕av观看| 日韩午夜在线影院| 综合在线影院| 岛国大片在线播放| 国产精品精品国产色婷婷| 视频二区在线| 99高清视频有精品视频| 日韩**一区毛片| 在线观看亚洲欧美|