【问题标题】:Output Spring Boot is reversed in Postman在 Postman 中输出 Spring Boot 反转
【发布时间】:2021-12-22 00:51:08
【问题描述】:

我的问题:当我在 Postman 中执行 @Post 时,我从价格中获取数据,但不是小猫数据。

我输入以下内容:

{
    "name": "Frizzle",
    "dateOfBirth": "2019-07-27",
    "weight": 7.1,
    "breed": "Birman",
    "firstVaccination": "yes",
    "secondVaccination": "yes",
    "breedPrice": 8000,
    "firstVaccinationPrice": 80.50,
    "secondVaccinationPrice": 80.10
}

这就是我在 Postman 中得到的:

{
        "id": 3,
        "name": null,
        "dateOfBirth": null,
        "weight": 0.0,
        "breed": null,
        "firstVaccination": null,
        "secondVaccination": null,
        "fileUpload": null,
        "price": {
            "id": 3,
            "broadPrice": 8000.0,
            "firstVaccinationPrice": 80.5,
            "secondVaccinationPrice": 80.1,
            "totalPrice": 8160.6
        }
}

我尝试在几个地方更改代码,但我不明白为什么它输出的是价格部分而不是小猫数据部分。我希望它输出小猫数据。所以基本上我想要的是让他反转它,返回小猫的数据并给出价格为空的数据。

我的文件看起来像这样。

小猫.java

import com.sun.istack.NotNull;

import javax.persistence.*;
import java.time.LocalDate;

@Entity
@Table(name = "kittens")
public class Kitten {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotNull
    private String name;

    @NotNull
    @Column(name = "date_of_birth")
    private LocalDate dateOfBirth;

    @NotNull
    @Column
    private double weight;

    @NotNull
    @Column(name = "breed")
    private String breed;

    @Column(name = "first_vaccination")
    private String firstVaccination;

    @Column(name = "second_vaccination")
    private String secondVaccination;

    @OneToOne(mappedBy = "kitten")
    private FileUpload fileUpload;

    @OneToOne(fetch = FetchType.LAZY,
            mappedBy = "kitten")
    private Price price;

    public Kitten(String name, LocalDate dateOfBirth, double weight, String breed, String firstVaccination, String secondVaccination) {
    }

    public Kitten() {

    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(LocalDate dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public String getBreed() {
        return breed;
    }

    public void setBreed(String breed) {
        this.breed = breed;
    }

    public String getFirstVaccination() {
        return firstVaccination;
    }

    public void setFirstVaccination(String firstVaccination) {
        this.firstVaccination = firstVaccination;
    }

    public String getSecondVaccination() {
        return secondVaccination;
    }

    public void setSecondVaccination(String secondVaccination) {
        this.secondVaccination = secondVaccination;
    }

    public FileUpload getFileUpload() {
        return fileUpload;
    }

    public void setFileUpload(FileUpload fileUpload) {
        this.fileUpload = fileUpload;
    }

    public Price getPrice() {
        return price;
    }

    public void setPrice(Price price) {
        this.price = price;
    }
}

价格.java

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.sun.istack.NotNull;

import javax.persistence.*;

@Entity
@Table(name = "prices")
public class Price {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotNull
    @Column(name = "breed_price")
    private double breedPrice;

    @Column(name = "first_vaccination_price")
    private double firstVaccinationPrice;

    @Column(name = "second_vaccination_price")
    private double secondVaccinationPrice;

    @JsonIgnore
    @OneToOne(fetch = FetchType.LAZY,
            cascade = CascadeType.ALL,
            orphanRemoval = true)
    @JoinColumn(name = "kitten_id")
    private Kitten kitten;

    public Price() {

    }

    public Price(double breedPrice, double firstVaccinationPrice, double secondVaccinationPrice) {
        this.breedPrice = breedPrice;
        this.firstVaccinationPrice = firstVaccinationPrice;
        this.secondVaccinationPrice = secondVaccinationPrice;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public double getBreedPrice() {
        return breedPrice;
    }

    public void setBreedPrice(double breedPrice) {
        this.breedPrice = breedPrice;
    }

    public double getFirstVaccinationPrice() {
        return firstVaccinationPrice;
    }

    public void setFirstVaccinationPrice(double firstVaccinationPrice) {
        this.firstVaccinationPrice = firstVaccinationPrice;
    }

    public double getSecondVaccinationPrice() {
        return secondVaccinationPrice;
    }

    public void setSecondVaccinationPrice(double secondVaccinationPrice) {
        this.secondVaccinationPrice = secondVaccinationPrice;
    }

    public Kitten getKitten() {
        return kitten;
    }

    public void setKitten(Kitten kitten) {
        this.kitten = kitten;
    }

    public Double getTotalPrice() {
        return this.getBreedPrice() + this.getFirstVaccinationPrice() + this.getSecondVaccinationPrice();
    }
}

KittenBuilder.java

import nl.danielle.cattery.payload.KittenRequest;

import java.time.LocalDate;

public class KittenBuilder {

    //Kitten    
    private String name;
    private LocalDate dateOfBirth;
    private double weight;
    private String breed;
    private String firstVaccination;
    private String secondVaccination;

    //Price
    private double breedPrice;
    private double firstVaccinationPrice;
    private double secondVaccinationPrice;

    public KittenBuilder(KittenRequest kittenRequest) {
        this.name = kittenRequest.getName();
        this.dateOfBirth = kittenRequest.getDateOfBirth();
        this.weight = kittenRequest.getWeight();
        this.breed = kittenRequest.getBreed();
        this.firstVaccination = kittenRequest.getFirstVaccination();
        this.secondVaccination = kittenRequest.getSecondVaccination();
        this.breedPrice = kittenRequest.getBreedPrice();
        this.firstVaccinationPrice = kittenRequest.getFirstVaccinationPrice();
        this.secondVaccinationPrice = kittenRequest.getSecondVaccinationPrice();
    }

    public Kitten buildKitten() {
        return new Kitten(name, dateOfBirth, weight, breed, firstVaccination, secondVaccination);
    }

    public Price buildPrice() {
        return new Price(breedPrice, firstVaccinationPrice, secondVaccinationPrice);
    }
}

KittenRequest.java

import com.sun.istack.NotNull;

import java.time.LocalDate;

public class KittenRequest {
    //Kitten
    @NotNull
    private String name;
    @NotNull
    private LocalDate dateOfBirth;
    @NotNull
    private double weight;
    @NotNull
    private String breed;
    private String firstVaccination;
    private String secondVaccination;

    //Price
    @NotNull
    private double breedPrice;
    private double firstVaccinationPrice;
    private double secondVaccinationPrice;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(LocalDate dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public String getBreed() {
        return breed;
    }

    public void setBreed(String breed) {
        this.breed = breed;
    }

    public String getFirstVaccination() {
        return firstVaccination;
    }

    public void setFirstVaccination(String firstVaccination) {
        this.firstVaccination = firstVaccination;
    }

    public String getSecondVaccination() {
        return secondVaccination;
    }

    public void setSecondVaccination(String secondVaccination) {
        this.secondVaccination = secondVaccination;
    }

    public double getBreedPrice() {
        return breedPrice;
    }

    public void setBreedPrice(double breedPrice) {
        this.breedPrice = breedPrice;
    }

    public double getFirstVaccinationPrice() {
        return firstVaccinationPrice;
    }

    public void setFirstVaccinationPrice(double firstVaccinationPrice) {
        this.firstVaccinationPrice = firstVaccinationPrice;
    }

    public double getSecondVaccinationPrice() {
        return secondVaccinationPrice;
    }

    public void setSecondVaccinationPrice(double secondVaccinationPrice) {
        this.secondVaccinationPrice = secondVaccinationPrice;
    }
}

KittenController.java

import nl.danielle.cattery.model.FileUpload;
import nl.danielle.cattery.payload.KittenRequest;
import nl.danielle.cattery.payload.ResponseMessage;
import nl.danielle.cattery.service.FileStorageServiceImpl;
import nl.danielle.cattery.service.KittenService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;

@RestController
@RequestMapping(value = "/kittens")
public class KittenController {

    final KittenService kittenService;

    final FileStorageServiceImpl storageService;

    public KittenController(KittenService kittenService, FileStorageServiceImpl storageService) {
        this.kittenService = kittenService;
        this.storageService = storageService;
    }

    @GetMapping(value = "")
    public ResponseEntity<Object> getKittens() {
        return ResponseEntity.ok().body(kittenService.getKittens());
    }

    @GetMapping(value = "/{id}")
    public ResponseEntity<Object> getKitten(@PathVariable("id") long id) {
        return ResponseEntity.ok().body(kittenService.getKittenById(id));
    }

    @PostMapping(value = "/add")
    public ResponseEntity<Object> saveKitten(@RequestBody KittenRequest kitten) {
        long newId = kittenService.saveKitten(kitten);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(newId).toUri();

        return ResponseEntity.created(location).build();
    }

    @PutMapping(value = "/{id}")
    public ResponseEntity<Object> updateKitten(@PathVariable("id") long id, @RequestBody KittenRequest kitten) {
        kittenService.updateKitten(id, kitten);
        return ResponseEntity.noContent().build();
    }

    @PutMapping(value = "/{id}/price")
    public ResponseEntity<Object> updatePrice(@PathVariable("id") long id, @RequestBody KittenRequest price) {
        kittenService.updatePrice(id, price);
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping(value = "/{id}")
    public ResponseEntity<Object> deleteKitten(@PathVariable("id") long id) {
        kittenService.deleteKitten(id);
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/upload/kittenid/{id}")
    public ResponseEntity<ResponseMessage> uploadFile(@PathVariable long id, @RequestParam("file") MultipartFile file) {

        try {
            storageService.store(file, id);

            String message = "Uploaded the file successfully: " + file.getOriginalFilename();
            return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));

        } catch (Exception e) {
            String message = "Could not upload the file: " + file.getOriginalFilename() + "!";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
        }
    }

    @GetMapping("/download/{id}")
    public ResponseEntity<byte[]> getFileById(@PathVariable("id") String id) {
        FileUpload fileUpload = storageService.getFileById(id);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileUpload.getName() + "\"")
                .body(fileUpload.getData());
    }
}

KittenService.java

package nl.danielle.cattery.service;

import nl.danielle.cattery.exceptions.DatabaseErrorException;
import nl.danielle.cattery.exceptions.RecordNotFoundException;
import nl.danielle.cattery.model.Kitten;
import nl.danielle.cattery.model.KittenBuilder;
import nl.danielle.cattery.model.Price;
import nl.danielle.cattery.payload.KittenRequest;
import nl.danielle.cattery.repository.KittenRepository;
import nl.danielle.cattery.repository.PriceRepository;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class KittenServiceImpl implements KittenService {

    final KittenRepository kittenRepository;

    final PriceRepository priceRepository;

    public KittenServiceImpl(KittenRepository kittenRepository, PriceRepository priceRepository) {
        this.kittenRepository = kittenRepository;
        this.priceRepository = priceRepository;
    }

    @Override
    public Collection<Kitten> getKittens() {
        return kittenRepository.findAll();
    }

    @Override
    public Kitten getKittenById(long id) {
        if (!kittenRepository.existsById(id)) {
            throw new RecordNotFoundException();
        }
        return kittenRepository.findById(id).orElse(null);
    }

    @Override
    public long saveKitten(KittenRequest kittenRequest) {

        Kitten newKitten = new KittenBuilder(kittenRequest).buildKitten();
        Price newPrice = new KittenBuilder(kittenRequest).buildPrice();

        Price savedPrice = priceRepository.save(newPrice);
        newKitten.setPrice(savedPrice);
        newPrice.setKitten(newKitten);

        return kittenRepository.save(newKitten).getId();
    }

    @Override
    public void updateKitten(long id, KittenRequest kitten) {
        if (kittenRepository.existsById(id)) {
            try {
                Kitten existingKitten = kittenRepository.findById(id).orElse(null);
                existingKitten.setName(kitten.getName());
                existingKitten.setDateOfBirth(kitten.getDateOfBirth());
                existingKitten.setWeight(kitten.getWeight());
                existingKitten.setBreed(kitten.getBreed());
                existingKitten.setFirstVaccination(kitten.getFirstVaccination());
                existingKitten.setSecondVaccination(kitten.getSecondVaccination());
                kittenRepository.save(existingKitten);
            } catch (Exception ex) {
                throw new DatabaseErrorException();
            }
        } else {
            throw new RecordNotFoundException();
        }
    }

    @Override
    public void updatePrice(long id, KittenRequest price) {
        if (priceRepository.existsById(id)) {
            try {
                Price existingPrice = priceRepository.findById(id).orElse(null);
                existingPrice.setBreedPrice(price.getBreedPrice());
                existingPrice.setFirstVaccinationPrice(price.getFirstVaccinationPrice());
                existingPrice.setSecondVaccinationPrice(price.getSecondVaccinationPrice());
                priceRepository.save(existingPrice);
            } catch (Exception ex) {
                throw new DatabaseErrorException();
            }
        } else {
            throw new RecordNotFoundException();
        }
    }

    @Override
    public void deleteKitten(long id) {
        kittenRepository.deleteById(id);
    }
}

【问题讨论】:

    标签: java spring-boot spring-data-jpa postman sql-null


    【解决方案1】:

    我对您的代码有很多话要说,但让我们看看这里的主要问题是什么。如果您查看KittenBuilder,问题很简单,您使用此构建器创建了一只小猫,但您的小猫构造函数为空。

    public Kitten(String name, LocalDate dateOfBirth, double weight, String breed, String firstVaccination, String secondVaccination) {
        this.name = name;
        this.dateOfBirth = dateOfBirth;
        this.weight = weight;
        this.breed = breed;
        this.firstVaccination = firstVaccination;
        this.secondVaccination = secondVaccination;
    }
    

    这将填充 Kitten 对象,您就可以开始了。


    关于您的代码的一些建议

    如果您想知道为什么在指定 null 约束时它会保存 null 值,因为最新版本的 spring boot 没有在 web 启动器中包含验证启动器,您必须自己包含它。

    在你pom.xml添加以下依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    

    并且您必须在您的服务中包含注释 @Transactional 以使您的操作具有原子性,例如在您的 create kitten 方法中,您希望以原子方式保持价格和小猫。

    @Service
    @Transactional
    class KittenServiceImpl implementes ...
    

    还有一个最佳实践是不要直接在控制器中使用您的实体,使用DTO(数据传输对象),因此您可以将您想要的属性从您的实体映射到您的 DTO(这样您可以包括只有你的小猫属性并留下价格实体)。

    最后的奖励:

    public Kitten getKittenById(long id) {
        if (!kittenRepository.existsById(id)) {
           throw new RecordNotFoundException("");
        }
        return kittenRepository.findById(id).orElse(null);
    }
    

    这可以简化为:

    public Kitten getKittenById(long id) {
        return kittenRepository.findById(id).orElseThrow(() -> new RecordNotFoundException());
    }
    

    【讨论】:

    • 你在开玩笑吧!我检查了 1000 次代码,只是没有看到构造函数是空的。感谢所有关于代码的提示,这些是我在课堂上没有得到的东西。非常感谢!
    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 2018-08-14
    • 2020-05-23
    • 2021-07-19
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多