在Spring引导静态控制器中解析Json数组init单个对象

时间:2018-05-22 06:05:03

标签: java spring spring-mvc spring-boot

我需要一些帮助来解析类基础上的对象。 我有一个Imp对象列表。我不想让它全部映射到类并创建所有对象。 我只需要在我的RtbRequest类中使用Imp 的第一个对象。

原因: - 为什么我需要这样做。在imp json user 中,在列表中发送非数量的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 :(得分:0)

如果序列化为强类型,则JSON序列化效果最佳,因此每个JSON对象通常会直接映射到Java类。如果您的所有商品都是:

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

你应该用getter和setter创建一个相同的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对象没有名称,因此需要以其他方式包含它。以下是指向how Jackson inheritance works

的指南的链接

注意:我个人在设计API时从不使用数组作为我的顶级JSON结构,我总是使用对象。原因是我可以向对象添加其他字段,这允许我以向后兼容的方式改变API - 如果您的顶级结构是数组,这是不可能的。

答案 1 :(得分:0)

对于这个问题的晚期重播,我很抱歉通过使用Cross过滤器处理这个问题。 我首先将 IMP 列表更新为对象,然后通过将此请求添加到do-filer更改中来更新 ReadHttpServletRequest 流。

主要要点

  

注意: - 最后的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;
    }
}