All I need some help to parse the object on the class base.
I have a list of Imp object. i don't want it map all to the class and create the all object. I need only the First object of the Imp in my RtbRequest class.
Reason:- why i need to do like that. In imp json user send the non-number of imp object's in list and required on one object. i'd want to parse all. Is this possible
My Pojo Class
@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());
}
}
My Json Object
{
"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
}
]
}
My RestController
@RequestMapping(value= { "/request/{partner}"}, method = RequestMethod.POST)
public Map<String, String> getRtbResponse(@PathVariable String partner, @RequestBody RtbRequest request) {}
JSON serialization works best if you serialize into strong types, so each JSON object will normally map directly to a Java class. If all your items look like:
{
"id": "1",
"exp": 3600,
"secure": 0,
"instl": 1
}
you should create an identical Java class, with getters and setters
Class Item {
String id;
long exp;
int secure;
int instl;
// setters and getter
}
The controller method signature should be:
@RequestMapping(value= { "/request/{partner}"}, method =
RequestMethod.POST)
public Map<String, String> getRtbResponse(@RequestBody List<Item> data, @PathVariable String partner) {}
If each partner sends in data in different formats, the solution may depend on weather you need to process the data, or simply store it.
If you 'just' need to store the data and not process it, you can use the fact that all JSON object can be handled as maps, so it is possible to make your controller like this:
@RequestMapping(value= { "/request/{partner}"}, method =
RequestMethod.POST)
public Map<String, String>> getRtbResponse(@RequestBody List<Map<String, Object>> data, @PathVariable String partner) {}
However if you need to process the data in any way, using Map<String, Object>
is generally not a good plan.
In Java we could create an Interface PartnerItem
and multiple subclasses, each matching the data submitted by each partner. This is also possible in JSON, but since JSON objects have no name, it needs to be included in some other way. Here is a link to a guide that explains how Jackson inheritance works
Note: Personally I never use array as my top level JSON structure when I design APIs, I always use object. The reason is that I can add additional fields to an object, which allows me to mutate the API in a backwards compatible way - this is not possible if your top-level structure is an array.
All Sorry for late replay for this issue i handle this by use of Cross filter.
I first update my IMP list to Object after that i update the ReadHttpServletRequest stream by adding this Request into do-filer change.
Main Key Point
Note:- 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;
}
}