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
我想实现一个拍卖网络服务,其中多个客户对单一产品出价,出价开始后有 10 秒倒计时,如果在该时间范围内有任何新出价,则 10 秒计时器重新启动,否则最高出价者分配该产品。
这个错误:
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
解决此问题的一种方法是使用 BigDecimal