#java #rest #curl #terminal
#java #rest #curl #терминал
Вопрос:
Я работаю с приложением Spring boot, и несколько конечных точек возвращают ошибку
$ curl -X PUT http://localhost:8080/api/v1/users/calculateReward?userId=1 |jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0parse error: Exceeds depth limit for parsing at line 1, column 6472
100 81714 0 81714 0 0 1641k 0 --:--:-- --:--:-- --:--:-- 1662k
curl: (23) Failed writing body (0 != 7978)
Я также получаю сообщение об ошибке parse error: Invalid numeric literal at line 1, column 9
.
Я думаю, что это связано с разделителем каналов, но я ранее использовал его без проблем.
Когда я отлаживаю, я получаю что-то вроде этого Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.user.reward.models.RewardList.toString()
Классы моей модели предоставляются,
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
@NotNull
@NotEmpty
private String name;
@Column(name = "countryName")
@NotNull
@NotEmpty
private String countryName;
/*
* total steps is for the keepign the history of the user movement
* */
@Column(name = "totalSteps")
@Min(value = 0L, message = "The value must be positive")
private int totalSteps;
/*
* current steps is for providing the user reward. We will need to set
* it to zero after processing the user payment
* */
@Column(name = "currentSteps")
@Min(value = 0L, message = "The value must be positive")
private int currentSteps;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RewardList> rewardLists = new ArrayList<>();
public User() {
}
public User(@NotNull @NotEmpty String name, @NotNull @NotEmpty String countryName) {
this.name = name;
this.countryName = countryName;
}
public User(@NotNull @NotEmpty String name, @NotNull @NotEmpty String countryName, @Min(value = 0L, message = "The value must be positive") int totalSteps) {
this.name = name;
this.countryName = countryName;
this.totalSteps = totalSteps;
}
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 String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public int getTotalSteps() {
return totalSteps;
}
public void setTotalSteps(int totalSteps) {
this.totalSteps = totalSteps;
}
public int getCurrentSteps() {
return currentSteps;
}
public void setCurrentSteps(int currentSteps) {
this.currentSteps = currentSteps;
}
public List<RewardList> getRewardLists() {
return rewardLists;
}
public void setRewardLists(RewardList rl) {
this.rewardLists.add(rl);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getTotalSteps() == user.getTotalSteps() amp;amp;
getCurrentSteps() == user.getCurrentSteps() amp;amp;
getId().equals(user.getId()) amp;amp;
getName().equals(user.getName()) amp;amp;
getCountryName().equals(user.getCountryName()) amp;amp;
getRewardLists().equals(user.getRewardLists());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getName(), getCountryName(), getTotalSteps(), getCurrentSteps(), getRewardLists());
}
@Override
public String toString() {
return "User{"
"id=" id
", name='" name '''
", countryName='" countryName '''
", totalSteps=" totalSteps
", currentSteps=" currentSteps
", rewardLists=" rewardLists
'}';
}
}
@Entity
public class RewardList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "reward")
@Min(value = 0L, message = "The value must be positive")
private double reward;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
public RewardList() {
}
public RewardList(User user) {
this.user = user;
}
public RewardList(@Min(value = 0L, message = "The value must be positive") double reward) {
this.reward = reward;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public double getReward() {
return reward;
}
public void setReward(double reward) {
this.reward = reward;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RewardList)) return false;
RewardList list = (RewardList) o;
return Double.compare(list.getReward(), getReward()) == 0 amp;amp;
getId().equals(list.getId()) amp;amp;
getUser().equals(list.getUser());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getReward(), getUser());
}
@Override
public String toString() {
return "RewardList{"
"id=" id
", reward=" reward
", user=" user
'}';
}
}
Я нахожусь в терминале OS X, каково решение проблемы?
Комментарии:
1. вы должны следить за этим в коде. Вы можете очистить ввод, например, с помощью выражения регулярного выражения. Но было бы неплохо увидеть ваш код.
2. Вы обращались к данным JSON
jq
, на которые жалуются? Является ли оно невероятно раздутым и недействительным в качествеjq
состояний? Если да, можно ли это исправить в приложении Spring boot?3. Я обновил вопрос с
java.lang.StackOverflowError
ошибкой
Ответ №1:
У вас есть циклическая зависимость между RewardList
User
объектами и при их отображении toString()
. Пользователь A отобразит награду B, которая отобразит пользователя A, который отобразит награду B … и так далее, пока вы не перейдете StackOverflowError
от рекурсивного toString()
.
Вы можете решить это с помощью:
- не отображаются
rewardLists
данные связи вUser.toString()
- не отображаются
user
данные связи вRewardList.toString()
Я бы выбрал вариант 1, поскольку User
это объект-владелец для этого отношения.
Комментарии:
1. Ошибка исчезает, но я все еще получаю доступ к терминалу
parse error: Exceeds depth limit for parsing at line 1, column 6472 curl: (23) Failed writing body (0 != 8026)
2. И он печатает
User{id=1, name='Robert', countryName='Germany', totalSteps=200, currentSteps=0}