Hi I am trying to implement a pass through SOAP proxy via #RestController in spring. For this purpose I have mapped a rest controller in following way:
#RestController
class MyProxy {
#PostMapping(value = "/**")
public ResponseEntity<String> proxyPost(#RequestBody(required = false) String body, HttpServletRequest request) {}
}
The regular SOAP requests are going OK. The problem comes when a MTOM type of SOAP request is send via the proxy. Then spring failes with unrecognized content type. Here is the exception:
Caused by: org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is javax.servlet.ServletException: Unsupported Content-Type [multipart/related; type="application/xop+xml"; boundary="uuid:dacf4733-80b4-41bc-b2e1-db69b6beadf6"; start="<root.message#cxf.apache.org>"; start-info="text/xml"], expected [multipart/form-data]
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure(StandardMultipartHttpServletRequest.java:124)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:115)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:88)
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:122)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1205)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
... 60 common frames omitted
Caused by: javax.servlet.ServletException: Unsupported Content-Type [multipart/related; type="application/xop+xml"; boundary="uuid:dacf4733-80b4-41bc-b2e1-db69b6beadf6"; start="<root.message#cxf.apache.org>"; start-info="text/xml"], expected [multipart/form-data]
at org.eclipse.jetty.server.Request.getParts(Request.java:2407)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:317)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:95)
... 66 common frames omitted
When receiving a multipart/* request Spring delegates this to the configured Multipart handler. This is enabled by default and for this case should be disabled.
spring.servlet.multipart.enabled=false
Adding the above to your properties should disable it and prevent the parsing, so you can handle it in your controller.
I am setting up a basic Spring Cloud Stream producer with Kafka. The intent is to accept a HTTP POST, save the result of the post to a database with Spring Data JPA, and write the results to a Kafka topic using Spring Cloud Stream Kafka Binder. I am following the latest binder documentation on how to setup a KafkaTransactionManager, but this code results in an error on Application startup.
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| kafkaTransactionManager defined in com.example.tx.Application
↑ ↓
| org.springframework.boot.autoconfigure.kafka.KafkaAnnotationDrivenConfiguration
└─────┘
I have the following Bean defined in my Application class, which is the same as documentation.
#Bean
public KafkaTransactionManager kafkaTransactionManager(BinderFactory binders) {
ProducerFactory<byte[], byte[]> pf = ((KafkaMessageChannelBinder) binders.getBinder(null, MessageChannel.class)).getTransactionalProducerFactory();
KafkaTransactionManager tm = new KafkaTransactionManager<>(pf);
tm.setTransactionIdPrefix("tx-test");
return tm;
}
It seems that calling getBinder causes Spring to create the context again. How can I resolve this circular dependency?
Dependencies: Spring Boot parent 2.4.6; Spring Cloud BOM 2020.0.3
Something must have changed in one of the layers; here is a work around:
#Bean
SmartInitializingSingleton ktmProvider(BinderFactory binders, GenericApplicationContext context) {
return () -> {
context.registerBean("kafkaTransactionManager", KafkaTransactionManager.class,
((KafkaMessageChannelBinder) binders.getBinder(null, MessageChannel.class))
.getTransactionalProducerFactory());
context.getBean(KafkaTransactionManager.class).setTransactionIdPrefix("tx-test");
};
}
i.e. wait for the other beans to be created before registering and configuring the tm.
After migrating Spring Boot from 2.3.0 to 2.3.2.RELEASE, my #RedisHash code is broken.
#RedisHash(value = "OtpCache", timeToLive = 5 * 60)
data class OtpCache(#Id val mobile: String,
val otp: String)
interface OtpCacheRepository : CrudRepository<OtpCache, String>
val optional = otpCacheRepository.findById("unknown")
println("optional = " + optional.isPresent)
When I try to find a instance of OtpCache with unknown identifier using findById, instead of getting a Optional.empty(), i see an exception
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method com.example.demo.OtpCache.<init>, parameter mobile
at com.example.demo.OtpCache.<init>(DemoApplication.kt) ~[main/:na]
at com.example.demo.OtpCache_Instantiator_humu2e.newInstance(Unknown Source) ~[main/:na]
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:238) ~[spring-data-commons-2.3.2.RELEASE.jar:2.3.2.RELEASE]
This code was working perfect in Spring Boot 2.3.0.RELEASE
I am using Kotlin data class for creating POJO in my codebase.
Here is link to sample repository
https://github.com/cancerian0684/bug-redishash-springboot
I am migrating a Project which using JBOSS fuse to Spring Boot and I use this code for registry a dynamic DataSource:
PropertyPlaceholderDelegateRegistry reg = (PropertyPlaceholderDelegateRegistry) exchange.getContext().getRegistry();
CompositeRegistry cReg = (CompositeRegistry) reg.getRegistry();
SimpleRegistry simpleReg = new SimpleRegistry();
simpleReg.put(
Messaging.Names.SAM_DATABASE_CONNECTION_KEY.toString() + configuration.getCustomerNumber(),
dataSource);
cReg.addRegistry(simpleReg);
But when i migrated it to Spring boot, it does not work and has this Error:
There's uncaught exception has occured. Exception message:
org.apache.camel.spring.spi.ApplicationContextRegistry cannot be cast to org.apache.camel.impl.CompositeRegistry
Please help!!!
I am running a spring boot application that connects to activeMQ as a consumer from my Spring STS environment. I then run my camel blueprint from my JBoss Developer Studio app.
Here's the code from my listener:
#JmsListener(destination = '${tripRequest.updateStatus.destination}')
void handle(TextMessage message) {
When the message hits the consumer, I get the following exception:
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.xxx.trip.request.messaging.status.TripRequestUpdateStatusListener.handle(javax.jms.TextMessage)]
Bean [com.xxx.trip.request.messaging.status.TripRequestUpdateStatusListener#1a99744a]
; nested exception is org.springframework.messaging.converter.MessageConversionException: No converter found to convert to interface javax.jms.TextMessage, message=GenericMessage [payload=byte[197], headers={CamelFileLastModified=1466448102155, CamelFileParent=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data, CamelFilePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, CamelFileLength=22, jms_destination=queue://tripRequest.updateStatus.v1.0, jms_priority=4, CamelFileAbsolute=true, jms_timestamp=1466631945834, CamelFileName=one.json, jms_redelivered=false, jms_deliveryMode=2, CamelFileNameConsumed=one.json, breadcrumbId=ID-ThomasLaptop-55017-1466631942306-0-1, jms_replyTo=temp-queue://ID:ThomasLaptop-55022-1466631945608-1:1:1, CamelFileRelativePath=one.json, jms_correlationId=Camel-ID-ThomasLaptop-55017-1466631942306-0-3, id=3c38a185-44c7-4df2-fefb-1f3320e0262f, CamelFileAbsolutePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, jms_expiration=1466631965834, jms_messageId=ID:ThomasLaptop-55022-1466631945608-1:1:2:1:1, CamelFileNameOnly=one.json, timestamp=1466631945924}]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:94) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1158) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1047) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_91]
Caused by: org.springframework.messaging.converter.MessageConversionException: No converter found to convert to interface javax.jms.TextMessage, message=GenericMessage [payload=byte[197], headers={CamelFileLastModified=1466448102155, CamelFileParent=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data, CamelFilePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, CamelFileLength=22, jms_destination=queue://tripRequest.updateStatus.v1.0, jms_priority=4, CamelFileAbsolute=true, jms_timestamp=1466631945834, CamelFileName=one.json, jms_redelivered=false, jms_deliveryMode=2, CamelFileNameConsumed=one.json, breadcrumbId=ID-ThomasLaptop-55017-1466631942306-0-1, jms_replyTo=temp-queue://ID:ThomasLaptop-55022-1466631945608-1:1:1, CamelFileRelativePath=one.json, jms_correlationId=Camel-ID-ThomasLaptop-55017-1466631942306-0-3, id=3c38a185-44c7-4df2-fefb-1f3320e0262f, CamelFileAbsolutePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, jms_expiration=1466631965834, jms_messageId=ID:ThomasLaptop-55022-1466631945608-1:1:2:1:1, CamelFileNameOnly=one.json, timestamp=1466631945924}]
at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:118) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:98) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:138) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:107) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:90) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 10 common frames omitted
I know for a fact that we have tested this with text messages sent from another application and this message works fine. I don't understand why it fails from my camel route. When I look at the message, it appears to be well-formed XML. Here it is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tripRequestUpdateStatus>
<id>1</id>
<status>Approved</status>
<updatedBy source="lgtc">1</updatedBy>
</tripRequestUpdateStatus>
Why does it need converted in the first place when I'm sending text? Why is conversion failing?
I guess you created a new question after you found out something, but forgot to mention this in this question: How to send text message instead of byte message
You send the messages as byte payload so the JMS consumer receives the message payload as a javax.jms.BytesMessage which Spring Integration is not able to convert to a javax.jms.TextMessage. So you can change your code to use a javax.jms.BytesMessage instead. Or have the sender send the JMS messages as Text based instead of Bytes.