package org.springframework.web.servlet.view.xml;

import java.io.ByteArrayOutputStream;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.xml.transform.stream.StreamResult;

import org.springframework.beans.BeansException;

import org.springframework.oxm.Marshaller;

import org.springframework.util.Assert;

import org.springframework.util.FileCopyUtils;

import org.springframework.web.servlet.view.AbstractView;

public class XmlMarshallerView extends AbstractView {

/**

     * Default content type. Overridable as bean property.

     */

    public static final String DEFAULT_CONTENT_TYPE = "application/xml";

private Marshaller marshaller;

    

    private JibxMarshallerFactory jibxMarshallerFactory;

    

    private String modelKey;

/**

     * Constructs a new {@code MarshallingView} with no {@link Marshaller} set. The marshaller must be set after

     * construction by invoking {@link #setMarshaller(Marshaller)}.

     */

    public XmlMarshallerView() {

        setContentType(DEFAULT_CONTENT_TYPE);

        setExposePathVariables(false);

    }

/**

     * Constructs a new {@code MarshallingView} with the given {@link Marshaller} set.

     */

    public XmlMarshallerView(Marshaller marshaller) {

        Assert.notNull(marshaller, "'marshaller' must not be null");

        setContentType(DEFAULT_CONTENT_TYPE);

        this.marshaller = marshaller;

        setExposePathVariables(false);

    }

public void setJibxMarshallerFactory(JibxMarshallerFactory jibxMarshallerFactory) {

        this.jibxMarshallerFactory = jibxMarshallerFactory;

    }

/**

     * Sets the {@link Marshaller} to be used by this view.

     */

    public void setMarshaller(Marshaller marshaller) {

        Assert.notNull(marshaller, "'marshaller' must not be null");

        this.marshaller = marshaller;

    }

/**

     * Set the name of the model key that represents the object to be marshalled. If not specified, the model map will be

     * searched for a supported value type.

     *

     * @see Marshaller#supports(Class)

     */

    public void setModelKey(String modelKey) {

        this.modelKey = modelKey;

    }

@Override

    protected void initApplicationContext() throws BeansException {

        if (marshaller == null && jibxMarshallerFactory == null) {

            throw new RuntimeException("Property 'marshaller' or 'jibxMarshallerFactory', at least one is required");

        }

    }

@Override

    protected void renderMergedOutputModel(Map<String, Object> model,

                                           HttpServletRequest request,

                                           HttpServletResponse response) throws Exception {

        Object toBeMarshalled = locateToBeMarshalled(model);

        

        if (toBeMarshalled == null) {

            throw new ServletException("Unable to locate object to be marshalled in model: " + model);

        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);

        marshaller.marshal(toBeMarshalled, new StreamResult(bos));

setResponseContentType(request, response);

        response.setContentLength(bos.size());

FileCopyUtils.copy(bos.toByteArray(), response.getOutputStream());

    }

/**

     * Locates the object to be marshalled. The default implementation first attempts to look under the configured

     * {@linkplain #setModelKey(String) model key}, if any, before attempting to locate an object of {@linkplain

     * Marshaller#supports(Class) supported type}.

     *

     * @param model the model Map

     * @return the Object to be marshalled (or {@code null} if none found)

     * @throws ServletException if the model object specified by the {@linkplain #setModelKey(String) model key} is not

     *                          supported by the marshaller

     * @see #setModelKey(String)

     */

    protected Object locateToBeMarshalled(Map<String, Object> model) throws ServletException {

        if (this.modelKey != null) {

            Object o = model.get(this.modelKey);

            if (o == null) {

                throw new ServletException("Model contains no object with key [" + modelKey + "]");

            }

            checkMarshaller(o);

            if (!this.marshaller.supports(o.getClass())) {

                throw new ServletException("Model object [" + o + "] retrieved via key [" + modelKey +

                        "] is not supported by the Marshaller");

            }

            return o;

        }

        for (Object o : model.values()) {

            if (o != null) {

                checkMarshaller(o);

                if (this.marshaller.supports(o.getClass())) {

                    return o;

                }

            }

        }

        return null;

    }

    

    /**

     * check the marshaller is null or not

     * @param object if the marshaller is null, will query from jibxMarshallerFactory by object

     */

    protected void checkMarshaller(Object object) {

        if (marshaller == null) {

            marshaller = jibxMarshallerFactory.getJibxMarshaller(object.getClass());

        }

    }

}

这个类参考了spring mvc的MarshallingView。不同就是引入了JibxMarshallerFactory。因为jibx 要对每个要序列化的类进行字节码增强。如果使用xstream等xml框架则不需要使用这个类。当然使用也是可以的。可以直接使用MarshallingView。

package com.vteba.service.xml.jibx;import java.util.HashMap;import java.util.List;import java.util.Map;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.InitializingBean;import org.springframework.oxm.jibx.JibxMarshaller;/**
 * JibxMarshaller Factory。
 * @author yinlei
 * date 2013-8-1 下午8:10:45
 */publicclassJibxMarshallerFactoryimplementsInitializingBean{
        privatestaticLogger logger =LoggerFactory.getLogger(JibxMarshallerFactory.class);
        privatestaticfinalString BINDING_NAME ="Binding";         privateList<Class<?>> targetClassList;
        privateMap<Class<?>,JibxMarshaller> jibxCache =newHashMap<Class<?>,JibxMarshaller>();         @Override
        publicvoid afterPropertiesSet()throwsException{
                if(targetClassList !=null){
                        for(Class<?> clazz : targetClassList){
                                JibxMarshaller jibxMarshaller =newJibxMarshaller();
                                jibxMarshaller.setTargetClass(clazz);
                                jibxMarshaller.setBindingName(BINDING_NAME);
                                jibxMarshaller.afterPropertiesSet();
                                jibxCache.put(clazz, jibxMarshaller);
                        }
                }else{
                        if(logger.isInfoEnabled()){
                                logger.info("JiBX映射目标类没有设置。运行时将无法获得JibxMarshaller实例。");
                        }
                }
        }         publicList<Class<?>> getTargetClassList(){
                return targetClassList;
        }         publicvoid setTargetClassList(List<Class<?>> targetClassList){
                this.targetClassList = targetClassList;
        }         publicJibxMarshaller getJibxMarshaller(Class<?> targetClass){
                return jibxCache.get(targetClass);
        }}

因为jibx对所有需要序列化的JavaBean都要事先注册,所以你要事先配置JibxMarshallerFactory,将所有要序列化的类都配置进去。

例如:

<beanid="jibxMarshallerFactory"class="com.vteba.service.xml.jibx.JibxMarshallerFactory">
                <propertyname="targetClassList">
                        <list>
                                <value>com.vteba.service.xml.jibx.Customer</value>
                        </list>
                </property>
        </bean>

绝对原创,转载请注明出处。

使用高性能xml序列化框架jibx作为spring mvc的xml view的更多相关文章

  1. 第二十四天 框架之痛-Spring MVC(四)

    6月3日,晴."绿树浓阴夏日长. 楼台倒影入池塘. 水晶帘动微风起, 满架蔷薇一院香". 以用户注冊过程为例.我们可能会选择继承AbstractController来实现表单的显示 ...

  2. Spring与Web框架(例如Spring MVC)漫谈——关于Spring对于多个Web框架的支持

    在看Spring MVC的官方文档时,最后一章是关于Spring对于其它Web框架的支持(如JSF,Apache Struts 2.x,Tapestry 5.x),当然Spring自己的MVC框架Sp ...

  3. spring mvc 返回xml格式数据

    1.问题 : 因为业务需要,需要发送xml格式的数据,使用spring mvc 自己解析,就不用费心去自己搞这些东西. 2.解决: 新建一个实体类,直接在实体类中添加注解即可,如下: @XmlRoot ...

  4. Spring MVC 返回 xml json pdf 数据的配置方法

    <!-- Spring MVC 返回 xml 数据的配置方法 -->     <bean class="org.springframework.web.servlet.vi ...

  5. spring boot 1.x完整学习指南(含各种常见问题servlet、web.xml、maven打包,spring mvc差别及解决方法)

    spring boot 入门 关于版本的选择,spring boot 2.0开始依赖于 Spring Framework 5.1.0,而spring 5.x和之前的版本差距比较大,而且应该来说还没有广 ...

  6. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  7. Spring MVC 的 XML 配置方式

    索引: 开源Spring解决方案--lm.solution 参看代码 GitHub: solution/pom.xml solution/webapi/pom.xml solution/mapper/ ...

  8. Spring MVC生成XML

    以下示例演示如何使用Spring Web MVC框架生成XML.首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: 创建一个名 ...

  9. Spring框架系列(一)--Spring MVC基础知识

    Web项目开发过程中一般都是使用MVC(Model-View-Controller)模式,早先的Struts2到Spring MVC,再到现在Spring Boot,都是相似的思 路.Spring B ...

随机推荐

  1. 从Qt4到Qt5的,主要的进化有三(对于QtWidget的精简和优化会很有限)

    从Qt4到Qt5的,主要的进化有三:1 语言的进化,原来是基于C++(qtwidget)和XML(.ui),现在添加了QML(QtQuick)+JS(v8)的架构.2 绘图系统的进化,原先基于QPai ...

  2. 转:DataTable的一些特殊用法:Select

    当你从数据库里取出一些数据,然后要对数据进行整合,你很容易就会想到: 1DataTable dt = new DataTable();//假设dt是由"SELECT C1,C2,C3 FRO ...

  3. MFC DestroyWindow窗口对象和窗口句柄的销毁

    考虑单窗口情况: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create.则销毁窗口的调用次序: 1. 手工调用pWnd->DestroyWindow(): 2. De ...

  4. codecomb 2092【课程选择】

    题目描述 大学选课总是烦恼着很多人.现在X同学选出了很多备选课,但是有的课程之间是有时间冲突的.X不会分身,自然无法在同一个时间上不同的课.每个课可能有很多备选时间,但是每个课只需要选一个时间上就可以 ...

  5. Maximum Depth of Binary Tree 解答

    Question Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along ...

  6. tangible T4 Editor 2.2.3 plus modeling tools for VS 2012 扩展名

    tangible T4 Editor 2.2.3 plus modeling tools for VS 2012 扩展名 tangible T4 Editor 2.2.3 plus modeling ...

  7. 【git学习二】git基础之git管理本地项目

    1.背景        git基础打算分两部分来说,一部分是对于本地项目的管理,第二部分是对于远程代码仓库的操作. git运行本地项目管理包含对于相关文件的追踪,暂存区的比較分析,提交,撤销等功能. ...

  8. Python 练习 —— 2048

    1. 引言 2048 这段时间火的不行啊,大家都纷纷仿造,"百家争鸣",于是出现了各种技术版本号:除了手机版本号,还有C语言版.Qt版.Web版.java版.C#版等,刚好我接触P ...

  9. Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7867340 在前面一篇文章中,我们分析了And ...

  10. ubuntu 下安装伪分布式 hadoop

    安装准备: (1)hadoop安装包:hadoop-1.2.1.tar.gz (2)jdk安装包:jdk-7u60-linux-i586.gz (3)要是须要eclipse开发的话 还须要eclips ...