自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot與Apache Ignite整合,實(shí)現(xiàn)廣告實(shí)時(shí)競(jìng)拍系統(tǒng)

開(kāi)發(fā) 前端
傳統(tǒng)的廣告投放方式往往依賴于人工操作和簡(jiǎn)單的規(guī)則引擎,無(wú)法高效地處理大規(guī)模的廣告競(jìng)拍請(qǐng)求。因此,我們需要一個(gè)智能高效的廣告競(jìng)拍系統(tǒng)來(lái)解決這個(gè)問(wèn)題。

傳統(tǒng)的廣告投放方式往往依賴于人工操作和簡(jiǎn)單的規(guī)則引擎,無(wú)法高效地處理大規(guī)模的廣告競(jìng)拍請(qǐng)求。因此,我們需要一個(gè)智能高效的廣告競(jìng)拍系統(tǒng)來(lái)解決這個(gè)問(wèn)題。

哪些公司使用Apache Ignite?

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

Apache Ignite的優(yōu)勢(shì)

1. 高性能

  • 內(nèi)存計(jì)算:Apache Ignite是一個(gè)內(nèi)存數(shù)據(jù)庫(kù),數(shù)據(jù)存放在內(nèi)存中,提供了極低的延遲訪問(wèn)速度。
  • 分布式架構(gòu):支持水平擴(kuò)展,通過(guò)集群化部署,可以顯著提升系統(tǒng)的吞吐量和處理能力。

2. 靈活性

  • 多種數(shù)據(jù)模型:支持鍵值存儲(chǔ)、SQL查詢、流處理等多種數(shù)據(jù)模型,能夠滿足不同場(chǎng)景下的需求。
  • ACID事務(wù)支持:確保數(shù)據(jù)的一致性和完整性,適合需要強(qiáng)一致性的應(yīng)用。

3. 易用性

  • 豐富的API:提供Java、C++、.NET、Python等多種語(yǔ)言的API接口,方便開(kāi)發(fā)者快速集成。
  • 易于部署:可以通過(guò)簡(jiǎn)單的配置文件進(jìn)行設(shè)置,并且支持自動(dòng)發(fā)現(xiàn)和負(fù)載均衡。

4. 強(qiáng)大的功能特性

  • 緩存與持久化:結(jié)合了內(nèi)存緩存的優(yōu)勢(shì)和磁盤(pán)持久化的穩(wěn)定性,能夠在性能和耐久性之間取得平衡。
  • 實(shí)時(shí)分析:內(nèi)置的數(shù)據(jù)網(wǎng)格技術(shù)允許在內(nèi)存中進(jìn)行復(fù)雜的分析操作,而無(wú)需額外的數(shù)據(jù)移動(dòng)或轉(zhuǎn)換。
  • 機(jī)器學(xué)習(xí)加速:與MLlib等機(jī)器學(xué)習(xí)庫(kù)集成良好,可以加速訓(xùn)練過(guò)程并提高預(yù)測(cè)準(zhǔn)確性。

代碼實(shí)操

<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; // 競(jìng)價(jià)請(qǐng)求ID
    private Double bidAmount; // 競(jìng)價(jià)金額
    private String adContent; // 廣告內(nèi)容
    private Integer userId; // 用戶ID
}

WinningBid.java

package com.example.adauctionsystem.model;

import lombok.Data;

@Data
public class WinningBid {
    private String requestId; // 競(jìng)價(jià)請(qǐng)求ID
    private Double bidAmount; // 勝出的競(jìng)價(jià)金額
    private String adContent; // 勝出的廣告內(nèi)容
    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;

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

    /**
     * 根據(jù)用戶ID獲取用戶畫(huà)像
     *
     * @param userId 用戶ID
     * @return 用戶畫(huà)像對(duì)象
     */
    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");
    }

    /**
     * 提交競(jìng)價(jià)請(qǐng)求
     *
     * @param bidRequest 競(jìng)價(jià)請(qǐng)求對(duì)象
     */
    public void placeBid(BidRequest bidRequest) {
        bidCache.put(bidRequest.getRequestId(), bidRequest);
        processAuction(bidRequest.getRequestId());
    }

    /**
     * 處理拍賣(mài)過(guò)程
     *
     * @param requestId 競(jìng)價(jià)請(qǐng)求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);
    }

    /**
     * 獲取勝出的競(jìng)價(jià)
     *
     * @param requestId 競(jìng)價(jià)請(qǐng)求ID
     * @return 勝出的競(jìng)價(jià)對(duì)象
     */
    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;

    /**
     * 認(rèn)證用戶并生成JWT令牌
     *
     * @param loginRequest 登錄請(qǐng)求對(duì)象
     * @return 包含JWT令牌的響應(yīng)對(duì)象
     */
    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);
    }

    /**
     * 注冊(cè)新用戶
     *
     * @param signUpRequest 注冊(cè)請(qǐng)求對(duì)象
     */
    public void registerUser(SignUpRequestDTO signUpRequest) {
        // 這里通常會(huì)在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)新的用戶
        // 為了簡(jiǎn)化示例,我們僅模擬注冊(cè)過(guò)程
    }
}

AuctionUtils.java

package com.example.adauctionsystem.util;

import com.example.adauctionsystem.model.BidRequest;

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

publicclass AuctionUtils {

    /**
     * 查找最高競(jìng)價(jià)
     *
     * @param bids 競(jìng)價(jià)列表
     * @return 最高競(jìng)價(jià)對(duì)象
     */
    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());

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

    /**
     * 方法執(zhí)行后的日志記錄
     *
     * @param joinPoint 連接點(diǎn)對(duì)象
     * @param result 返回結(jié)果
     */
    @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;

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

    /**
     * 根據(jù)用戶ID獲取用戶畫(huà)像
     *
     * @param userId 用戶ID
     * @return 用戶畫(huà)像對(duì)象或404錯(cuò)誤
     */
    @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;

    /**
     * 提交競(jìng)價(jià)請(qǐng)求
     *
     * @param bidRequest 競(jìng)價(jià)請(qǐng)求對(duì)象
     * @return 成功響應(yīng)
     */
    @PostMapping("/")
    public ResponseEntity<Void> placeBid(@RequestBody BidRequest bidRequest) {
        adBiddingService.placeBid(bidRequest);
        return ResponseEntity.ok().build();
    }

    /**
     * 獲取勝出的競(jìng)價(jià)
     *
     * @param requestId 競(jìng)價(jià)請(qǐng)求ID
     * @return 勝出的競(jìng)價(jià)對(duì)象或404錯(cuò)誤
     */
    @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 登錄請(qǐng)求對(duì)象
     * @return 包含JWT令牌的響應(yīng)對(duì)象
     */
    @PostMapping("/signin")
    public ResponseEntity<AuthResponseDTO> authenticateUser(@RequestBody LoginRequestDTO loginRequest) {
        AuthResponseDTO response = authService.authenticateUser(loginRequest);
        return ResponseEntity.ok(response);
    }

    /**
     * 用戶注冊(cè)
     *
     * @param signUpRequest 注冊(cè)請(qǐng)求對(duì)象
     * @return 成功響應(yīng)
     */
    @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 異常對(duì)象
     * @return 404錯(cuò)誤響應(yīng)
     */
    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        returnnew ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }

    /**
     * 處理通用異常
     *
     * @param ex 異常對(duì)象
     * @return 500錯(cuò)誤響應(yīng)
     */
    @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;

/**
 * 認(rèn)證響應(yīng)數(shù)據(jù)傳輸對(duì)象
 */
@Data
@AllArgsConstructor
public class AuthResponseDTO {
    private String accessToken; // JWT訪問(wèn)令牌
}

LoginRequestDTO.java

package com.example.adauctionsystem.dto;

import lombok.Data;

/**
 * 登錄請(qǐng)求數(shù)據(jù)傳輸對(duì)象
 */
@Data
public class LoginRequestDTO {
    private String username; // 用戶名
    private String password; // 密碼
}

SignUpRequestDTO.java

package com.example.adauctionsystem.dto;

import lombok.Data;

/**
 * 注冊(cè)請(qǐng)求數(shù)據(jù)傳輸對(duì)象
 */
@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認(rèn)證過(guò)濾器
 */
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);
    }

    /**
     * 從請(qǐng)求頭中提取JWT令牌
     *
     * @param request HTTP請(qǐng)求對(duì)象
     * @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 認(rèn)證對(duì)象
     * @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());
    }

    /**
     * 驗(yàn)證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;

/**
 * 用戶詳細(xì)信息服務(wù)實(shí)現(xiàn)類
 */
@Service
publicclass UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 根據(jù)用戶名加載用戶詳情
     *
     * @param username 用戶名
     * @return 用戶詳情對(duì)象
     * @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);
    }

    /**
     * 根據(jù)用戶ID加載用戶詳情
     *
     * @param id 用戶ID
     * @return 用戶詳情對(duì)象
     * @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');

測(cè)試

創(chuàng)建用戶畫(huà)像

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

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

Respons Code: 200 OK。

獲取用戶畫(huà)像

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

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

提交競(jìng)價(jià)請(qǐng)求

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

request Body:

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

Respons Code: 200 OK

獲取勝出競(jìng)價(jià)

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

Respons:

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

責(zé)任編輯:武曉燕 來(lái)源: Java知識(shí)日歷
相關(guān)推薦

2024-05-17 08:07:46

Spring廣告推薦系統(tǒng)

2025-03-17 08:39:08

SpringApache數(shù)據(jù)

2025-04-01 08:38:41

2025-04-23 08:50:00

SpringBootCurator分布式鎖

2025-03-03 07:30:00

SpringBootJGraphT網(wǎng)絡(luò)建模

2025-03-31 08:43:34

SpringTika優(yōu)化

2025-02-28 08:40:28

ZooKeeperSpringBoot計(jì)費(fèi)系統(tǒng)

2025-04-08 08:50:37

SpringCamel系統(tǒng)

2020-02-12 09:00:48

數(shù)據(jù)網(wǎng)格Apache Igni數(shù)據(jù)管理

2025-03-26 01:55:00

Spring協(xié)議物聯(lián)網(wǎng)

2025-02-26 09:24:54

SpringMySQLMyBatis

2025-04-21 03:00:00

2025-03-20 08:57:54

Spring日志存儲(chǔ)系統(tǒng)

2025-04-25 08:34:52

2025-03-21 08:55:36

SpringOpenFeignAPI

2025-04-18 08:54:30

2025-04-14 01:00:00

Calcite電商系統(tǒng)MySQL

2021-08-17 06:48:43

SpringbootKafkaStream

2020-04-23 15:08:41

SpringBootMyCatJava

2025-03-13 08:37:58

Spring智能條款系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)