How to set Content-Type header for JMS message - jms

We have a Java application that sends JMS message via IBM WebSphere MQ. The consumer application requires the message content type to be set to "application/json". How can I go about doing it?
I've checked through a few references and it seems I can set extra header via method "setStringProperty(headerKey, headerName)", E.g.
Message jmsMsg = session.createTextMessage(msgStr);
jmsMsg.setStringProperty("Content-Type", "application/json");
The problem then is "Content-Type" is not a valid property key since it contains the "-" character.
Is this something that can be done in code? Or is it actually configured in the queue settings?

The property name "Content-Type" has a '-' character. According to JMS specifications a property name can contain any character for which the Java Character.isJavaIdentifierPart method returns a true. For '-' character isJavaIdentifierPart method returns false. Hence the setStringProperty("Content-Type", "application/json") method call fails with the following exception.
com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0049: The property name 'Content-Type' is not a valid Java(tm) identifier.
The supplied property name does not conform to the allowed format described in the JMS specification.
Check the characters used in the property name and modify as necessary.
If it's possible to change the receiving application, you could opt for "Content_Type" (Use an underscore) as property name instead of "Content-Type".

As an example for SOAP format, w3c requires using JMS property named "SOAPJMS_contentType" (http://www.w3.org/TR/soapjms/). It looks that there is nothing about JSON format in the standards, but you can use name like that. Such name will be processed correctly by IBM JMS libraries.

Related

Spring Boot doesn't recognize multipart form-data element when filename is missing

I have this code:
#PostMapping("foobar")
public ResponseEntity<SaveLogsResult> foobar(#RequestPart("file") MultipartFile log, #RequestPart("env") MultipartFile json){
return ResponseEntity.ok(fooService.saveFooBar(log, json, UUID.randomUUID().toString()));
}
Two applications send formally correct data to this endpoint, one fails miserably and receives an http status 400.
I set logging.level.org.springframework.web=DEBUG and can see (among other lines) this:
Required request part 'env' is not present
Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'env' is not present]
Completed 400 BAD_REQUEST
To further diagnose this I compared a working (left) and a non-working (right) request. The only different is the mising filename:
As far as I understand the RFC for Content-Disposition leaving out the filename is perfectly valid:
Is followed by a string containing the original name of the file
transmitted. The filename is always optional and must not be used
blindly by the application: path information should be stripped, and
conversion to the server file system rules should be done. This
parameter provides mostly indicative information. When used in
combination with Content-Disposition: attachment, it is used as the
default filename for an eventual "Save As" dialog presented to the
user.
Is this an error inside Spring ? I use Spring Boot 2.6.2
Unfortunately I can't change the non-working component for a quick test because it is a bought component that doesn't receive bugfixes very often.
I think that my problem is different from that described here because the failure only happens in a specific scenario.
It looks like you have to provide the filename. see this issue
This [The situation in which filename is not present] can lead to inconsistencies, e.g. you would get it with
MultipartFile but not with collection or array of MultipartFile, and
one can make the opposite argument that it should be rejected.
Why does it matter to have it injected as MultipartFile if it doesn't
even have a filename? You could also inject it as InputStream or any
other type supported by a registered HttpMessageConverter.

Can Jmeter LDAP Request or LDAP Extended Request populate a multi-valued attribute?

I am working on a Jmeter LDAP test plan and the test plan has to populate an attribute on the LDAP that is multi-valued.
When I do an LDAP search sampler, I noted that the value I get back is a string, with the values separated by ", ".
But, if I take the same comma-separated string and try to do an LDAP modify or add, using either an LDAP Request or LDAP Extended Request, I get an error.
So I am wondering if there is a way that the Jmeter LDAP Request or LDAP Extended Request can do that?
Thanks,
Jim
EDIT: When I try to use an Extended LDAP Request modification test/add with the attribute of "", I get this error in the Jmeter GUI response:
When attempting to modify entry cn=xxx... to replace the set of values for attribute lastlogindate, value "20181023085627-04, 20181024063205-04" was found to be invalid according to the associated syntax: The provided value "20181023085627-04, 20181024063205-04" is not a valid generalized time value because it contains an invalid character '-' at position 14
The strange part is that even though I have Jmeter to log at debug level, I don't see any detail on the error in the Jmeter.log, but/so I am guessing that that error message is coming from the Jmeter client itself. I noticed that the message says:
to replace the set of values
so it seems like it recognizes that I am trying to modify/replace a multi-value, but it doesn't seem to like the syntax of the replacement values string(s).
Does anyone know what the correct format SHOULD be?
I found the answer to my own question, or at least "A" answer: It appears that I can use an Extended LDAP request, and add the same attribute in that request, multiple times. So for example, if I am populating an attribute named "foo" the Extended LDAP request would have the following:
attribute value opcode
foo 12345 add
foo 12346 add
etc.
I think I also need to do a replace with no value, to empty the attribute, before all the adds.

How does json String to Object auto conversion works in Spring cloud Stream?

I am looking at this example - https://github.com/spring-cloud/spring-cloud-stream-samples/blob/master/kafka-streams-samples/kafka-streams-product-tracker/src/main/java/kafka/streams/product/tracker/KafkaStreamsProductTrackerApplication.java
Trying to do something similar, but for me it is not working. How does product json string is received as Product Object ?
By default, the deserialization on the inbound KStream is done by Spring Cloud Stream. The default content-type used is application/json (equivalent to providing the property: spring.cloud.stream.bindings.input.contentType: application/json). This is why the product json string is properly converted.
You can disable the framework level conversion and let Kafka do that in which case you need to provide the Serdes through properties. In order to enable native deserialization, you can set the property - spring.cloud.stream.bindings.input.consumer.useNativeDecoding: true. Then you need to provide the appropriate Serdes. More on all these are here: https://docs.spring.io/spring-cloud-stream/docs/Elmhurst.BUILD-SNAPSHOT/reference/htmlsingle/#_message_conversion

Disable automatic reply in Spring JMS

According to Spring reference documentation, method annotated with #JmsListener and have a non-void return type will have the result of the invocation encapsulated in a javax.jms.Message and sent either in the destination specified in the JMSReplyTo header of the original message or in the default destination configured on the listener.
If no destination is found then an InvalidDestinationException will be thrown.
Is there a way to disable this behavior of automatic reply ?
EDIT
I'm using an #AroundAdvice to log the result of the execution that's why i need to have a return type on my listener.
Returning null from the method if it has a return type, will disable reply processing.
You can detect the presence (or not) of a replyTo by adding a #Header parameter to the method.
Or, add a #SendTo with a destination to use if there's no header.
EDIT
Since you are using an advice to log the return value, you can simply return null from the advice, instead of the result of invocation.proceed().

Change Struts Validator default messages

I am new in struts2 . I have created an XML file for validations, but when I test my form I don't get the error messages that I configured in the XML file. instead I get the Struts 2 defaults messages such as this one :
invalid field value for field "capteur.ENERGIE_CAPTEUR".
Is there anyway to make struts2 prints the messages configured in the XML file instead of the default ones ?
That is not a validation error message, it is a conversion error message.
You can override the default conversion error message up to each single object, by creating an entry for it in the global .properties file, as described in Struts 2 documentation, Type Conversion Errors Handling:
By default, all conversion errors are reported using the generic i18n
key xwork.default.invalid.fieldvalue, which you can override (the
default text is Invalid field value for field "xxx", where xxx is the
field name) in your global i18n resource bundle.
However, sometimes you may wish to override this message on a
per-field basis. You can do this by adding an i18n key associated with
just your action (Action.properties) using the pattern
invalid.fieldvalue.xxx, where xxx is the field name.
If you are interested in understanding how it works in a deeper way, read the Short Story about Validation, Conversion and Friends.

Resources