Я написал службу CXF REST, которая возвращает приложение / json, настроенное следующим образом:
ProspectGenerator:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/consume")
public Prospect convertProspectToJson(Prospect prospect,@QueryParam("customerType") String customerType){
//DTO logic goes here
System.out.println("Prospect obj received.."+prospect.getProspectName());
prospect.setCustomerType(customerType);
return prospect;
}
Эта служба работает при развертывании в JBoss Fuse.
Теперь у меня есть следующий конструктор Camel Route:
public class ServiceRouter extends RouteBuilder {
/* (non-Javadoc)
* @see org.apache.camel.builder.RouteBuilder#configure()
*/
@Override
public void configure() throws Exception {
from("jetty://http://localhost:8182/route/prospect?bindingStyle=SimpleConsumer")
//The Raw type to String conversion is done here. Refer the class for details
//Processor converts the Message from byte[] to String
.process(new ResponseToStringProcessor())
.unmarshal("jsonDataformat") //jsonDataformat - bean in blueprint XML for converting to requested object type
.to("cxfrs://http://localhost:8181/cxf/prospect/consume")
/*1) The above line has the BodyType as Cxf's ResponseImpl instead of Prospect Object
* 2) The below bean accepts type only as Prospect object and hence I get exception */
.to("bean:prospectService?method=doSomething");
}
ProspectService:
public class ProspectService {
public void doSomething(@Body Prospect prospect){
System.out.println("Prospect Service got the request.."+prospect.getCustomerType());
}
}
Я получаю следующее исключение при попытке выполнить маршрутизацию к определенному компоненту:
org.apache.camel.InvalidPayloadException: нет доступного тела типа: com.karthik.bo.Prospect, но имеет значение: org.apache.cxf.jaxrs.impl.ResponseImpl@54c96476 типа
Как мне исправить эту ошибку? Я не могу понять, как преобразовать ResponseImpl в мой POJO. Пришедший след показывает:
BodyType: org.apache.cxf.jaxrs.impl.ResponseImpl, Body: {"prospect": {"customerType": "VIP", "prospectId": 999, "prospectName": "karthik"}} em>
Я попытался преобразовать ResponseImpl в String (который будет содержать полезные данные JSON), но всегда оказываюсь в закрытом потоке IOException. - Код преобразования ниже:
public void convert(Exchange exchange){
InputStream is = (InputStream)exchange.getIn().getBody(ResponseImpl.class).getEntity();
String s="";
try {
s = org.apache.commons.io.IOUtils.toString(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("in convertor..."+s);
}
После множества неудачных попыток (упомянутых в комментариях) окончательным решением было написать FallBackCoverter следующим образом: Это не привело к сбою Stream closed IOException, что нельзя было объяснить самому себе. Em >
@FallbackConverter
public static <T> T convertTo(Class<T> type, Exchange exchange, Object value, TypeConverterRegistry registry){
System.out.println("Checking fall backconverter");
if (ResponseImpl.class.isAssignableFrom(value.getClass())) {
TypeConverter tc = registry.lookup(type, ResponseImpl.class);
if (tc == null && type.getName().equals("com.karthik.bo.Prospect")) {
Prospect prospect=new Prospect();
try(InputStream is = (InputStream)((ResponseImpl)value).getEntity()) {
if(is!=null){
String s = org.apache.commons.io.IOUtils.toString(is);
if(s!=null && s.length()>0){
ObjectMapper mapper = new ObjectMapper();
prospect = mapper.readValue(s, Prospect.class);
}
is.close();
}
} catch (IOException e) {
System.out.println("Exception occured"+e.getMessage());
}
return type.cast(prospect);
}
}
return (T) Void.TYPE;
}
и мой маршрутизатор был изменен на:
from("jetty://http://localhost:8182/route/prospect?bindingStyle=SimpleConsumer")
//The Raw type to String conversion is done here. Refer the class for details
.process(new ResponseToStringProcessor())
.unmarshal("jsonDataformat")
.to("cxfrs://http://localhost:8181/cxf/prospect/consume")
.convertBodyTo(Prospect.class)
.to("bean:prospectService?method=doSomething")
.marshal("jsonDataformat");
Я не мог отметить это как решение, не подтвердив, что это единственный способ сделать это. Мое решение было реализовано после того, как я обнаружил старую проблему JIRA в camel-cxf
https://issues.apache.org/jira/browse/CAMEL-3208
Для этого мне пришлось написать FallBackConvertor.