`

Spring MVC JSON转换自定义注解

阅读更多

1.JSON转换

package cn.com.shopec.app.convert;

import cn.com.shopec.app.common.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;


/**
 * Created by guanfeng.li on 2016/7/18.
 */
public class JSONHttpMessageConverter extends FastJsonHttpMessageConverter {

    private Log log = LogFactory.getLog(JSONHttpMessageConverter.class);

    //字符集
    private String charset = "UTF-8";
    //漂亮格式化
    private boolean prettyFormat = false;
    private boolean recordeResult = true;

    @Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        if(obj instanceof Result){
//            writer(obj, outputMessage);
            writerResult(obj, outputMessage);
        }else{
            super.writeInternal(obj, outputMessage);
        }
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json转换
     */
    private void writerResult(Object obj, HttpOutputMessage outputMessage) throws IOException {
        Result result = (Result) obj;
        result.addSerializerFeature(SerializerFeature.SortField,SerializerFeature.DisableCircularReferenceDetect);
        if(prettyFormat){
            result.addSerializerFeature(SerializerFeature.PrettyFormat);
        }
        String json = result.toString();
        OutputStream out = null;
        try {
            out = outputMessage.getBody();
            out.write(json.getBytes(charset));
            out.flush();
        } finally {
            out.close();
        }
        if(recordeResult){
            log.info("JSON:"+json);
        }
    }

    //json转换
    private void writer(Object obj, HttpOutputMessage outputMessage) throws IOException {
        Result result = (Result) obj;
        result.addSerializerFeature(SerializerFeature.SortField);
        if(prettyFormat){
            result.addSerializerFeature(SerializerFeature.PrettyFormat);
        }
        result.addSerializeFilter(Result.class,"jsonConfig,jsonFeatures,jsonFilter",false);

        SerializerFeature[] features = new SerializerFeature[result.getJsonFeatures()==null?0:result.getJsonFeatures().size()];
        if(result.getJsonFeatures()!=null){
            result.getJsonFeatures().toArray(features);
        }

        SerializeFilter[] filters = new SerializeFilter[result.getJsonFilter()==null?0:result.getJsonFilter().size()];
        if(result.getJsonFilter()!=null){
            result.getJsonFilter().toArray(filters);
        }
        SerializeConfig jsonConfig = result.getJsonConfig();
        String json ;
        if(jsonConfig!=null){
            json = JSON.toJSONString(obj,jsonConfig,filters,features);
        }else{
            json = JSON.toJSONString(obj,filters,features);
        }
        outputMessage.getBody().write(json.getBytes(charset));
        log.info("返回JSON结果:\n"+json);
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public void setPrettyFormat(boolean prettyFormat) {
        this.prettyFormat = prettyFormat;
    }

    public void setRecordeResult(boolean recordeResult) {
        this.recordeResult = recordeResult;
    }
}

 

2.自定义注解

package cn.com.shopec.app.mvc.annotation;

import java.lang.annotation.*;

/**
 * Created by guanfeng.li on 2016/8/26.
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestAttribute {

    String value() default "";

}

 

package cn.com.shopec.app.mvc.support;

import cn.com.shopec.app.mvc.annotation.RequestAttribute;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by guanfeng.li on 2016/8/26.
 */
public class RequestAttributeHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        RequestAttribute requestAttribute = parameter.getParameterAnnotation(RequestAttribute.class);
        if(requestAttribute!=null){
            return true;
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest req = webRequest.getNativeRequest(HttpServletRequest.class);
        if(req!=null){
            RequestAttribute requestAttribute = parameter.getParameterAnnotation(RequestAttribute.class);
            String value = requestAttribute.value();
            if(StringUtils.isNotEmpty(value)){
                return req.getAttribute(value);
            }

            if(StringUtils.isEmpty(value)){
                String parameterName = parameter.getParameterName();
                return req.getAttribute(parameterName);
            }
        }
        return null;
    }
}

 3.Spring MVC配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">

	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations" value="classpath:*.properties" />
	</bean>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>


    <mvc:default-servlet-handler/>

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean id="fastJsonHttpMessageConverter" class="cn.com.shopec.app.convert.JSONHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                    </list>
                </property>
                <!--是否漂亮格式化JSON结果-->
                <property name="prettyFormat" value="false"></property>
                <!--是否记录JSON返回结果-->
                <property name="recordeResult" value="false"></property>
            </bean>
        </mvc:message-converters>
        <mvc:argument-resolvers>
            <bean class="cn.com.shopec.app.mvc.support.RequestAttributeHandlerMethodArgumentResolver"></bean>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

    <!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 -->
	<context:component-scan base-package="cn.com.shopec.app.controller" >
    </context:component-scan>
	<!-- 默认的注解映射的支持 -->
	<mvc:annotation-driven />

	<!-- 对静态资源文件的访问 -->
	<!--<mvc:resources mapping="/res/**" location="/res/" />-->

	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="defaultEncoding">
			<value>UTF-8</value>
		</property>
		<property name="maxUploadSize">
			<value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 -->
		</property>
		<property name="maxInMemorySize">
			<value>4096</value>
		</property>
	</bean>


    <!--统一异常处理-->
    <bean id="exceptionHandler" class="cn.com.shopec.app.exception.ExceptionHandler"/>

    <!-- 系统错误转发配置[并记录错误日志] -->
    <bean id="exceptionResolver"
          class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!--<property name="defaultErrorView" value="error"></property>   &lt;!&ndash; 默认为500,系统错误(error.jsp) &ndash;&gt;-->
        <property name="exceptionMappings">
            <props>
                <prop key="cn.com.shopec.app.exception.ExceptionHandler">error</prop>
            </props>
        </property>
    </bean>

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/public/api/**"/>
            <mvc:mapping path="/app/api/**"/>
            <bean class="cn.com.shopec.app.intercept.CommonIntercept"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/app/api/**"/>
            <mvc:mapping path="/api/**"/>
            <bean class="cn.com.shopec.app.intercept.TokenIntercept"/>
        </mvc:interceptor>
        <!--<mvc:interceptor>-->
            <!--<mvc:mapping path="/wechat/**"/>-->
            <!--<mvc:exclude-mapping path="/wechat/index"/>-->
            <!--<bean class="cn.com.shopec.app.intercept.WechatIntercept"/>-->
        <!--</mvc:interceptor>-->
    </mvc:interceptors>


</beans>

 4.接口消息实体类

package cn.com.shopec.app.common;


import cn.com.shopec.core.common.PageFinder;
import cn.com.shopec.core.common.Query;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.*;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.*;

/**
 * Created by guanfeng.li on 2016/7/8.
 * APP接口返回实体类
 */
public class Result implements Serializable {

    //状态码
    private String status = "200";
    //消息提示
    private String msg = "";
    //响应数据
    private Object data;
    //分页
    private PageFinder page;

    //json格式化
    private SerializeConfig jsonConfig;
    //json 特性配置
    private Set<SerializerFeature> jsonFeatures;
    //json 属性过滤
    private Set<SerializeFilter> jsonFilter;

    public Result() {

    }

    public Result(Object data, Query query, long rowCount) {
        this.data = data;
        this.page = new PageFinder<>(query.getPageNo(), query.getPageSize(), rowCount);
    }

    public Result(String status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public Result(Object data) {
        this.data = data;
    }

    public Result(Object data,PageFinder page) {
        this.data = data;
        this.page = page;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * 特性配置
     */
    public Result addSerializerFeature(SerializerFeature... serializerFeatures) {
        addSerializerFeature(3, serializerFeatures);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * 特性配置
     */
    public Result addSerializerFeature(int size, SerializerFeature... serializerFeatures) {
        if (jsonFeatures == null) {
            jsonFeatures = new HashSet<>(size);
        }
        for (SerializerFeature item : serializerFeatures) {
            jsonFeatures.add(item);
        }
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json 属性过滤
     */
    public Result addSerializeFilter(Class<?> clazz, String properties) {
        addSerializeFilter(3, clazz, properties, true);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json 属性过滤
     */
    public Result addSerializeFilter(Class<?> clazz, String properties, boolean isinclude) {
        addSerializeFilter(3, clazz, properties, isinclude);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json 属性过滤
     */
    public Result addSerializeFilter(int size, Class<?> clazz, String properties, boolean isinclude) {
        if (jsonFilter == null) {
            jsonFilter = new HashSet<>();
        }
        if(clazz!=null && properties==null){
            jsonFilter.add(new SimplePropertyPreFilter(clazz));
            return this;
        }
        if(clazz==null && properties!=null){
            jsonFilter.add(new SimplePropertyPreFilter(properties.split(",")));
            return this;
        }
        if (!isinclude) {
            SimplePropertyPreFilter filter = new SimplePropertyPreFilter(clazz);
            filter.getExcludes().addAll(Arrays.asList(properties.split(",")));
            jsonFilter.add(filter);
        } else {
            jsonFilter.add(new SimplePropertyPreFilter(clazz, properties.split(",")));
        }
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * 过滤分页信息
     */
    public Result filterPage(){
        addSerializeFilter(this.getClass(),"page",false);
        return  this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json格式化
     */
    public Result putSerializeConfig(Class cls, ObjectSerializer value) {
        putSerializeConfig(3, cls, value);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * json格式化
     */
    public Result putSerializeConfig(int size, Class cls, ObjectSerializer value) {
        if (jsonConfig == null) {
            jsonConfig = new SerializeConfig(size);
        }
        jsonConfig.put(cls, value);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * 空字符串显示 “”
     * 空集合 []
     * 空Map {}
     * Number 0
     */
    public Result writeNullStringNumberListAsEmpty() {
        addSerializerFeature(5, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteNullListAsEmpty);
        return this;
    }

    public Result writeNullStringAsEmpty() {
        addSerializerFeature(2, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty);
        return this;
    }

    public Result writeNullListAsEmpty() {
        addSerializerFeature(2, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty);
        return this;
    }

    public Result writeNullNumberAsZero() {
        addSerializerFeature(2, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullNumberAsZero);
        return this;
    }

    /**
     * Created by guanfeng.li   2016/7/19
     * 漂亮格式化
     */
    public Result prettyFormat() {
        addSerializerFeature(SerializerFeature.PrettyFormat);
        return this;
    }

    //添加返回结果
    public Result put(String key, Object value) {
        if (data == null) {
            data = new HashMap();
        } else {
            if (!(data instanceof Map)) {
                return this;
            }
        }

        ((Map) data).put(key, value);
        return this;
    }

    public String getStatus() {
        return status;
    }

    public Result setStatus(String status) {
        this.status = status;
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public Result setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public PageFinder getPage() {
        return page;
    }

    public Result setPage(PageFinder page) {
        this.page = page;
        return this;
    }

    public SerializeConfig getJsonConfig() {
        return jsonConfig;
    }

    public Set<SerializerFeature> getJsonFeatures() {
        return jsonFeatures;
    }

    public Set<SerializeFilter> getJsonFilter() {
        return jsonFilter;
    }

    @Override
    public String toString() {
        if (jsonFilter != null || jsonFeatures != null || jsonConfig != null) {
            addSerializeFilter(Result.class, "jsonConfig,jsonFeatures,jsonFilter", false);
        }
        SerializerFeature[] features = new SerializerFeature[jsonFeatures == null ? 0 : jsonFeatures.size()];
        if (jsonFeatures != null) {
            jsonFeatures.toArray(features);
        }

        SerializeFilter[] filters = new SerializeFilter[jsonFilter == null ? 0 : jsonFilter.size()];
        if (jsonFilter != null) {
            jsonFilter.toArray(filters);
        }
        String json;
        if (jsonConfig != null) {
            json = JSON.toJSONString(this, jsonConfig, filters, features);
        } else {
            json = JSON.toJSONString(this, filters, features);
        }
        return json;
    }
}

 

分享到:
评论

相关推荐

    Spring+Spring mvc+Hibernate+Bootstrap、企业级员工信息管理系统

    Spring mvc 返回数据格式采用统一的对象(JSONReturn)进行封装 09. 通过自定义处理器 ExceptionIntercept 实现 Spring mvc的全局异常捕获 10. 系统中包含了企业中采用的开发工具类的集合 11. AbstractDao 父类...

    SpringMVCDemo:Spring MVC 框架知识案例

    1.创建第一个 Spring MVC 程序案例 2.Spring MVC @RequestMapping 注解案例 ...12.Spring MVC 实现 JSON 数据返回案例 13.Spring MVC 文件的上传与下载案例 14.Spring MVC 拦截器案例 15.Spring MVC 异常处理案例

    Spring3MVC注解教程.ppt

    《Spring MVC 3.0实战指南》,参考《Spring 3.x企业应用开发实战》。 内容简介: 1、Spring MVC框架简介 2、HTTP请求地址映射 3、HTTP请求数据的绑定 4、数据转换、格式化、校验 5、数据模型控制 6、视图及...

    Spring MVC 3.0实战指南.ppt

    《Spring MVC 3.0实战指南》,参考《Spring 3.x企业应用开发实战》。 内容简介: 1、Spring MVC框架简介 2、HTTP请求地址映射 3、HTTP请求数据的绑定 4、数据转换、格式化、校验 5、数据模型控制 6、视图及解析器 7...

    Spring3 MVC Ajax with JSON

    Ajax With Spring 3. Eclipse 工程,包含Web所需要的 所有jar包。 1&gt; ajax 请求。 2&gt; spring 3注解使用 3&gt; mvc:annotation

    Spring mvc 接收json对象

    本文通过代码实例介绍spring mvc 接收json数据的方法,具体详情如下所示: 接收JSON 使用 @RequestBody 注解前台只需要向 Controller 提交一段符合格式的 JSON,Spring 会自动将其拼装成 bean。 1)在上面的项目中...

    Spring MVC 3 实例

    Spring MVC 3实例,包含上传下载,还有Spring mvc jsr303表单验证技术,还有一个spring mvc ajax json等 欢迎下载 自己研究,简单易懂 如果有注解不懂,可以看看...

    Spring MVC – Easy REST-Based JSON Services with @ResponseBody

    NULL 博文链接:https://nethub2.iteye.com/blog/2329387

    spring mvc 3.2 参考文档

    Spring MVC 框架简介 Spring Web model-view-controller (MVC)框架是围绕 DispatcherServlet 设计的,并分发请求到处理程序(handler),Spring MVC支持可配置的处理程序映射(handler mapping),视图解析(view ...

    Spring mvc实现Restful返回json格式数据实例详解

    在本示例中,我们将向您展示如何将对象转换成json格式并通过spring mvc框架返回给用户。 使用技术及环境: Spring 3.2.2.RELEASE Jackson 1.9.10 JDK 1.6 Eclipse 3.6 Maven 3 PS:在spring 3 中,要输出json...

    spring杂谈 作者zhang KaiTao

    1. spring杂谈[原创] 1.1 Spring事务处理时自我调用的解决方案及一些实现方式的风险 ...1.32 Spring3 Web MVC下的数据类型转换(第一篇)——《跟我学Spring3 Web MVC》抢先看 1.33 Spring 注入集合类型

    spring-basic:弹簧基础

    spring-basic spring核心知识学习 弹簧芯 2015-05-18 春天环境搭建 spring xml配置 弹簧配置(xml,注释,java) spring Bean 自动装配(xml) spring Bean 自动装配... 3.Spring MVC 查看JSON | XML | PDF | 卓越

    spring_MVC源码

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...

    Spring MVC之@RequestMapping详解

    前段时间项目中用到了REST风格来开发程序,但是当用POST、PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没有加任何注解),查看了提交方式为application/json, 而且服务器端通过request....

    SpringMVC返回json数据的三种方式

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC架构,从而在使用Spring进行WEB开发时,可以选择使用...

    Spring MVC+Maven+Eclipse工程框架

    使用Eclipse配置一个SpringMVC + Maven的工程。具体的步骤可以参考博客:http://limingnihao.iteye.com/blog/830409。 附件对于一些注解、json的配置已经完成,并且有一个TestController可以做测试。

    rural:基于spring的mvc框架,使用简单,URL映射零配置零注解

     Rural是一个基于spring的mvc框架,设计上类似spring mvc,相比于spring mvc,Rural使用更简便,无需配置和注解就可以实现URL到java方法的映射。 取名Rural(乡村风味的,田园的)寓意简洁。  目前Rural支持json,...

    Spring.3.x企业应用开发实战(完整版).part2

    2.5.1 配置Spring MVC框架 2.5.2 处理登录请求 2.5.3 JSP视图页面 2.6 运行Web应用 2.7 小结 第2篇 IoC和AOP 第3章 IoC容器概述 3.1 IoC概述 3.1.1 通过实例理解IoC的概念 3.1.2 IoC的类型 3.1.3 通过容器完成依赖...

    SpringDataMongoDB:SpringMVC SpringData MongoDB注解

    版本 1.0 日期:2013 年 3 月 7 日 Simple Spring MVC、Spring DATA、MongoDB、Annotations Project With one Entity only Save、update、delete、findById、FindAll 方法 Controller、Services、Dao 层返回 JSON ...

Global site tag (gtag.js) - Google Analytics