我尝试为REST创建多个通道,以便可以使用http protcol从浏览器调用我的端点,或者可以通过在队列中放置消息来异步调用其他应用程序。虽然我能够配置两种传输类型。我能够访问REST服务,但在发送JMS消息时失败。
以下是我用于复制问题的完整代码设置。
的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kp.swasthik</groupId>
<artifactId>kp-rest-jms-artemis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>kp-rest-jms-artemis</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<cxf.version>3.1.10</cxf.version>
<!-- <artemis.version>2.0.0</artemis.version> -->
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-jms</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
REST服务
@Service
@Path("/kp")
public class KPRest {
@Autowired
private JmsTemplate jmsTemplate;
@POST
@Path("/hello")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public String hello(String hello){
System.out.println(hello);
return "Hello from CXF";
}
@GET
@Path("/send-message")
public String sendMessage(){
jmsTemplate.send("cxf_queue", (session)->{
TextMessage msg = session.createTextMessage();
msg.setBooleanProperty("OnewayMessage", true);
msg.setStringProperty("org.apache.cxf.message.Message.REQUEST_URI", "/kp/hello");
msg.setText("JMS message");
return msg;
});
return "Sent message";
}
}
Cxf配置
import com.kp.swasthik.cxf.rest.KPRest;
@Configuration
public class CxfConfig {
@Bean
public Server jaxrsServerRest(Bus bus, KPRest rest){
JAXRSServerFactoryBean server = new JAXRSServerFactoryBean();
server.setAddress("/kp");
server.setBus(bus);
server.setServiceBean(rest);
server.setFeatures(Arrays.asList(new LoggingFeature()));
return server.create();
}
@Bean
public Server jaxrsServerJMS(Bus bus, KPRest rest, JMSConfigFeature feature){
JAXRSServerFactoryBean server = new JAXRSServerFactoryBean();
server.setAddress("/");
server.setTransportId("http://cxf.apache.org/transports/jms");
server.setBus(bus);
server.setServiceBean(rest);
server.setFeatures(Arrays.asList(new LoggingFeature(), feature));
return server.create();
}
@Bean
public JMSConfigFeature getJMSFeature(JMSConfiguration jmsConfiguration) {
JMSConfigFeature feature = new JMSConfigFeature();
feature.setJmsConfig(jmsConfiguration);
return feature;
}
@Bean
public JMSConfiguration getjmsConfig(ConnectionFactory connectionFactory) {
JMSConfiguration config = new JMSConfiguration();
config.setConnectionFactory(connectionFactory);
config.setTargetDestination("cxf_queue");
return config;
}
}
Spring Boot入门级
@SpringBootApplication
public class KpRestJmsArtimisApplication {
public static void main(String[] args) {
SpringApplication.run(KpRestJmsArtimisApplication.class, args);
}
}
application.properties
spring.artemis.embedded.queues=cxf_queue
spring.artemis.embedded=true
我正在调用send-message rest api,它将消息放在cxf_queue
中,这将由CXF端点读取。但是,由于.
org.apache.cxf.message.Message.REQUEST_URI
,我收到了错误消息
这是stacktrace。
javax.jms.JMSRuntimeException: AMQ129012: The property name 'org.apache.cxf.message.Message.REQUEST_URI' is not a valid java identifier.
at org.apache.activemq.artemis.jms.client.ActiveMQMessage.checkProperty(ActiveMQMessage.java:919) ~[artemis-jms-client-1.3.0.jar:1.3.0]
at org.apache.activemq.artemis.jms.client.ActiveMQMessage.setStringProperty(ActiveMQMessage.java:657) ~[artemis-jms-client-1.3.0.jar:1.3.0]
at com.kp.swasthik.cxf.rest.KPRest.lambda$0(KPRest.java:37) ~[classes/:na]
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:593) ~[spring-jms-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:574) ~[spring-jms-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484) ~[spring-jms-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570) ~[spring-jms-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.kp.swasthik.cxf.rest.KPRest.sendMessage(KPRest.java:34) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_102]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189) ~[cxf-rt-frontend-jaxrs-3.1.10.jar:3.1.10]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99) ~[cxf-rt-frontend-jaxrs-3.1.10.jar:3.1.10]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:262) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:223) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) ~[cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar:8.5.11]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_102]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_102]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]
不确定Cxf完全支持具有JMS传输类型的REST。虽然在文档中说它支持但我没有看到很多细节。并且还不确定是否有任何方式或属性来逃避.
字符。
答案 0 :(得分:1)
我不知道你要做什么的完整背景,但是这......
'org.apache.cxf.message.Message.REQUEST_URI' is not a valid java identifier.
......非常清楚。你不能这样做......
msg.setStringProperty("org.apache.cxf.message.Message.REQUEST_URI", "/kp/hello");
...因为JMS属性中不能包含.
- 它们使用与java标识符相同的规则(例如变量)。
您可以将.
替换为发送方_
,并在接收方交换它们;如果您需要那种格式。
答案 1 :(得分:1)
CXF实施目前不遵循JMS规范。我会注意我们解决这个问题,同时保持与旧CXF客户端的兼容性。