如何在通过CommandLine传递给Spring Batch作业的作业参数中区分String和Long

时间:2017-03-11 11:24:33

标签: spring-batch spring-batch-admin

我正在使用vulnscanner作业示例并尝试添加2个附加参数。这是我以前运行这个职位的网址。

curl -d jobParameters=ipAddress=74.54.219.210,outputFile=logs/tb.xml,country=USA,randomId=1245873 http://localhost:8080/partitioningJobs/jobs/vulnScannerJob.json

当我使用VARCHAR作为country的数据类型和BIGINT作为randomId的数据类型时,该示例在scanPorts步骤中抛出以下异常。

Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]; SQL state [25P02]; error code [0]; ERROR: current transaction is aborted, commands ignored until end of transaction block; nested exception is org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:909)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:970)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:233)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.updateExecutionContext(JdbcExecutionContextDao.java:161)
    at org.springframework.batch.core.repository.support.SimpleJobRepository.updateExecutionContext(SimpleJobRepository.java:205)
    at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy18.updateExecutionContext(Unknown Source)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:451)
    ... 50 more
Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2458)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2158)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:291)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:432)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:358)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:171)
    at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:138)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:916)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:909)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
    ... 68 more
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = character varying
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
  Position: 67

我将两种数据类型都更改为VARCHAR并且运行正常。但我想知道spring批处理是否将所有作业参数识别为仅字符串或其他数据类型。

仅供参考,我在randomId中使用了ItemReader jobParameter,我收到了此错误消息。我已在TargetTargetRowMapper类中进行了所有必要的更改,以处理这些附加参数。

<bean id="targetItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">
            <property name="dataSource" ref="dataSource" />
            <property name="queryProvider">
                <bean
                    class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
                    <property name="dataSource" ref="dataSource" />
                    <property name="selectClause" value="ID, RANDOMID, IP, PORT, CONNECTED, BANNER" />
                    <property name="fromClause" value="FROM TARGET" />
                    <property name="whereClause" value="RANDOMID = :qid AND ID &gt;= :minId AND ID &lt;= :maxId AND CONNECTED IS NULL"/>
                    <property name="sortKey" value="ID" />
                </bean>
            </property>
            <property name="pageSize" value="10" />
            <property name="parameterValues">
                <map>
                    <entry key="minId" value="#{stepExecutionContext[minValue]}"/>
                    <entry key="maxId" value="#{stepExecutionContext[maxValue]}"/>
                    <entry key="qid" value="#{jobParameters[randomId]}"/>
                </map>
            </property>
            <property name="rowMapper">
                <bean class="com.michaelminella.springbatch.domain.TargetRowMapper"/>
            </property>
        </bean>

1 个答案:

答案 0 :(得分:0)

据我了解,#{jobParameter}是java.util.Collections类型的不可修改的Map。它可以包含任何对象,例如

JobExecution jobExecution = jobLauncher.run(this.exampleJob,new

JobParametersBuilder()
                        .addDate("now", new Date())
                        .addString("paramString", "stringAsParam")
                        .addLong("paramLong", 1234L)
                        .toJobParameters()

对于您的情况,您将所有参数传递为String,这就是您在查询级别收到错误的原因。

要修复它,我想改变

<entry key="qid" value="#{jobParameters[randomId]}"/>

<entry key="qid" value="#{T(java.lang.Long).parseLong(jobParameters[randomId])}"/>