如何在Spring Boot中实现拍卖逻辑

问题描述 投票:0回答:1
package com.project.customer.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.project.customer.baseEntity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.persistence.*;

@EqualsAndHashCode(callSuper = true)
@Entity
@Data
public class Product  extends BaseEntity {


    private String name;
    private double price;
    private double highestBid;
    @Column(name = "EndDate")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime bidEndTime;

    private LocalDate addedDate;
    boolean status;

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer highestBidder;

}

Product.java:这是我的产品实体

package com.project.customer.controllers;

import com.project.customer.entity.Product;
import com.project.customer.repositories.ProductRepository;
import com.project.customer.service.AuctionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Optional;

@RestController
@RequestMapping("/products")
public class AuctionController {

    @Autowired
    private AuctionService auctionService;

    @Autowired
    private ProductRepository productRepository;

    @PostMapping("/{productId}/bid")
    public ResponseEntity<String> placeBid(@PathVariable Integer productId, @RequestBody double bidAmount) {
        Optional<Product> optionalProduct = productRepository.findById(productId);
        if (optionalProduct.isPresent()) {
            Product product = optionalProduct.get();
            if (product.isStatus() && product.getBidEndTime().isAfter(LocalDateTime.now())) {
                if (product.getHighestBid() == 0 || bidAmount > product.getHighestBid()) {
                    product.setHighestBid(bidAmount);
                    product.setHighestBidder(product.getHighestBidder()); // Set the highest bidder
                    // Reset the bid end time to give another 10 seconds
                    product.setBidEndTime(LocalDateTime.now().plusSeconds(10));
                    productRepository.save(product);
                    return ResponseEntity.ok("Bid placed successfully.");
                }
                return ResponseEntity.badRequest().body("Bid amount should be higher than the current highest bid.");
            }
        }
        return ResponseEntity.notFound().build();
    }

}

AuctionController.java:我从请求正文中获取出价金额

package com.project.customer;

import com.project.customer.config.AppConstants;
import com.project.customer.entity.Roles;
import com.project.customer.repositories.RoleRepository;
import com.project.customer.service.AuctionService;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.List;
//import org.springframework.security.crypto.password.PasswordEncoder;


@SpringBootApplication
public class CustomerApplication implements CommandLineRunner {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuctionService auctionService;

    @Autowired
    private RoleRepository roleRepository;
    public static void main(String[] args) {
        SpringApplication.run(CustomerApplication.class, args);
    }
    @Bean
    public ModelMapper mapper(){
        ModelMapper mapper = new ModelMapper();
        mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        return  mapper;
    }

    @Override
    public void run(String... args){
        System.out.println(this.passwordEncoder.encode("bjp"));
        try
        {
            Roles admin = new Roles();
            admin.setId(AppConstants.ROLE_ADMIN);
            admin.setName("ROLE_ADMIN");

            Roles normal_user = new Roles();
            normal_user.setId(AppConstants.NORMAL_USER);
            normal_user.setName("ROLE_NORMAL");

            List<Roles> roleList = List.of(admin, normal_user);
            List<Roles> result = this.roleRepository.saveAll(roleList);
            result.forEach(r-> System.out.println(r.getName()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "${auction.schedule}")
    public void executeAuction() {
        auctionService.startAuction();
    }

}

主要方法:我还实现了 JWT 身份验证工作。

在邮递员中测试 API 时,我收到 400 错误请求

"status": 400,
    "error": "Bad Request",
    "trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `double` from Object value (token `JsonToken.START_OBJECT`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `double` from Object value (token `JsonToken.START_OBJECT`)\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 1]\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:391)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:343)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185

Postman request

我想实现一个拍卖网络服务,其中多个客户对单一产品出价,出价开始后有 10 秒倒计时,如果在该时间范围内有任何新出价,则 10 秒计时器重新启动,否则最高出价者分配该产品。

java spring-boot spring-data-jpa scheduled-tasks
1个回答
0
投票

这个错误:

Cannot deserialize value of type `double` from Object value (token `JsonToken.START_OBJECT`)

告诉您不能将对象

{"bidAmount": 500.26}
反序列化为双原语
bidAmount

在这种情况下,我可以建议您创建一个单独的类来将 @RequestBody 映射到对象:

// Getter, setter and etc. if you need
public class YourNameModel {
    private double bidAmount;
}

或接受 bidAmount 作为请求参数@RequestParam:Spring @RequestParam

我还想提请您注意在需要精度的情况下使用 float/double 的危险。以金钱为例:

double total = 0;
total += 5.6;
total += 5.8;
// 11.399999999999

在java中使用双精度保持精度

解决此问题的一种方法是使用 BigDecimal

© www.soinside.com 2019 - 2024. All rights reserved.