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

org.springframework.http.converter.xml.SimpleXmlHttpMessageConverter Maven / Gradle / Ivy

/*
 * Copyright 2011 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
 *
 *      http://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.http.converter.xml;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;

import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.Assert;

/**
 * Implementation of {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverter}
 * that can read and write XML using Simple's {@link Serializer} abstraction.
 * *
 * 

By default, this converter supports {@code text/xml} and {@code application/xml}. This can be * overridden by setting the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes} property. * * @author Roy Clarkson * @since 1.0 */ public class SimpleXmlHttpMessageConverter extends AbstractHttpMessageConverter { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private Serializer serializer; /** * Construct a new {@code SimpleXmlHttpMessageConverter} with a default {@link Serializer}. * Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes} * to {@code text/xml} and {@code application/xml}, and {@code application/*+xml}. */ public SimpleXmlHttpMessageConverter() { this(new Persister()); } /** * Construct a new {@code SimpleXmlHttpMessageConverter} with a customized {@link Serializer}. * Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes} * to {@code text/xml} and {@code application/xml}, and {@code application/*-xml}. */ public SimpleXmlHttpMessageConverter(Serializer serializer) { super(MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_WILDCARD_XML); setSerializer(serializer); } /** * Sets the {@code Serializer} for this view. If not set, a default * {@link Serializer} is used. *

Setting a custom-configured {@code Serializer} is one way to take further control of the XML serialization * process. * @throws IllegalArgumentException if serializer is null */ public void setSerializer(Serializer serializer) { Assert.notNull(serializer, "'serializer' must not be null"); this.serializer = serializer; } @Override public boolean canRead(Class clazz, MediaType mediaType) { return canRead(mediaType); } @Override public boolean canWrite(Class clazz, MediaType mediaType) { return clazz.isAnnotationPresent(Root.class) && canWrite(mediaType); } @Override protected boolean supports(Class clazz) { // should not be called, since we override canRead/Write throw new UnsupportedOperationException(); } @Override protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { Reader source = new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders())); try { Object result = this.serializer.read(clazz, source); if (!clazz.isInstance(result)) { throw new TypeMismatchException(result, clazz); } return result; } catch (Exception ex) { throw new HttpMessageNotReadableException("Could not read [" + clazz + "]", ex); } } @Override protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { Writer out = new OutputStreamWriter(outputMessage.getBody(), getCharset(outputMessage.getHeaders())); try { this.serializer.write(o, out); out.close(); } catch (Exception ex) { throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex); } } // helpers private Charset getCharset(HttpHeaders headers) { if (headers != null && headers.getContentType() != null && headers.getContentType().getCharSet() != null) { return headers.getContentType().getCharSet(); } return DEFAULT_CHARSET; } }