Не удалось записать JSON: 503 служба временно недоступна;Вложенным исключением является com.fasterxml.jackson.databind.JsonMappingException - PullRequest
0 голосов
/ 02 марта 2019

Мое приложение работает нормально, если у меня в базе данных 2 записи или меньше, но если я добавлю больше данных, я получу это предупреждение в maven и сообщение об ошибке:

2019-03-02 21:36:44.642  WARN 14734 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: 503 Service Temporarily Unavailable; nested exception is com.fasterxml.jackson.databind.JsonMappingException: 503 Service Temporarily Unavailable (through reference chain: java.util.ArrayList[2])]

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

Мой код:

package com.awesome2048.score;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
public class ScoreController {

    @Autowired
    ScoreRepository repository;

    @GetMapping("/scores")
    public List<Score> fetchScores() throws JsonProcessingException {
        List<Score> scores = (List<Score>) repository.findAll();
        return scores;
    }

}

Оценка объекта:

package com.awesome2048.score;

import javax.persistence.*;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.web.client.RestTemplate;

@JsonSerialize(using = ScoreSerializer.class)
@Entity
@Table(name = "scores")
public class Score {

    private static final long serialVersionUID = -3009157732242241606L;

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

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "score", nullable = false)
    private int score;

    @Column(name = "ip", nullable = false)
    private String ip;

    public Score(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public Score() {}

    public String getName() {
        return this.name;
    }

    public int getScore() {
        return this.score;
    }

    public String getIp() {
        return this.ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getCountryCode() {
        String endpoint = "http://api.ipinfodb.com/v3/ip-country/?key=62ee2a10303261af0cf55d6eb2c807c8db5e6fa539fe5ba843c341f4062bfaea&ip= " + this.getIp();
        RestTemplate restTemplate = new RestTemplate();
        String countryCode = restTemplate.getForObject(endpoint, String.class).split(";")[3];
        return countryCode;
    }
}

Я также реализовал пользовательский сериализатор:

package com.awesome2048.score;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

public class ScoreSerializer extends StdSerializer<Score> {

    public ScoreSerializer() {
        this(null);
    }

    public ScoreSerializer(Class<Score> t) {
        super(t);
    }

    @Override
    public void serialize(Score score, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("name", score.getName());
        jsonGenerator.writeNumberField("score", score.getScore());
        jsonGenerator.writeStringField("countryCode", score.getCountryCode());
        jsonGenerator.writeEndObject();
    }
}

1 Ответ

0 голосов
/ 03 марта 2019

Причина в том, что ваш метод get:

public String getCountryCode() {
 String endpoint = "http://api.ipinfodb.com/v3/ip-country/?key=62ee2a10303261af0cf55d6eb2c807c8db5e6fa539fe5ba843c341f4062bfaea&ip= " + this.getIp();
 RestTemplate restTemplate = new RestTemplate();
 String countryCode = restTemplate.getForObject(endpoint, String.class).split(";")[3];
 return countryCode;
}

Вы используете ipinfodb API, который имеет ограничение.Информация с их страницы:

Для сохранения стабильности бесплатного сервиса к нашим серверам API применяется ограничение 2 запросов в секунду .Любой IP-адрес, запрашивающий API быстрее, чем эта скорость, будет временно заблокирован нашим брандмауэром.Ваш IP будет навсегда заблокирован, если вы продолжаете использовать сервер API, игнорируя это ограничение скорости.

getter, как это классический пример побочного эффекта в программировании .Вы не можете вызывать другие сервисы, записывать данные на диск в POJO методах, которые предназначены для переменной get/set.Вместо этого попробуйте создать пакетное задание, которое будет сканировать таблицу scores и обновлять необходимую информацию.Эта реализация должна заботиться об ограничении сервера 2 requests per second.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...