Разбор массива JSON init одиночного объекта в Spring boot Rest Controller - PullRequest
0 голосов
/ 22 мая 2018

Все, что мне нужно, поможет разобрать объект на базе класса.У меня есть список объектов Imp.я не хочу, чтобы он отображал все в класс и создавал весь объект. Мне нужен только первый объект Imp в моем классе RtbRequest.

Причина: - почему мне нужно сделать это.В imp json пользователь отправляет не количество объектов imp в списке и требуется для одного объекта.Я хотел бы разобрать все.Возможно ли это

Мой класс Pojo

@JsonInclude(JsonInclude.Include.NON_NULL)
public class RtbRequest {

   // number of attribute
    private Imp imp;

    public void setImp(Imp imp) {
        this.imp = imp;
    }

}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Imp {

   // number of attribute
   @JsonIgnore
   private Map<String, String> impMap = new HashMap<>();
   private String id;
   private Double bidfloor;
    //final-map
    public void setId(String id) {
        log.info("set--id--rtb--Imp");
        this.id = id;
        impMap.put("impid", getId());
    }


}

Мой объект Json

{
    "id": "ded06290-f586-45c6-bbcb-015adba03e39",
    "imp": [{
            "id": "1",
            "video": {
                "linearity": 1,
                "maxduration": 120,
                "protocols": [2, 5, 3, 6],
                "w": 1280,
                "h": 720,
                "startdelay": 0,
                "skip": 1,
                "sequence": 1,
                "playbackmethod": [1, 2, 3],
                "api": [2]
            },
            "bidfloor": 0.0,
            "secure": 1

        },
        {
            "id": "2",
            "video": {
                "linearity": 1,
                "maxduration": 120,
                "protocols": [2, 5, 3, 6],
                "w": 1280,
                "h": 720,
                "startdelay": 0,
                "skip": 1,
                "sequence": 1,
                "playbackmethod": [1, 2, 3],
                "api": [2]
            },
            "bidfloor": 0.0,
            "secure": 1
        }
    ]

}

Мой RestController

@RequestMapping(value= { "/request/{partner}"}, method = RequestMethod.POST)
public Map<String, String> getRtbResponse(@PathVariable String partner, @RequestBody RtbRequest request) {}

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Все Извините за позднее воспроизведение этой проблемы. Я справился с этим с помощью фильтра Cross.Сначала я обновляю свой список IMP до Объект , после чего я обновляю поток ReadHttpServletRequest , добавляя этот запрос в изменение do-filer.

Основная ключевая точка

Примечание: - final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (getNewRequest (). GetBytes ());

@Component
public class Cross implements Filter {

    private final static Logger log = LoggerFactory.getLogger(Cross.class);

    //********************************
    //           Filter Config      //
    //********************************
    private static Integer count = 0;
    private Long before;


    @Autowired
    ValidatorService validatorService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {

        try {

            // response
            log.info("=================Request-Start-"+(count++)+"-=====================");
            before = System.currentTimeMillis();
            ReadHttpServletRequest requestWrapper = new ReadHttpServletRequest((HttpServletRequest) servletRequest);

            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "X-requested-with, Content-Type");

            String body = requestWrapper.getNewRequest();
            String header = requestWrapper.getHeader();
            if (body != null && header != null) {
                /*
                * Note:- This below line's first update the request and conver the imp's to imp by getting
                * the single first index object. if the object is not their this will not process ad send the simple same
                * json string for validation if the string valid then dofilter map the json into @Pojo.
                * */
                log.info("New:- "+"header " + header + ", body " + body);
                if (validatorService.isResponseValidator(body, InputType.REQUEST.toString().equals("REQUEST") ? InputType.REQUEST : null)) {
                    filterChain.doFilter(requestWrapper, servletResponse);
                } else {
                    /*
                    * Note:- IF Validator fail this will show error
                    * if imp's size 0 then here
                    * if imp's object not their then here
                    * */
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    String responseMessage = "{\"result\": \"Oops an error happened!\nSomething bad happened uh-oh!\"}";
                    response.getWriter().print(responseMessage);
                }
            }
        }catch (NullPointerException e) {
            log.error("--Error--> "+ e.getMessage());
            filterChain.doFilter(servletRequest, servletResponse);

        }finally {
            long result = System.currentTimeMillis() - before;
            log.info("Total response time -> (" + (result) + ") miliseconds");
            log.info("=================Request-End=====================");
        }
    }

    @Override
    public void destroy() { }

}


public class ReadHttpServletRequest extends HttpServletRequestWrapper {

    private final static Logger log = LoggerFactory.getLogger(Cross.class);

    private String body = "";
    private String newBody = "";
    private String header = "";
    private final String IMP = "imp";

    public ReadHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        BufferedReader bufferedReader = request.getReader();
        String line;
        StringBuffer stringBuffer = new StringBuffer();
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line);
        }
        setBody(stringBuffer.toString());
        // fetch header
        this.setHeader(request.getHeader("x-openrtb-version"));
        log.info("Old:- "+"header " + getHeader() + ", body " + getBody());
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream =
                new ByteArrayInputStream(getNewRequest().getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
            @Override
            public boolean isFinished() { return false; }
            @Override
            public boolean isReady() { return false; }
            @Override
            public void setReadListener(ReadListener listener) {}

        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public void setBody(String body) {
        log.info("Body-set");
        this.body = body;
        // set the new body also
        setNewRequest(getUpdateRequestBody(getBody()));
    }
    public void setHeader(String header) {
        log.info("Header-set");
        this.header = header;
    }

    public String getBody() {
        log.info("Body-get");
        return this.body;
    }
    public String getHeader() {
        log.info("Header-get");
        return this.header;
    }

    private String getUpdateRequestBody(String body) {

        JSONObject jsonRequest = (JSONObject) JSONSerializer.toJSON(body);
        /**
         * Find the imp's list and convert into the json-object then add into the request as update's
         * */
        if(jsonRequest.get(IMP) != null) {
            JSONArray jsonArray = jsonRequest.getJSONArray(IMP);
            if(jsonArray != null && (jsonArray.isArray() && jsonArray.size() > 0)) {
                JSONObject impObject = jsonRequest.getJSONArray(IMP).getJSONObject(0);
                // remove the list of imp
                jsonRequest.remove(IMP);
                // add the new one into the json reqeust
                jsonRequest.put(IMP, impObject);
            }
        }
        return jsonRequest.toString();
    }

    private void setNewRequest(String body) {
        log.info("newBody set");
        this.newBody = body;
    }

    public String getNewRequest() {
        log.info("newBody get");
        return this.newBody;
    }
}
0 голосов
/ 22 мая 2018

Сериализация JSON работает лучше всего, если вы сериализуете в строгие типы, поэтому каждый объект JSON обычно отображается непосредственно в класс Java.Если все ваши элементы выглядят так:

{
    "id": "1",
    "exp": 3600,
    "secure": 0,
    "instl": 1
}

, вы должны создать идентичный класс Java с геттерами и сеттерами

Class Item {
    String id;
    long exp;
    int secure;
    int instl;
    // setters and getter
}

Подпись метода контроллера должна быть:

 @RequestMapping(value= { "/request/{partner}"}, method = 
 RequestMethod.POST)
public Map<String, String> getRtbResponse(@RequestBody List<Item> data, @PathVariable String partner) {}

Если каждый партнер отправляет данные в разных форматах, решение может зависеть от погодных условий, в которых вам необходимо обрабатывать данные, или просто сохранять их.Если вам «просто» нужно хранить данные, а не обрабатывать их, вы можете использовать тот факт, что все объекты JSON могут обрабатываться как карты, поэтому ваш контроллер можно сделать так:

 @RequestMapping(value= { "/request/{partner}"}, method = 
 RequestMethod.POST)
public Map<String, String>> getRtbResponse(@RequestBody List<Map<String, Object>> data, @PathVariable String partner) {}

Однако, если вам нужно обрабатывать данные каким-либо образом, использование Map<String, Object> обычно не является хорошим планом.

В Java мы могли бы создать Interface PartnerItem и несколько подклассов, каждый из которых соответствовал бы данным, представленным каждым партнером.Это также возможно в JSON, но поскольку у объектов JSON нет имени, его необходимо включить другим способом.Вот ссылка на руководство, которое объясняет , как работает наследование Джексона

Примечание : лично я никогда не использую массив в качестве структуры JSON верхнего уровня при разработке API, явсегда используйте объект.Причина в том, что я могу добавить дополнительные поля к объекту, что позволяет мне изменять API обратно совместимым способом - это невозможно, если ваша структура верхнего уровня представляет собой массив.

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