JSON получено отличается от JSON, отправленных с помощью Spring Rest и Hibernate - PullRequest
0 голосов
/ 01 апреля 2020

У меня проблемы с Spring Rest & Hibernate. Я выполняю вызовы API из моего Android приложения, и, похоже, возникла проблема с одним из вызовов POST.

У меня есть 2 класса: Player и Game

@Entity
@Table(name = "Game", schema = "statistics")
public class GameEntity {
    private int matchId;
    private int firstPlayer;
    private int secondPlayer;

    @Column(name = "first_player")
    public int getFirstPlayer() {
        return firstPlayer;
    }

    public void setFirstPlayer(int firstPlayer) {
        this.firstPlayer = firstPlayer;
    }

    @Column(name = "second_player")
    public int getSecondPlayer() {
        return secondPlayer;
    }

    public void setSecondPlayer(int secondPlayer) {
        this.secondPlayer = secondPlayer;
    }
}

@Entity
@Table(name = "Players", schema = "statistics")
public class PlayersEntity {
    private int playerId;
    private String name;

    @Id
    @Column(name = "player_id")
    public int getPlayerId() {
        return playerId;
    }

    public void setPlayerId(int id) {
        this.playerId = id;
    }

    @Basic
    @Column(name = "name")
    public String getName() {
        return name;
    }Ga

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

Когда я отправляю POST для Player: это работает. Однако, когда я делаю то же самое для Game, он отклоняет его, потому что он не получает значения правильно - когда я отлаживал @RequestBody, я обнаружил, что полученная сущность содержала неправильные значения (все были 0, поскольку все поля являются целыми числами) :

incorrect json values

Несмотря на то, что отправленные JSON имели правильные значения:

correct JSON

И я получаю ошибку SQL (потому что 2 из 3 идентификаторов в Game являются внешними ключами, ссылающимися на Player).

Я действительно не понимаю, почему и Я не знаю, как регистрировать HTTP-запросы / ответы на Spring.

В любом случае, заранее спасибо всем, кто поможет мне найти правильный ответ и оставаться в безопасности.

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Проблема в том, что JSON Десериализация не смотрит на аннотации JPA. Поэтому существует несоответствие между отправляемым JSON, в котором используются свойства snake_case и Java, которые находятся в camelCase

. Существует как минимум 3 варианта решения этой проблемы:

Включить чехол Snake для всего приложения

spring.jackson.property-naming-strategy=SNAKE_CASE

Включить чехол Snake для указанного c class

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class GameEntity {

}

Предоставьте пользовательский конструктор JsonCreator

Обратите внимание, что конструктор по умолчанию также необходим для JPA

@Entity
@Table(name = "Game", schema = "statistics")
public class GameEntity {
    private int matchId;
    private int firstPlayer;
    private int secondPlayer;

    public GameEntity() {}

    @JsonCreator
    public GameEntity(@JsonProperty("match_id") int matchId,
                      @JsonProperty("first_player") int firstPlayer,
                      @JsonProperty("second_player") int secondPlayer) {
        this.matchId = matchId;
        this.firstPlayer = firstPlayer;
        this.secondPlayer = secondPlayer;
    }

    ...

}

Обратите внимание, что существует дополнительное несоответствие: у вас есть matchId в Java и game_id в JSON. Только третий подход позволяет решить эту проблему без переименования поля в Java

0 голосов
/ 01 апреля 2020

Дело в том:

В ваших сущностях поле называется "firstPlayer", тогда как в вашем JSON поле называется "first_player".

Обратите внимание, аннотация @Column указанное вами поле действительно только для хранения в таблице базы данных, а не для JSON преобразований между вашим бэкэндом и внешним интерфейсом.

Для этого я бы, вероятно, построил пользовательский DTO / VO вместо повторного использования вашего @ Объект с соответствующими аннотациями сопоставления Джексона: @ JsonProperty.

@JsonProperty("player_id")
private int playerId;
...