All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.messaging.converter.MarshallingMessageConverter Maven / Gradle / Ivy

There is a newer version: 6.2.0
Show newest version
/*
 * Copyright 2002-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.messaging.converter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.beans.TypeMismatchException;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;

/**
 * Implementation of {@link MessageConverter} that can read and write XML using Spring's
 * {@link Marshaller} and {@link Unmarshaller} abstractions.
 *
 * 

This converter requires a {@code Marshaller} and {@code Unmarshaller} before it can * be used. These can be injected by the {@linkplain #MarshallingMessageConverter(Marshaller) * constructor} or {@linkplain #setMarshaller(Marshaller) bean properties}. * * @author Arjen Poutsma * @since 4.2 * @see Marshaller * @see Unmarshaller */ public class MarshallingMessageConverter extends AbstractMessageConverter { @Nullable private Marshaller marshaller; @Nullable private Unmarshaller unmarshaller; /** * Default construct allowing for {@link #setMarshaller(Marshaller)} and/or * {@link #setUnmarshaller(Unmarshaller)} to be invoked separately. */ public MarshallingMessageConverter() { this(new MimeType("application", "xml"), new MimeType("text", "xml"), new MimeType("application", "*+xml")); } /** * Constructor with a given list of MIME types to support. * @param supportedMimeTypes the MIME types */ public MarshallingMessageConverter(MimeType... supportedMimeTypes) { super(supportedMimeTypes); } /** * Constructor with {@link Marshaller}. If the given {@link Marshaller} also * implements {@link Unmarshaller}, it is also used for unmarshalling. *

Note that all {@code Marshaller} implementations in Spring also implement * {@code Unmarshaller} so that you can safely use this constructor. * @param marshaller object used as marshaller and unmarshaller */ public MarshallingMessageConverter(Marshaller marshaller) { this(); Assert.notNull(marshaller, "Marshaller must not be null"); this.marshaller = marshaller; if (marshaller instanceof Unmarshaller _unmarshaller) { this.unmarshaller = _unmarshaller; } } /** * Set the {@link Marshaller} to be used by this message converter. */ public void setMarshaller(@Nullable Marshaller marshaller) { this.marshaller = marshaller; } /** * Return the configured Marshaller. */ @Nullable public Marshaller getMarshaller() { return this.marshaller; } /** * Set the {@link Unmarshaller} to be used by this message converter. */ public void setUnmarshaller(@Nullable Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; } /** * Return the configured unmarshaller. */ @Nullable public Unmarshaller getUnmarshaller() { return this.unmarshaller; } @Override protected boolean canConvertFrom(Message message, Class targetClass) { return (supportsMimeType(message.getHeaders()) && this.unmarshaller != null && this.unmarshaller.supports(targetClass)); } @Override protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) { return (supportsMimeType(headers) && this.marshaller != null && this.marshaller.supports(payload.getClass())); } @Override protected boolean supports(Class clazz) { // should not be called, since we override canConvertFrom/canConvertTo instead throw new UnsupportedOperationException(); } @Override @Nullable protected Object convertFromInternal(Message message, Class targetClass, @Nullable Object conversionHint) { Assert.state(this.unmarshaller != null, "Property 'unmarshaller' is required"); try { Source source = getSource(message.getPayload()); Object result = this.unmarshaller.unmarshal(source); if (!targetClass.isInstance(result)) { throw new TypeMismatchException(result, targetClass); } return result; } catch (Exception ex) { throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex); } } private Source getSource(Object payload) { if (payload instanceof byte[] bytes) { return new StreamSource(new ByteArrayInputStream(bytes)); } else { return new StreamSource(new StringReader(payload.toString())); } } @Override @Nullable protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { Assert.state(this.marshaller != null, "Property 'marshaller' is required"); try { if (byte[].class == getSerializedPayloadClass()) { ByteArrayOutputStream out = new ByteArrayOutputStream(1024); Result result = new StreamResult(out); this.marshaller.marshal(payload, result); payload = out.toByteArray(); } else { Writer writer = new StringWriter(1024); Result result = new StreamResult(writer); this.marshaller.marshal(payload, result); payload = writer.toString(); } } catch (Throwable ex) { throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex); } return payload; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy