java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object; - spring

I am trying to access list of friends of given username using hibernate. Here is my Service class in which fetchListOfFriends function is used to convert the generic list to an Arraylist of type of FriendsDetails.
#Service
#Transactional
public class DetailsServiceImpl implements DetailsService {
#Autowired
private DetailsDao detailsDao;
#Override
public List<FriendsDetails> fetchListOfFriends(String name) {
#SuppressWarnings("rawtypes")
List listOfFriends=detailsDao.fetchListOfFriends(name);
List<FriendsDetails> friendList= fetchListOfFriendss(listOfFriends);
if(listOfFriends==null){
System.out.println("Empty and null list");
}
System.out.println("size of friendList" + listOfFriends.size());
return friendList;
}
private List<FriendsDetails> fetchListOfFriendss(#SuppressWarnings("rawtypes") List genericList) {
#SuppressWarnings("unchecked")
List<Object> result = (List<Object>) genericList;
Iterator<Object> itr = result.iterator();
List<FriendsDetails> listOfFriend= new ArrayList<FriendsDetails>();
while(itr.hasNext()){
Object[] obj = (Object[]) itr.next();
System.out.println(obj.toString());
String userName = String.valueOf(obj[0]);
FriendsDetails obj1= new FriendsDetails();
obj1.setFriendName(userName);
listOfFriend.add(obj1);
}
return listOfFriend;
}
DetailsDaoImpl.java
#Autowired
private SessionFactory sessionFactory;
#SuppressWarnings("rawtypes")
#Override
public List fetchListOfFriends(String name) {
Session session=sessionFactory.getCurrentSession();
String queryToFetchFriends="Select name,presenceStatus from UserPresence where name in (Select friendName from Friends where name='"+name+"')";
List listOfFriends=session.createSQLQuery(queryToFetchFriends).list();
return listOfFriends;
}
Logs.txt
May 22, 2016 1:24:11 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [springmvc] in context with path [/Testing] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;] with root cause
java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;
at com.tcs.Service.FriendServiceImpl.searchFriend(FriendServiceImpl.java:61)
at com.tcs.Service.FriendServiceImpl.searchFriend(FriendServiceImpl.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Everything should work correctly.
The problem, obviously, that List listOfFriends is List<String>, not List<Object[]>. It is strange, because of Select name,presenceStatus from UserPresence should return List<Object[]>.
Maybe Spring set an incorrect implementation of #Autowired
private DetailsDao detailsDao;.
Try this code. This should work for List<String>
private List<FriendsDetails> fetchListOfFriendss(List<?> genericList) {
Iterator<?> itr = genericList.iterator();
List<FriendsDetails> listOfFriend = new ArrayList<FriendsDetails>();
while (itr.hasNext()) {
Object obj = itr.next();
String userName = String.valueOf(obj);
System.out.println(userName);
FriendsDetails obj1 = new FriendsDetails();
obj1.setFriendName(userName);
listOfFriend.add(obj1);
}
return listOfFriend;
}

Related

Spring Data Jdbc and Oracle21c

for my latest assignment I'm developing a Spring boot application which will connect with an Oracle 21c database.
The feature of the oracle release we're interested in is the native JSON data type called OSON (reference here: Oracle 21c JSON data type )
I've developed an old fashion DAO approach to accomplish the task, but I would like to use Spring Data JDBC project for the data access layer ideally with minimal extra configuration.
Actually I'm struggling with the mapping of the columns where the OSON type will be stored. After several tries I've obtained the error below following the idea of creating a custom converter for the datatype.
Any suggestion on how to proceed?
pom:
<!-- ORACLE -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11-production</artifactId>
<version>21.1.0.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
Entity class:
#Table("T_BUDGET")
#Data #NoArgsConstructor
public class BudgetEntityData {
#Id
private Long id;
#Column("BUDGET")
private JsonObjectWrapper budget;
}
Wrapper used for the converter:
#Data
public class JsonObjectWrapper {
private OracleJsonValue json;
}
Jdbc configuration with custom converter:
#Configuration
#EnableJdbcRepositories
public class JdbcConfig extends AbstractJdbcConfiguration {
//utility object used to centralize the use of OracleJsonFactory, not involved in the problem
private static OracleJsonFactoryWrapper factoryWrapper = new OracleJsonFactoryWrapper(new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false),
new OracleJsonFactory());
#Override
public JdbcCustomConversions jdbcCustomConversions() {
return new JdbcCustomConversions(Arrays.asList(StringToJsonObjectWrapper.INSTANCE,JsonObjectWrapperToString.INSTANCE));
}
#WritingConverter
enum JsonObjectWrapperToString implements Converter<JsonObjectWrapper, String> {
INSTANCE;
#Override
public String convert(JsonObjectWrapper source) {
return source.toString();
}
}
#ReadingConverter
enum StringToJsonObjectWrapper implements Converter<String, JsonObjectWrapper> {
INSTANCE;
#Override
public JsonObjectWrapper convert(String source) {
JsonObjectWrapper jsonObjectWrapper = new JsonObjectWrapper();
OracleJsonValue osonObject = factoryWrapper.createOsonObject(source);
jsonObjectWrapper.setJson(osonObject);
return jsonObjectWrapper;
}
}
}
Error:
2022-04-07 09:47:27.335 DEBUG 24220 --- [nio-8080-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2022-04-07 09:47:27.335 DEBUG 24220 --- [nio-8080-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT "T_BUDGET"."ID" AS "ID", "T_BUDGET"."BUDGET" AS "BUDGET" FROM "T_BUDGET"]
2022-04-07 09:48:58.006 ERROR 24220 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.mapping.MappingException: Could not read value BUDGET from result set!] with root cause
java.sql.SQLException: Invalid column type: getOracleObject not
implemented for class oracle.jdbc.driver.T4CJsonAccessor at
oracle.jdbc.driver.GeneratedAccessor.getOracleObject(GeneratedAccessor.java:1221)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.JsonAccessor.getObject(JsonAccessor.java:200)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.GeneratedStatement.getObject(GeneratedStatement.java:196)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.GeneratedScrollableResultSet.getObject(GeneratedScrollableResultSet.java:334)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
~[HikariCP-3.4.5.jar:na] at
org.springframework.jdbc.support.JdbcUtils.getResultSetValue(JdbcUtils.java:283)
~[spring-jdbc-5.3.8.jar:5.3.8]
I had the very same issue. I fixed it with the RowMapper like this:
Create DTO for the JSON content (JsonObjectWrapper in your case)
#Getter
#Setter
public class JsonContent {
private String code;
private String name;
}
Create entity (BudgetEntityData in your case)
#Data
#Relation( collectionRelation = "persons" )
public class Person {
#Id
private Long id;
private JsonContent content;
}
Create custom RowMapper (probably JdbcConfig in your case)
public class PersonMapper implements RowMapper<Person> {
static ObjectMapper objectMapper = new ObjectMapper();
#Override
public Person mapRow( ResultSet rs, int rowNum ) throws SQLException {
try {
var jsonContent = rs.getBytes( 2 );
var content = objectMapper.readValue( jsonContent, JsonContent.class );
var person = new Person();
person.setId( rs.getLong( 1 ) );
person.setContent( content );
return person;
} catch ( IOException e ) {
throw new RuntimeException( "JSON unmarschalling failed!", e );
}
}
}
Use it in repository (not mentioned in your case) as
#Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
#Query( value = "SELECT id, ctnt FROM PERSON", rowMapperClass = PersonMapper.class )
#Override
List<Person> findAll();
}
Note: you can even simplify it with the spring-data-jpa as:
Define entity
#Entity
#Table( name = Person.TABLE_NAME )
#Data
#Relation( collectionRelation = "persons" )
public class Person {
static final String TABLE_NAME = "PERSON";
#Id
#GeneratedValue
private Long id;
#Column( name = "CTNT" )
#Convert( converter = JsonContentConverter.class )
private JsonContent content;
}
And the converter
public class JsonContentConverter implements AttributeConverter<JsonContent, byte[]> {
static ObjectMapper objectMapper = new ObjectMapper();
#Override
public byte[] convertToDatabaseColumn( JsonContent attribute ) {
try {
return objectMapper.writeValueAsBytes( attribute );
} catch ( JsonProcessingException e ) {
throw new RuntimeException( "JSON marschalling failed!", e );
}
}
#Override
public JsonContent convertToEntityAttribute( byte[] jsonContent ) {
try {
return objectMapper.readValue( jsonContent, JsonContent.class );
} catch ( IOException e ) {
throw new RuntimeException( "JSON unmarschalling failed!", e );
}
}
}

JSON decoding error: Cannot deserialize value of type `java.math.BigInteger` from Object value (token `JsonToken.START_OBJECT`); (Jackson)

It is necessary to deserialize the result from Mono<ResultSumDto> to JSON, then to sent to the client as JSON.
Controller
#GetMapping("v1/sequence/{startRange}/{endRange}")
Mono<ResultSumDto > getSumFromRange(
#PathVariable BigInteger startRange,
#PathVariable BigInteger endRange) {
ResultSumDto resultSumDto = ...
return Mono.just(resultSumDto);
}
#Configuration
public class JacksonObjectMapperConfiguration {
#Autowired
public void serializeBigInteger(ObjectMapper objectMapper) {
JsonFormat.Value formatValue =
JsonFormat.Value.forShape(JsonFormat.Shape.STRING);
objectMapper
.configOverride(BigInteger.class)
.setFormat(formatValue);
}
}
#Data
#Builder
public class ResultSumDto {
private final BigInteger sumSeq;
private final BigInteger [] seqRange;
private final Boolean isCached;
}
private Mono<ResultSumDto> buildResult(SeqDto dto) {
Mono<BigInteger> sumSeq =
calculateSumRangeValuesFibonacciSequence(dto);
BigInteger bigInteger = null;
try {
bigInteger = sumSeq
.toFuture()
.get();
} catch (InterruptedException | ExecutionException e) {
log.error(e.getLocalizedMessage());
Thread.currentThread().interrupt();
}
BigInteger[] rangeGiven = new BigInteger[]
{dto.getStartRange(), dto.getEndRange()};
return Mono.just(ResultSumSeqDto.builder()
.sumSequence(bigInteger)
.sequenceRange(rangeGiven)
.isCached(false)
.build()
);
}
But I have a mistake:
org.springframework.core.codec.DecodingException: JSON decoding error: Cannot deserialize value of type java.math.BigInteger from Object value (token JsonToken.START_OBJECT); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type java.math.BigInteger from Object value (token JsonToken.START_OBJECT)
at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1]
But after all, when I get values in endpoint, serialization to the BigInteger type goes without problems.
Who has any idea why it doesn't work and how it can be fixed. Share your knowledge on how to deserialize an array BigInteger and a field with the BigInteger type?
That's what worked in my case.
public class DeserializeResultCalculateSumSequence
extends StdDeserializer<ResultCalculateSumSequenceDto> {
public DeserializeResultCalculateSumSequence() {
this(null);
}
protected DeserializeResultCalculateSumSequence(Class<?> vc) {
super(vc);
}
#Override
public ResultCalculateSumSequenceDto deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException, JacksonException {
JsonNode node = jsonParser
.getCodec()
.readTree(jsonParser);
BigInteger sumSequence = node
.get("sumSequence")
.bigIntegerValue();
ObjectMapper mapper = new ObjectMapper();
String sequenceRangeStr = node.get("sequenceRange").toString();
BigInteger[] sequenceRange = mapper
.readValue(sequenceRangeStr, BigInteger[].class);
boolean isCached = node
.get("isCached")
.asBoolean();
return ResultCalculateSumSequenceDto
.builder()
.sumSequence(sumSequence)
.sequenceRange(sequenceRange)
.isCached(isCached)
.build();
}
}
#Data
#Builder
#JsonDeserialize(using = DeserializeResultCalculateSumSequence.class)
public class ResultCalculateSumSequenceDto {
private final BigInteger sumSequence;
private final BigInteger [] sequenceRange;
private final Boolean isCached;
}

java.lang.IllegalArgumentException: Could not find field 'isBoolean' of type [class java.lang.Boolean] on target object

When I run test then it failed at this point ReflectionTestUtils.setField(service, SeRepositoryImpl.class, "isBoolean",true,Boolean.class) complains about Could not find field 'isBoolean' of type not found. Error trace as below.
I am not sure why because my repositoryImpl class has isBoolean variable defined.
java.lang.IllegalArgumentException: Could not find field 'isBoolean' of type [class java.lang.Boolean] on target object [lautomation.repository.impl.SaRepositoryImpl#4a178d1e] or target class [lautomation.repository.impl.SaRepositoryImpl]
at org.springframework.test.util.ReflectionTestUtils.setField(ReflectionTestUtils.java:175)
test class looks like
#MockBean(name = "seRepository")
PolicyRepository seRepository;
#InjectMocks
private SeRepositoryImpl service;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testUpdateStatus() throws Exception{
ReflectionTestUtils.setField(service, SeRepositoryImpl.class, "isBoolean",true,Boolean.class);
List<Policy> policies = Arrays.asList(new Policy[] {new Policy() });
service.updateIssuedStatus(Mockito.any(Policy.class));
Mockito.verify(seRepository, Mockito.times(1)).updateIssuedStatus(Mockito.any(Policy.class));
}
}
Respository implementation class SeRepositoryImpl has isBoolean variable defined
#Repository("seRepository")
#Log4j
public class SeRepositoryImpl implements PolicyRepository {
#Value("${change-db}")
private boolean isBoolean;
#Autowired
#Qualifier("jdbcDbName")
private NamedParameterJdbcTemplate jdbcTemplate;
#Override
public void updateIssuedStatus(final Policy policy) {
if(!isBoolean) {
log.warn("isBoolean is set to false - skipping db write.");
return;
}
final HashMap<String, String> params = new HashMap<>();
params.put("issued",
new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
params.put("id", Integer.toString(policy.getId()));
jdbcTemplate.update(updateIssuedStatus, params);
String currDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
log.info("params:"+Integer.toString(policy.getId())+" Date:"+currDate);
final String sql = "call usp_updateDatabase(:policy,:currDate)";
MapSqlParameterSource value = new MapSqlParameterSource();
value.addValue("id",Integer.toString(policy.getId()));
value.addValue("stop_dt",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
jdbcTemplate.update(sql, value);
}
}

Unable to show XML data

Hi my need is to show both xml and json data .
I am able to see this in local by JaxB but unable to see same code in server.
When ever I deploy that to server I got this error.
I don't know how to solve this error.
Unable to solve this, Tried a lot but Nothing happened , in local everything is fine, but when it comes to server it shows different exception.
Error 500: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Could not instantiate JAXBContext for class [class com.rest.model.ExerciseInstructionsList]: null; nested exception is javax.xml.bind.JAXBException - with linked exception: [com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Class has two properties of the same name "exerciseList" this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.getExerciseList()
at com.rest.model.ExerciseInstructionsList this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.exerciseList at com.rest.model.ExerciseInstructionsList ]
My Controller IS
#Controller
#RequestMapping("/")
public class ExerciseController {
#Autowired
private ExerciseService exerciseService;
private static final Logger logger = LoggerFactory.getLogger(ExerciseController.class);
#Consumes
#Produces
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_ALL,method=RequestMethod.GET,produces={"application/json"})
public #ResponseBody List<ExerciseInstructions> getAllExercise()throws Exception{
logger.info("Start getAllExercises.");
System.out.println("<<<<<<<<<<<<<<<<<--------------Coming Inside List Exercise Controller----------->>>>>>>>>>>");
List<ExerciseInstructions> listExercise = new ArrayList<ExerciseInstructions>();
//ExerciseInstructionsList exe = new ExerciseInstructionsList();
/*This list contains Exercise Instructions Data*/
listExercise = exerciseService.getAllExercise();
/*here i kept the list in ExerciseInstructionsList list so that i can fetch xml data also and can show the list.*/
//exe.setExerciseList(listExercise);
return listExercise;
}
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_XML_ALL,method=RequestMethod.GET,produces={"application/xml"})
public #ResponseBody ExerciseInstructionsList getAllXmlExercise()throws Exception{
logger.info("Start getAllExercises.");
System.out.println("<<<<<<<<<<<<<<<<<--------------Coming Inside List Exercise Controller----------->>>>>>>>>>>");
List<ExerciseInstructions> listExercise = new ArrayList<ExerciseInstructions>();
ExerciseInstructionsList exeList = new ExerciseInstructionsList();
/*This list contains Exercise Instructions Data*/
listExercise = exerciseService.getAllExercise();
/*here i kept the list in ExerciseInstructionsList list so that i can fetch xml data also and can show the list.*/
exeList.setExerciseList(listExercise);
return exeList;
}
#RequestMapping(value=OaesRestURIConstants.EXERCISE_SAVE,method=RequestMethod.POST)
public #ResponseBody ExerciseInstructions saveExercise(#RequestBody ExerciseInstructions exerciseInstructions)throws Exception{
logger.info("Start saveExercise.");
exerciseService.saveExercise(exerciseInstructions);
return exerciseInstructions;
}
//#Consumes({"application/xml","application/json"})
// #Produces({"application/xml","application/json"})
#RequestMapping(value=OaesRestURIConstants.GET_EXERCISE_ID,method=RequestMethod.GET,produces={"application/xml","application/json"})
public #ResponseBody ExerciseInstructions getExerciseById(#PathVariable("id") String exerciseId ) throws Exception{
logger.info("Start getExerciseById. ID="+exerciseId);
ExerciseInstructions exercise = null;
try {
exercise = exerciseService.getExerciseById(exerciseId);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Coming Here>>>>>>>>>>>"+exercise);
return exercise;
//return exerciseService.getExerciseById(exerciseId);
}
#RequestMapping(value=OaesRestURIConstants.EXERCISE_DELETE,method=RequestMethod.PUT)
public #ResponseBody ExerciseInstructions deleteById(#PathVariable("id") String exerciseId) throws Exception{
logger.info("Start deleteExercise.");
exerciseService.deleteExercise(exerciseId);
return null;
}
}
My Model class is :
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructions {}
My Model List Class Is :
#XmlRootElement(name="exerciseInstructions")
//#XmlSeeAlso({ExerciseInstructions.class})
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructionsList {
public List<ExerciseInstructions> exerciseList;
public List<ExerciseInstructions> getExerciseList() {
return exerciseList;
}
public void setExerciseList(List<ExerciseInstructions> exerciseList) {
this.exerciseList = exerciseList;
}
}
So can anyone help me in this.
I want to fetch and see both xml and json.
When you carefully read the error-message you see the reason: (I formatted and highlighted the message for better readability)
IllegalAnnotationExceptions Class has two properties of the same name "exerciseList"
this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.getExerciseList() at com.rest.model.ExerciseInstructionsList
this problem is related to the following location: at public java.util.List com.rest.model.ExerciseInstructionsList.exerciseList at com.rest.model.ExerciseInstructionsList
So the program complains that your class ExerciseInstructionsList has two properties which can be mapped to exerciseList, these are getExerciseList() and exerciseList.
To fix this you can declare exerciseList as private.
#XmlRootElement(name="exerciseInstructions")
#XmlAccessorType(XmlAccessType.FIELD)
public class ExerciseInstructionsList {
private List<ExerciseInstructions> exerciseList;
public List<ExerciseInstructions> getExerciseList() {
return exerciseList;
}
public void setExerciseList(List<ExerciseInstructions> exerciseList) {
this.exerciseList = exerciseList;
}
}

Custom Spring Integration Splitter throwing error

Hi I am Trying to extract multiple messages from a single message and split those into multiple messages using a splitter element. But my Splitter is throwing the below error
2015-10-26 15:09:06,257 [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.handler.MessageHandlerChain#1': Cannot create inner bean 'org.springframework.integration.config.SplitterFactoryBean#20e2ef61' of type [org.springframework.integration.config.SplitterFactoryBean] while setting bean property 'handlers' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.config.SplitterFactoryBean#20e2ef61': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public java.util.List com.salesorder.payment.util.PoslogToIsellRequests.poslogTransformer(java.lang.String), public java.util.List com.salesorder.payment.util.PoslogToIsellRequests.split(java.util.List)]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121)
at
The splitter block:
<si:splitter>
<bean
class="com.ikea.pip.salesorder.payment.util.PoslogToIsellRequests"
p:mapTaxRateCategory="${common.map.tax.rate.category}" p:buCode="${common.country.code.iso}"
p:sourceRegion="${common.isell.order.source}" p:countryCode ="${common.country.code.iso}" />
</si:splitter>
Java Code of the class:
public class PoslogToIsellRequests implements Splitter {
private static final Logger LOG = LoggerFactory
.getLogger(PoslogToIsellRequests.class);
private static final String ORDER= "SpecialOrderNumber";
private static XMLInputFactory inputFactory;
private final SimpleXslt transformPoslogXslt = new SimpleXslt(
"xsl/POSLogToAddPaymentRequest.xsl");
private String sourceRegion;
private String buCode;
private String mapTaxRateCategory;
private String countryCode;
static {
inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE,
Boolean.TRUE);
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Override
public List<String> split(List<String> xmlToSplit) {
List<String> splittedPayload = new ArrayList<String>();
for (String xml : xmlToSplit) {
splittedPayload.addAll(split(xml));
}
return splittedPayload;
}
public void setSourceRegion(String sourceRegion) {
this.sourceRegion = sourceRegion;
}
public void setBuCode(String buCode) {
this.buCode = buCode;
}
public void setMapTaxRateCategory(String mapTaxRateCategory) {
this.mapTaxRateCategory = mapTaxRateCategory;
}
/* #param xmlToSplit
* #return
* #throws Exception
*/
#Override
public List<String> split(String xmlToSplit) {
List<String> resultSet=new ArrayList<String>();
resultSet=poslogTransformer(xmlToSplit);
return resultSet;
}
public List<String> poslogTransformer(String xmlToSplit) {
List<String> resultSet=null;
Set<String> orderNos=new HashSet<String>();
String payload = xmlToSplit;
try{
orderNos= parseOrderNos(payload);
resultSet=new ArrayList<String>();
}
catch (XMLStreamException e) {
LOG.warn("Could not parse Transaction");
}
for(String orderno:orderNos){
Map<String, String> parameters = createParams(orderno);
String result = transformPoslogXslt.transform(payload,
parameters);
resultSet.add(result);
}
return resultSet;
}
private Map<String, String> createParams(String orderNo) {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("sourceRegion", sourceRegion);
parameters.put("buCode",buCode );
parameters.put("mapTaxRateCategory",mapTaxRateCategory );
parameters.put("orderNo",orderNo );
parameters.put("countryCode", countryCode);
return parameters;
}
private Set<String> parseOrderNos(String payload) throws XMLStreamException {
Set<String> orders=new HashSet<String>();
XMLEventReader reader;
reader = inputFactory.createXMLEventReader(new StringReader(payload));
String currentElement = "";
try {
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
currentElement = event.asStartElement().getName()
.getLocalPart();
} else if (currentElement.equals(ORDER)
&& event.isCharacters()) {
String value = event.asCharacters().getData();
if(StringUtils.isNotBlank(value)){
orders.add(value);}
}
}
} finally {
reader.close();
}
return orders;
}
}
The Splitter interface is just contains two split method. Is method overloading not allowed in spring Integration?
One additional query can I have string input as a parameter instead of message?
If you don't explicity identify the method name in the splitter, the framework will detect multiple method candidates and won't be able to determine which one to call.
Hence:
Found ambiguous parameter type [class java.lang.String] for method match: [public java.util.List com.salesorder.payment.util.PoslogToIsellRequests.poslogTransformer(java.lang.String), public java.util.List com.salesorder.payment.util.PoslogToIsellRequests.split(java.util.List)]
All public methods are considered for POJO method matching unless you specify method="split".
If you add that, the framework will invoke the appropriate split method, depending on the payload type of the inbound message.

Resources