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

xu3bshqb  于 7个月前  发布在  Spring
关注(0)|答案(2)|浏览(80)
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认证工作。
在Postman中测试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
我想实现一个拍卖的Web服务,其中多个客户对单一产品的出价和出价开始后,有10秒倒计时,如果任何新的出价在此时间范围内10秒计时器重新启动,否则最高投标人分配的产品。

gcuhipw9

gcuhipw91#

错误代码:Cannot deserialize value of typedoublefrom Object value (tokenJsonToken.START_OBJECT)
告诉您不能将对象{"bidAmount": 500.26}转换为双原语bidAmount
在这种情况下,我可以建议你创建一个单独的类来将@RequestBodyMap到一个对象:

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


retain precision with double in java
解决此问题的一种方法是使用BigDecimal

4dc9hkyq

4dc9hkyq2#

该错误是由请求负载和您要解析的对象之间不匹配引起的。要匹配数据和类,您需要:
1.修改封装类以匹配有效负载。这已经在other answer中介绍过了,所以我不再赘述。
1.更改payload以匹配double -例如"123.43""11",是正确的body以将其转换为doublefloatBigDecimal
此外,由于您正在处理货币,请考虑使用BigDecimal,而不是double。浮点类型对于财务操作不够精确-Why not use Double or Float to represent currency?

相关问题