`

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 mvc json&&jackson jquery js

    Spring MVC中的`@ResponseBody`注解可以将方法的返回值直接转换为JSON格式发送到客户端,而`@RequestBody`则可以将请求体中的JSON数据解析成Java对象。 **Jackson** Jackson是Java中广泛使用的JSON库,它可以高效地...

    spring mvc(整合了json)

    2. **配置 Spring MVC**:在 Spring MVC 的配置文件中,我们需要添加 `Jackson` 的转换器,使得 Spring MVC 能够解析和生成 JSON 数据。例如,在使用 XML 配置时,可以添加以下配置: ```xml &lt;bean class="org....

    Spring mvc Json处理实现流程代码实例

    更简洁的方式是使用`@RequestBody`注解,该注解告诉Spring MVC使用合适的HttpMessageConverter将请求体中的JSON数据自动转换为指定类型的Java对象。例如: ```java @RequestMapping("/addbook3") @ResponseBody...

    spring mvc json学习

    总之,"Spring MVC JSON学习"涵盖了许多关键概念,包括JSON数据的序列化和反序列化、控制器中使用`@RequestBody`和`@ResponseBody`、自定义序列化逻辑以及测试JSON API。掌握这些知识点将使你能够构建出高效、健壮的...

    SpringMVC中后台转换json格式

    此外,为了让SpringMVC知道如何将你的Java对象转换为JSON,你需要在你的模型类上使用Jackson的注解,例如`@JsonProperty`、`@JsonInclude`、`@JsonIgnore`等。这些注解可以帮助控制哪些属性应该被包含在JSON中,哪些...

    Spring MVC 的注解使用实例

    在Spring MVC框架中,注解的使用极大地简化了配置,提高了开发效率。Spring MVC通过注解可以实现控制器、方法映射、模型数据绑定、视图解析等关键功能。本实例将深入探讨Spring MVC中常见的注解及其应用。 1. `@...

    解决spring mvc JSON 无限死循环

    ### 解决Spring MVC JSON无限...总结来说,解决Spring MVC中的JSON无限死循环问题通常涉及调整实体类的序列化方式,使用注解或自定义序列化器等手段来避免无限递归。开发者可以根据实际需求选择合适的方法来解决问题。

    Spring MVC 学习笔记 九 json格式的输入和输出

    在Spring MVC中,我们可以使用Jackson库或者Gson库将Java对象转换为JSON字符串,反之亦然。 2. **Spring MVC中的JSON配置** 在Spring MVC项目中,我们需要引入相应的JSON库,如Jackson的`jackson-databind`依赖。...

    Spring MVC工作原理 及注解说明1

    以下是Spring MVC工作原理及注解的详细说明: 1. **Spring MVC组件及职责**: - **DispatcherServlet**:前端控制器,所有请求首先会到达这里,它负责调度请求,根据HandlerMapping找到合适的Controller。 - **...

    基于注解Spring MVC环境搭建

    创建Spring MVC项目时,需要在`pom.xml`文件中添加Spring MVC、Spring核心以及其他依赖,如Spring Web和Jackson库(用于JSON序列化和反序列化)。 10. **IDE集成** 使用Eclipse、IntelliJ IDEA等IDE,可以快速...

    spring4 mvc json配置jar包

    在开发基于Spring4 MVC的Web应用时,JSON(JavaScript Object Notation)是一种常见的数据交换格式,用于前后端之间的通信。为了使Spring MVC能够处理JSON序列化和反序列化,我们需要引入一系列的Jackson库。这些库...

    Mastering Spring MVC 4(2015.09)源码

    此外,Spring MVC 4还支持RESTful风格的Web服务,通过@RequestMapping注解的produces和consumes属性,可以处理不同格式的HTTP请求和响应,如JSON、XML等。 总的来说,"Mastering Spring MVC 4(2015.09)源码"提供了...

    spring mvc 注解实例

    在这个注解实例中,我们将深入探讨Spring MVC中的核心注解以及如何利用它们实现对数据库表的增删改查(CRUD)操作。拦截器是Spring MVC中的另一个重要概念,它允许我们在请求处理前后执行自定义逻辑。 首先,让我们...

    使用 Spring 2_5 基于注解驱动的 Spring MVC

    在本主题中,我们将深入探讨Spring框架的2.5版本引入的一个重要特性——基于注解的Spring MVC配置。Spring MVC是Spring框架的一部分,专门用于构建Web应用程序,它提供了一个模型-视图-控制器(MVC)架构来组织和...

    spring MVC 对 ResponseBody返回json数据进行脱敏处理

    在Spring MVC框架中,开发Web应用时经常需要将对象转换为JSON格式的数据并返回给客户端。然而,在处理敏感数据时,我们可能希望对这些数据进行脱敏,即隐藏或替换某些字段,以保护用户隐私或者确保数据安全性。本文...

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

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

    springmvc操作json数据所需的jar包

    总结,Spring MVC处理JSON数据的关键在于引入正确的jar包(如Jackson库),配置Spring MVC以支持JSON,以及在控制器中使用适当的注解。通过理解这些基础知识,开发者可以有效地在Spring MVC应用中进行JSON数据的交互...

    Spring MVC 数据转换和格式化.docx

    一旦设置好,我们就可以通过在控制器的方法上添加`@ResponseBody`注解,指示Spring MVC将方法返回的对象转换为JSON并返回给客户端。例如,如示例代码所示,当调用`getRole3`方法时,返回的`Role`对象会被自动转换为...

    SpringMVCDemo:Spring MVC 框架知识案例

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

    最全最经典spring-mvc教程

    除此之外,教程可能还会涵盖Spring MVC的RESTful API设计,如何创建JSON响应,以及使用Spring Boot快速构建Spring MVC应用。Spring Boot简化了配置,提供了预配置的依赖,使得开发者能更快地启动项目。 错误处理和...

Global site tag (gtag.js) - Google Analytics