ArrayList не может быть приведен к org.springframework.batch.core.JobParameter
Я хочу отправить список с клиента rest на веб-сервис rest, который запустит задание в Spring Batch. Это возможно, или я должен сохранить список в базе данных / плоском файле перед запуском задания и прочитать входные значения из базы данных / плоского файла? Я предполагаю, что кто-то указал, как сделать это в определенной проблеме Jira (см. Ниже), но я не мог понять хотя бы основную идею, как двигаться вперед. Я поместил ниже моего контроллера и как я пытаюсь привести его к JobParameter. Я разместил ссылку на Jira и возможное направление, которое, возможно, мне следует выбрать, но я действительно не понял предложения в этом выпуске Jira. Я добавил ниже клиента SoapUi и, наконец, вставил внизу весь свой журнал ошибок.
Мой контроллер:
@RequestMapping(value = "runit/family", method = RequestMethod.POST)
public void handle(@RequestBody List<Person> myFamily) throws Exception {
System.out.println(myFamily); //until here, it is fine
JobParameters jobParameters = new JobParametersBuilder()
.addParameter("parametersReceived", (JobParameter) myFamily)
.addLong("time", System.currentTimeMillis()).toJobParameters();
jobLauncher.run(job, jobParameters);
}
SoapUi (пост):
[{"firstName":"aa","lastName":"bb"}]
Pojo
public class Person {
private String lastName;
private String firstName;
...getters and setters
Возможный способ работы, но я действительно смущен этой проблемой Jira. Честно говоря, я ожидал чего-то более простого, как я пытаюсь с JobParameter
https://jira.spring.io/browse/BATCH-966 (this suggestion is from 2009. Probably some more up-to-date technique is available)
<bean class="MyItemReader">
<property name="dynamicValuesHashMap" ref="map"/>
...
</bean>
<bean class="MyLauncher">
<property name="dynamicValuesHashMap" ref="map"/>
...
</bean>
Вся ошибка:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.springframework.batch.core.JobParameter
at hello.BatchController.handle(BatchController.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
2 ответа
Пакетные задания должны быть основаны на времени, а не на событиях. Таким образом, вы не можете передать информацию из Службы отдыха в ваш экземпляр Job. Прежде чем запускать задание в методе вашего контроллера, запишите список во временный плоский файл или сохраните его в базе данных, откуда ваше задание может его прочитать.
Если вы посмотрите на фактическую схему, которая хранит метаданные для spring batch
вы увидите список доступных типов, поддерживаемых заданием, чтобы быть параметрами (есть string_val
, date_val
, long_val
, double_val
). Таким образом, при запуске задания каждый параметр задания сохраняется в БД с key_name
как имя параметра и значение хранятся в одном из упомянутых _val
столы. type_cd
дает подсказку, какой тип был использован.
Также документация для JobParameter дает подсказку, что можно использовать в качестве параметра задания:
Доменное представление параметра для пакетного задания. Параметрами могут быть только следующие типы: String, Long, Date и Double. Идентификационный флаг используется, чтобы указать, должен ли параметр использоваться как часть идентификации экземпляра задания.
Я думаю, что лучшим способом было бы создать таблицу в БД, которая хранит список параметров и передает идентификатор этой записи как JobParameter
или сериализовать список в JSON и передать его как String
в работе как JobParameter
, Если вы идете со вторым вариантом, знайте, что string_val
хранится в БД как varchar
250, поэтому ограничение составляет 250 символов.