Spring Batch: JSON неправильно преобразован в список<SampleItem>
В моей работе Spring Batch первым шагом является чтение данных JSON из службы REST и запись их в локальную таблицу HSQL для последующей обработки.
Мой звонок RestTemplate.exchange()
действительно получает ожидаемый JSON, и он конвертирует JSON в List<SampleItem>
,
Тем не менее, как ни странно, на SampleItem
объекты в списке. Это как если бы MappingJackson2HttpMessageConverter
не находит свойства бобов?
Определение должности:
<batch:job id="samples_results.job" restartable="false">
<batch:step id="get.samples" next="get.results">
<batch:tasklet>
<!-- 1. HERDS survey data about outlet samples so far. Form #1 -->
<batch:chunk reader="samples.rest.item.reader" writer="samples.hsqldb.item.writer" commit-interval="${commit.interval}"/>
</batch:tasklet>
</batch:step>
...
<batch:listeners>
<batch:listener ref="job.listener"/>
</batch:listeners>
<batch:validator ref="job.parameters.validator"/>
</batch:job>
<beans:bean id="samples.rest.item.reader" class="gov.ny.health.adsg.ceh.slrs_hdny.SamplesRestItemReader">
<beans:property name="activityId" value="${samples.activity.id}"/>
<beans:property name="formId" value="${samples.form.id}"/>
<beans:property name="username" value="${herds.uname}"/>
<beans:property name="password" value="${herds.password}"/>
</beans:bean>
<beans:bean id="samples.hsqldb.item.writer" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="sql">
<beans:value><![CDATA[insert into t_sample(org_id, name, address) values (:ORG_ID, :ORG_NAME, :ADDRESS_1)]]></beans:value>
</beans:property>
<beans:property name="itemSqlParameterSourceProvider">
<beans:bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</beans:property>
</beans:bean>
Соответствующий ItemReader
код, который успешно возвращает List<SampleItem>
с одним элементом (но без атрибутов для этого элемента):
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
headers.set("Authorization", this.getBasicAuthString_());
HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
ParameterizedTypeReference<List<SampleItem>> typeRef = new ParameterizedTypeReference<List<SampleItem>>(){};
ResponseEntity<List<SampleItem>> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, typeRef, this.activityId, this.formId);
this.list = response.getBody(); if (isDebug) {buf.append(NL).append("list.size=").append(null!=this.list ? this.list.size() : -1).append(NL).append("list[0]=").append(null!=this.list && !this.list.isEmpty() ? this.list.get(0).toString() : "null");}
this.iterator = null!=this.list ? this.list.iterator() : null;
} catch (Exception e) {
logger.error(e.getMessage());
throw e;
} finally {
if (isDebug) {
logger.debug(buf.toString());
}
}
SampleItem
боб. Обратите внимание на атрибуты верхнего регистра, пытаясь сопоставить JSON:
@JsonIgnoreProperties(ignoreUnknown = true)
public class SampleItem implements Serializable {
public String getORG_NAME() {
return ORG_NAME;
}
public void setORG_NAME(String s) {
this.ORG_NAME = s;
}
public String getADDRESS_1() {
return ADDRESS_1;
}
public void setADDRESS_1(String s) {
this.ADDRESS_1 = s;
}
public String getORG_ID() {
return ORG_ID;
}
public void setORG_ID(String s) {
this.ORG_ID = s;
}
public String toString() {
StringBuilder buf = new StringBuilder(getClass().getName());
buf.append("{").append(this.ORG_ID).append("}");
return buf.toString();
}
public int hashCode() {
return this.toString().hashCode();
}
public boolean equals(Object other) {
boolean b = null!=other && (other instanceof SampleItem);
if (b) {
b = this.toString().equals(other.toString());
}
return b;
}
private String ACT_ID = null;
private String ORG_ID = null;
private String ORG_NAME = null;
private String ADDRESS_1 = null;
private static final long serialVersionUID = -4839970923454745745L;
}
Вернул JSON. Все атрибуты уведомлений в верхнем регистре:
2016-09-15 14:14:29 [main] DEBUG g.n.h.a.c.s.SamplesRestItemReader pJsonString_ - json.str: [{"ACT_ID":7704,"ADDRESS_1":"800 North Pearl Street","ADDRESS_2":null,"DATAENTITY_ID":58184,"ENTITY_END_DATE":"06-JUN-2079","ENTITY_TYPE_ID":74,"HERDS_TABLE_NAME":"SCHOOLDRINKING_13536_00","ID1":"888888888889","ID2":"888888880000","LAST_SUBMITTED_DATE":"14/Sep/2016 09:34:11","LAST_SUBMITTED_USER":"tmb03","ORG_ID":58184,"ORG_ID1":"888888888889","ORG_NAME":"Z TEST PUBLIC SCHOOL","ORG_TYPE_ID":74,"POSTAL_CODE":"12204","SCH_LEAD_DT_COMPLETE_61752":"9/14/16","SCH_LEAD_OUTLETS_POSTR_61749":20,"SCH_LEAD_PREREG_COMPLI_61769":50,"SCH_LEAD_PREREG_NONCOM_61770":30,"SCH_LEAD_RESULTS_WEBSI_61927":null,"SCH_LEAD_SAMPLING_ATTE_61750":"on","SCH_LEAD_SAMPLING_COMP_61751":"on","SCH_LEAD_TOTAL_OUTLETS_61768":100,"SCH_LEAD_WAIVER_GRANTE_61772":0,"SCH_LEAD_WAIVER_PENDIN_61771":30,"TIME_SERIES_DATE":null,"TOWN_CITY":"Albany"}]
...
Правильные результаты, но ORG_ID
не установлен:
2016-09-15 14:14:30 [main] DEBUG g.n.h.a.c.s.SamplesRestItemReader init_ -
URL=https://sgw.health.state.ny.us/doh2/applinks/webserv/herdsrestfulservices/surveyData/allfieldsdata/{activityId}/{formId}
activity=7704
form=13536
list.size=1
list[0]=gov.ny.health.adsg.ceh.slrs_hdny.SampleItem{null}
...
Я пробовал каждую комбинацию атрибутов верхнего и нижнего регистра SampleItem
боб.
Любые предложения приветствуются.
1 ответ
Я подозреваю, что вы сталкиваетесь со стратегией именования свойств по умолчанию, предложенной Джексоном в нижнем регистре с некоторыми именами свойств, с https://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/PropertyNamingStrategy.html:
В отсутствие зарегистрированной пользовательской стратегии используется стратегия именования свойств Java по умолчанию, которая оставляет имена полей как есть и удаляет префикс set / get / is из методов (а также начальную последовательность строчных букв в нижнем регистре)
Я не могу найти более конкретную спецификацию алгоритма нижнего регистра, но вместо того, чтобы пытаться угадать его, просто явно назовите свойство, например:
@JsonProperty("ACT_ID")
private String ACT_ID = null;
Вы составляете вещи, указывая @JsonIgnoreProperties(ignoreUnknown = true)
- если вы удалите это, вы можете получить полезное исключение при десериализации, а не пустой объект.
Стоит написать простой модульный тест для сериализации json (de), чтобы определить эти проблемы.