2017-06-02 33 views
0

当指定某个时段时,我们准备一个Web API,该API返回该时段中每个日期的数据。如何设计模型以存储动态字段ResponseBody

具体地说,POST

{"targetFrom": "2016-04-01", "targetTo": "2016-04-03"}} 

以下JSON数据被返回。

{ 
    "meta": { 
     "StartTime": "2017-06-01T06:50:28.001344102Z", 
     "execute_time": 7532.0517, 
     "host": "49a6ced149d2", 
     "rid": "" 
    }, 
    "result": { 
     "2016-04-01": { 
      "0:num": 121, 
      "0:price": 5244614, 
      "1:num": 124, 
      "1:price": 6324547, 
      "2:num": 115, 
      "2:price": 5604491 
     }, 
     "2016-04-02": { 
      "0:num": 125, 
      "0:price": 6321222, 
      "1:num": 117, 
      "1:price": 5835030, 
      "2:num": 118, 
      "2:price": 5771826 
     }, 
     "2016-04-03": { 
      "0:num": 118, 
      "0:price": 5486071, 
      "1:num": 131, 
      "1:price": 6563447, 
      "2:num": 111, 
      "2:price": 5740078 
     }, 
     "subTotal": { 
      "total_2016-04-01_num": 360, 
      "total_2016-04-01_price": 17173652, 
      "total_2016-04-02_num": 360, 
      "total_2016-04-02_price": 17928078, 
      "total_2016-04-03_num": 360, 
      "total_2016-04-03_price": 17789596 
      }, 
     "total": { 
      "num": 1080, 
      "price": 52891326 
     } 
    } 
} 

问题是日期字段的一部分,如“2016-04-01”。 我想在SpringBoot的应用程序端接受这个,考虑处理修改,并且想要定义一个合适的模型。 但是,我找不到一个好方法。

首先,我认为以下是愚蠢的做法。

@JsonProperty("2016-04-01") 
private ResAnalyzeResultDayDto result_20160401; 

这是愚蠢的,因为它不能对应于取决于参数targetFrom或targetTo在询价时返回的数据。

那么,我们如何定义一个模型来处理响应数据,并根据请求动态变化呢? 如果你有一个好主意,请告诉我。

附加说明: 我没有相处得很好,因为我写了下面的代码。

@JsonProperty("[0-9]{4}-[0-9]{2}-[0-9]{2}") 
private Map<String,ResAnalyzeResultSubTotalDayDto> maps; 

首先,“@ JsonProperty”似乎并不能够使用正则表达式,我不认为它会自动设置地图的关键。

请求部分的代码使用“RestTemplate”。

ReqTotalSalesStatusDto reqGoMonth = new ReqTotalSalesStatusDto(); 
reqGoMonth.setStrTo("2016-04-03"); 
reqGoMonth.setStrFrom("2016-04-01"); 

// Jackson2HttpMessage 
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

ResponseEntity<ResAnalyzeDto> resultGoMonth = restTemplate.exchange(
    "http://localhost:18000/analyze" 
    , HttpMethod.POST 
    , new HttpEntity<>(reqGoMonth) 
    , ResAnalyzeDto.class); 

回答

1

你可以把所有的结果场那样的地图对象:

private Map<String,Object> result; 
result.forEach((k,v)->{ 
System.out.println("key: " + k + " value: " + v); 
if("total".equals(k)){ 
    Total total = (Total) v; 
} else if("subTotal".equals(k)) { 
    SubTotal subTotal = (SubTotal) v; 
} else { 
    ResAnalyzeResultDayDto resAnalyzeResultDayDto = (ResAnalyzeResultDayDto) v; 
} 
}); 

之后,你可以检查的密钥。至于你的示例地图值可以是3个不同的对象。 Total,SubTotal或DayInfo(ResAnalyzeResultDayDto)。您可以轻松了解总计和小计,并可将它们转换为相应的对象类型。对于地图的其他值,它们将转换为ResAnalyzeResultDayDto。

0

谢谢barbakini

我试图在我教的方式,但我不能把它很好的演员,现在是一步到位。 。

的日志如下

key: 2016-04-01 value: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
v.toString(): {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
2017-06-02 17:12:49.962 [maekawa-PC-http-nio-9999-exec-3] ACS XXX:[id: tenant_id:] url:/api/v1/totalsalesstatus/common3 status:200 elapsedNanoTime:8455258 
2017-06-02 17:12:49.963 [maekawa-PC-http-nio-9999-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.temp.sample.management.report.api.dto.ResAnalyzeResultDayDto] with root cause 

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.temp.sample.management.report.api.dto.ResAnalyzeResultDayDto 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.lambda$createFinalResultObj3$3(TotalSalesStatusCommandService.java:609) 
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.createFinalResultObj3(TotalSalesStatusCommandService.java:600) 
+0

嗨,你能分担率R esAnalyzeResultDayDto类和代码片段在哪里执行投射?原因可能是变量名称不匹配(Java不允许带有':'的变量名,比如2:num) – barbakini

0

型号

@Data 
public class ResAnalyzeResultDayDto { 

@JsonProperty("0:num") 
private int num0; 

@JsonProperty("0:price") 
private int price0; 

@JsonProperty("1:num") 
private int num1; 

@JsonProperty("1:price") 
private int price1; 

@JsonProperty("2:num") 
private int num2; 

@JsonProperty("2:price") 
private int price2; 
} 

代码

private ResponseEntity<TotalSalesStatus> createFinalResultObj3(TotalSalesStatus resultObj, 
     List<ResponseEntity<ResAnalyzeDto3>> goResponseEntityList ,String disposalDate) { 

    String methodName = Thread.currentThread().getStackTrace()[1].getMethodName(); 
    this.logger.info("■■UT:[{}] ", methodName); 

    int sumTotalNum = 0; 
    int sumTotalPrice = 0; 

    TotalSalesStatusGrandson totalSalesStatusDay = new TotalSalesStatusGrandson(); 
    resultObj.setTotalSalesStatusDay(totalSalesStatusDay); 

    TotalSalesStatusGrandson totalSalesStatusMonth = new TotalSalesStatusGrandson(); 
    resultObj.setTotalSalesStatusMonth(totalSalesStatusMonth); 

    boolean targetMonthFlag = false; 
    for(ResponseEntity<ResAnalyzeDto3> e : goResponseEntityList){ 
     ResAnalyzeDto3 dto = e.getBody(); 
     ResAnalyzeMetaDto meta = dto.getMeta(); 
     Map<String,Map<String,?>> resu = dto.getResult(); 
     this.logger.info("■■UT:[{}] ResAnalyzeMetaDto :{}", methodName,meta.toString()); 
     this.logger.info("■■UT:[{}] ResAnalyzeResultDto:{}", methodName,resu.toString()); 
      resu.forEach((k,v)->{ 
       System.out.println("key: " + k + " value: " + v); 
       System.out.println("v.toString(): " + v.toString()); 
       String val = v.toString(); 
       ObjectMapper mapper = new ObjectMapper(); 
       if("total".equals(k)){ 
//      ResAnalyzeResultTotalDto total = (ResAnalyzeResultTotalDto) v; 
        try { 
         ResAnalyzeResultTotalDto total = mapper.readValue(val,ResAnalyzeResultTotalDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } else if("subTotal".equals(k)) { 
//      ResAnalyzeResultSubTotalDto subTotal = (ResAnalyzeResultSubTotalDto) v; 
        try { 
         ResAnalyzeResultSubTotalDto subTotal = mapper.readValue(val,ResAnalyzeResultSubTotalDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } else { 
//      ResAnalyzeResultDayDto resAnalyzeResultDayDto = (ResAnalyzeResultDayDto) v; 
        try { 
         ResAnalyzeResultDayDto resAnalyzeResultDayDto = mapper.readValue(val,ResAnalyzeResultDayDto.class); 
        } catch (Exception e1) { 
         e1.printStackTrace(); 
        } 
       } 
      }); 
    } 
    TotalSalesStatusGrandson totalSalesStatusYear = new TotalSalesStatusGrandson(); 
    totalSalesStatusYear.setTotal(new BigDecimal(sumTotalPrice)); 
    resultObj.setTotalSalesStatusYear(totalSalesStatusYear); 
    resultObj.setUnitLabel("sample"); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_JSON); 
    ResponseEntity<TotalSalesStatus> result = new ResponseEntity<TotalSalesStatus>(resultObj, headers, HttpStatus.CREATED); 
    return result; 
} 

日志

2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] 
2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] ResAnalyzeMetaDto :ResAnalyzeMetaDto(startTime=2017-06-05T04:33:48.499791734Z, executeTime=2.1928, host=bb8bfd9acf04, rid=) 
2017-06-05 13:33:48.382 [maekawa-PC-http-nio-9999-exec-1] INFO SAMPLE:[id: tenant_id:] j.c.b.b.m.r.a.TotalSalesStatusCommandService ■■UT:[createFinalResultObj3] ResAnalyzeResultDto:{2016-04-01={0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491}, 2016-04-02={0:num=125, 0:price=6321222, 1:num=117, 1:price=5835030, 2:num=118, 2:price=5771826}, 2016-04-03={0:num=118, 0:price=5486071, 1:num=131, 1:price=6563447, 2:num=111, 2:price=5740078}, subTotal={total_2016-04-01_num=360, total_2016-04-01_price=17173652, total_2016-04-02_num=360, total_2016-04-02_price=17928078, total_2016-04-03_num=360, total_2016-04-03_price=17789596}, total={num=1080, price=52891326}} 
key: 2016-04-01 value: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
v.toString(): {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491} 
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('0' (code 48)): was expecting double-quote to start field name 
at [Source: {0:num=121, 0:price=5244614, 1:num=124, 1:price=6324547, 2:num=115, 2:price=5604491}; line: 1, column: 3] 
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1702) 
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:558) 
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:456) 
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddName(ReaderBasedJsonParser.java:1771) 
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:684) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842) 
    at jp.co.temp.sample.management.report.api.TotalSalesStatusCommandService.lambda$createFinalResultObj3$3(TotalSalesStatusCommandService.java:636) 
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) 
相关问题