出色的Apache Camel团队忙于解决查询中多个参数的处理问题,这是一种解决方法。 希望该帖子将在下一版本的Camel中变得过时。 (当前,我使用2.7.5)
问题
大于1的查询参数作为null
值传递给Camel-CXF服务。 假设网址中有四个查询参数,例如
name=arun&email=arun@arunma.com&age=10&phone=123456
执行以下操作时,只会填充第一个:
MultiQueryParams
@GET
@Path("search")
@Produces(MediaType.APPLICATION_JSON)
public String sourceResultsFromTwoSources(@QueryParam("name") String name, @QueryParam("age") String age,@QueryParam("phone") String phone,@QueryParam("email") String email
);
所有其他参数为null
。
最终输出
对于网址: http://localhost:8181/cxf/karafcxfcamel/search?name=arun&email=arun@arunma.com&age=31&phone=232323
预期的结果是:
解决方法
有趣的是,我们可以在标头中获取整个查询字符串。
QueryStringHeader
String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
然后我们可以做一个
提取参数
MultivaluedMap<String, String> queryMap = JAXRSUtils.getStructuredParams(queryString, "&", false, false);
获取查询参数作为多值Map。
然后可以将查询参数设置为Exchange
的属性,并在整个Exchange
使用。
码
- 整个代码可以从github下载
请注意,我在Karaf容器中将Camel作为OSGi的一部分运行。 尽管因使用Camel-CXF的环境而导致变通办法没有不同,但从github下载代码时请注意这一事实。 请注意用于骆驼配置的xml蓝图。
这里最重要的是路由器
路由器
RestToBeanRouter
package me.rerun.karafcxfcamel.camel.beans;import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.ws.rs.core.MultivaluedMap;
import java.util.List;
import java.util.Map;public class RestToBeanRouter extends RouteBuilder {private static Logger logger= LoggerFactory.getLogger(RouteBuilder.class);@Overridepublic void configure() throws Exception {from ("cxfrs://bean://rsServer").process(new ParamProcessor()).multicast().parallelProcessing().aggregationStrategy(new ResultAggregator()).beanRef("restServiceImpl", "getNameEmailResult").beanRef("restServiceImpl", "getAgePhoneResult").end().marshal().json(JsonLibrary.Jackson).to("log://camelLogger?level=DEBUG");}private class ParamProcessor implements Processor {@Overridepublic void process(Exchange exchange) throws Exception {String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);MultivaluedMap<String, String> queryMap = JAXRSUtils.getStructuredParams(queryString, "&", false, false);for (Map.Entry<String, List<String>> eachQueryParam : queryMap.entrySet()) {exchange.setProperty(eachQueryParam.getKey(), eachQueryParam.getValue());}}}
}
接口
RestService
package me.rerun.karafcxfcamel.rest;import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;public interface RestService {@GET@Path("search")@Produces(MediaType.APPLICATION_JSON)public String sourceResultsFromTwoSources();}
实作
RestServiceImpl
package me.rerun.karafcxfcamel.rest;import me.rerun.karafcxfcamel.model.AgePhoneResult;
import me.rerun.karafcxfcamel.model.NameEmailResult;
import me.rerun.karafcxfcamel.service.base.AgePhoneService;
import me.rerun.karafcxfcamel.service.base.NameEmailService;
import me.rerun.karafcxfcamel.service.impl.AgePhoneServiceImpl;
import org.apache.camel.Exchange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.List;public class RestServiceImpl implements RestService {private static Logger logger= LoggerFactory.getLogger(AgePhoneServiceImpl.class);private NameEmailService nameEmailService;private AgePhoneService agePhoneService;public RestServiceImpl(){}//Do nothing. Camel intercepts and routes the requestspublic String sourceResultsFromTwoSources() {return null;}public NameEmailResult getNameEmailResult(Exchange exchange){logger.info("Invoking getNameEmailResult from RestServiceImpl");String name=getFirstEntrySafelyFromList(exchange.getProperty("name", List.class));String email=getFirstEntrySafelyFromList(exchange.getProperty("email", List.class));return nameEmailService.getNameAndEmail(name, email);}public AgePhoneResult getAgePhoneResult(Exchange exchange){logger.info("Invoking getAgePhoneResult from RestServiceImpl");String age=getFirstEntrySafelyFromList(exchange.getProperty("age", List.class));String phone=getFirstEntrySafelyFromList(exchange.getProperty("phone", List.class));return agePhoneService.getAgePhoneResult(age, phone);}public NameEmailService getNameEmailService() {return nameEmailService;}public AgePhoneService getAgePhoneService() {return agePhoneService;}public void setNameEmailService(NameEmailService nameEmailService) {this.nameEmailService = nameEmailService;}public void setAgePhoneService(AgePhoneService agePhoneService) {this.agePhoneService = agePhoneService;}private String getFirstEntrySafelyFromList(List<String> list){if (list!=null && !list.isEmpty()){return list.get(0);}return null;}
}
资源资源
- 骆驼邮件列表问题
参考: Rerun.me博客上的JCG合作伙伴 Arun Manivannan提供的具有多个查询参数的Camel CXF服务 。
翻译自: https://www.javacodegeeks.com/2013/11/camel-cxf-service-with-multiple-query-parameters.html