@Override public Message<?> preSend(Message<?> message, MessageChannel channel) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { accessor.setImmutable(); } return message; }
/** * Return a mutable {@code MessageHeaderAccessor} for the given message attempting * to match the type of accessor used to create the message headers, or otherwise * wrapping the message with a {@code MessageHeaderAccessor} instance. * <p>This is for cases where a header needs to be updated in generic code * while preserving the accessor type for downstream processing. * @return an accessor of the required type (never {@code null}) * @since 4.1 */ public static MessageHeaderAccessor getMutableAccessor(Message<?> message) { if (message.getHeaders() instanceof MutableMessageHeaders) { MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) message.getHeaders(); MessageHeaderAccessor accessor = mutableHeaders.getAccessor(); return (accessor.isMutable() ? accessor : accessor.createAccessor(message)); } return new MessageHeaderAccessor(message); }
@Override public Message<?> preSend(Message<?> message, MessageChannel channel) { mutable.set(MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class).isMutable()); return message; } });
@Override public Message<?> preSend(Message<?> message, MessageChannel channel) { mutable.set(MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class).isMutable()); return message; } });
@Override public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) { if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { return MessageBuilder.createMessage(payload, accessor.getMessageHeaders()); } } return MessageBuilder.withPayload(payload).copyHeaders(headers).build(); }
@Override protected void handleMatch(SimpMessageMappingInfo mapping, HandlerMethod handlerMethod, String lookupDestination, Message<?> message) { Set<String> patterns = mapping.getDestinationConditions().getPatterns(); if (!CollectionUtils.isEmpty(patterns)) { String pattern = patterns.iterator().next(); Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(pattern, lookupDestination); if (!CollectionUtils.isEmpty(vars)) { MessageHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); Assert.state(mha != null && mha.isMutable(), "Mutable MessageHeaderAccessor required"); mha.setHeader(DestinationVariableMethodArgumentResolver.DESTINATION_TEMPLATE_VARIABLES_HEADER, vars); } } try { SimpAttributesContextHolder.setAttributesFromMessage(message); super.handleMatch(mapping, handlerMethod, lookupDestination, message); } finally { SimpAttributesContextHolder.resetAttributes(); } }
protected final void doSend(MessageChannel channel, Message<?> message, long timeout) { Assert.notNull(channel, "MessageChannel is required"); Message<?> messageToSend = message; MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { accessor.removeHeader(this.sendTimeoutHeader); accessor.removeHeader(this.receiveTimeoutHeader); accessor.setImmutable(); } else if (message.getHeaders().containsKey(this.sendTimeoutHeader) || message.getHeaders().containsKey(this.receiveTimeoutHeader)) { messageToSend = MessageBuilder.fromMessage(message) .setHeader(this.sendTimeoutHeader, null) .setHeader(this.receiveTimeoutHeader, null) .build(); } boolean sent = (timeout >= 0 ? channel.send(messageToSend, timeout) : channel.send(messageToSend)); if (!sent) { throw new MessageDeliveryException(message, "Failed to send message to channel '" + channel + "' within timeout: " + timeout); } }
@Override @Nullable public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { if (!canConvertTo(payload, headers)) { return null; } Object payloadToUse = convertToInternal(payload, headers, conversionHint); if (payloadToUse == null) { return null; } MimeType mimeType = getDefaultContentType(payloadToUse); if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { if (mimeType != null) { accessor.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType); } return MessageBuilder.createMessage(payloadToUse, accessor.getMessageHeaders()); } } MessageBuilder<?> builder = MessageBuilder.withPayload(payloadToUse); if (headers != null) { builder.copyHeaders(headers); } if (mimeType != null) { builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType); } return builder.build(); }
@Test public void convertAndSendWithSimpMessageHeaders() { MessageHeaderAccessor accessor = new MessageHeaderAccessor(); accessor.setHeader("key", "value"); accessor.setLeaveMutable(true); MessageHeaders headers = accessor.getMessageHeaders(); this.template.convertAndSend("channel", "data", headers); List<Message<byte[]>> messages = this.messageChannel.getMessages(); Message<byte[]> message = messages.get(0); assertSame(headers, message.getHeaders()); assertFalse(accessor.isMutable()); }
@Test public void getMutableAccessorNewInstanceMatchingType() { TestMessageHeaderAccessor expected = new TestMessageHeaderAccessor(); Message<?> message = MessageBuilder.createMessage("payload", expected.getMessageHeaders()); MessageHeaderAccessor actual = MessageHeaderAccessor.getMutableAccessor(message); assertNotNull(actual); assertTrue(actual.isMutable()); assertEquals(TestMessageHeaderAccessor.class, actual.getClass()); }
@Test public void getMutableAccessorNewInstance() { Message<?> message = MessageBuilder.withPayload("payload").build(); MessageHeaderAccessor actual = MessageHeaderAccessor.getMutableAccessor(message); assertNotNull(actual); assertTrue(actual.isMutable()); }
@Test public void getMutableAccessorSameInstance() { TestMessageHeaderAccessor expected = new TestMessageHeaderAccessor(); expected.setLeaveMutable(true); Message<?> message = MessageBuilder.createMessage("payload", expected.getMessageHeaders()); MessageHeaderAccessor actual = MessageHeaderAccessor.getMutableAccessor(message); assertNotNull(actual); assertTrue(actual.isMutable()); assertSame(expected, actual); }
@Override public Message<?> preSend(Message<?> message, MessageChannel channel) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { accessor.setImmutable(); } return message; }
/** * Return a mutable {@code MessageHeaderAccessor} for the given message attempting * to match the type of accessor used to create the message headers, or otherwise * wrapping the message with a {@code MessageHeaderAccessor} instance. * <p>This is for cases where a header needs to be updated in generic code * while preserving the accessor type for downstream processing. * @return an accessor of the required type (never {@code null}) * @since 4.1 */ public static MessageHeaderAccessor getMutableAccessor(Message<?> message) { if (message.getHeaders() instanceof MutableMessageHeaders) { MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) message.getHeaders(); MessageHeaderAccessor accessor = mutableHeaders.getAccessor(); return (accessor.isMutable() ? accessor : accessor.createAccessor(message)); } return new MessageHeaderAccessor(message); }
@Override public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) { if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { return MessageBuilder.createMessage(payload, accessor.getMessageHeaders()); } } return MessageBuilder.withPayload(payload).copyHeaders(headers).build(); }
@Override protected void handleMatch(SimpMessageMappingInfo mapping, HandlerMethod handlerMethod, String lookupDestination, Message<?> message) { Set<String> patterns = mapping.getDestinationConditions().getPatterns(); if (!CollectionUtils.isEmpty(patterns)) { String pattern = patterns.iterator().next(); Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(pattern, lookupDestination); if (!CollectionUtils.isEmpty(vars)) { MessageHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); Assert.state(mha != null && mha.isMutable(), "Mutable MessageHeaderAccessor required"); mha.setHeader(DestinationVariableMethodArgumentResolver.DESTINATION_TEMPLATE_VARIABLES_HEADER, vars); } } try { SimpAttributesContextHolder.setAttributesFromMessage(message); super.handleMatch(mapping, handlerMethod, lookupDestination, message); } finally { SimpAttributesContextHolder.resetAttributes(); } }
protected final void doSend(MessageChannel channel, Message<?> message, long timeout) { Assert.notNull(channel, "MessageChannel is required"); Message<?> messageToSend = message; MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { accessor.removeHeader(this.sendTimeoutHeader); accessor.removeHeader(this.receiveTimeoutHeader); accessor.setImmutable(); } else if (message.getHeaders().containsKey(this.sendTimeoutHeader) || message.getHeaders().containsKey(this.receiveTimeoutHeader)) { messageToSend = MessageBuilder.fromMessage(message) .setHeader(this.sendTimeoutHeader, null) .setHeader(this.receiveTimeoutHeader, null) .build(); } boolean sent = (timeout >= 0 ? channel.send(messageToSend, timeout) : channel.send(messageToSend)); if (!sent) { throw new MessageDeliveryException(message, "Failed to send message to channel '" + channel + "' within timeout: " + timeout); } }
@Override @Nullable public final Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { if (!canConvertTo(payload, headers)) { return null; } Object payloadToUse = convertToInternal(payload, headers, conversionHint); if (payloadToUse == null) { return null; } MimeType mimeType = getDefaultContentType(payloadToUse); if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { if (mimeType != null) { accessor.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType); } return MessageBuilder.createMessage(payloadToUse, accessor.getMessageHeaders()); } } MessageBuilder<?> builder = MessageBuilder.withPayload(payloadToUse); if (headers != null) { builder.copyHeaders(headers); } if (mimeType != null) { builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, mimeType); } return builder.build(); }
@Override public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) { if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { return MessageBuilder.createMessage(payload, accessor.getMessageHeaders()); } } return MessageBuilder.withPayload(payload).copyHeaders(headers).build(); }
@Override public Message<?> toMessage(Object payload, @Nullable MessageHeaders headers) { if (headers != null) { MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class); if (accessor != null && accessor.isMutable()) { return MessageBuilder.createMessage(payload, accessor.getMessageHeaders()); } } return MessageBuilder.withPayload(payload).copyHeaders(headers).build(); }