1. 程式人生 > >【巨坑】springmvc 輸出json格式數據的幾種方式!

【巨坑】springmvc 輸出json格式數據的幾種方式!

mapping cep process 添加 exc 文件中 != style find

最近公司項目需要發布一些數據服務,從設計到實現兩天就弄完了,心中竊喜之。 結果臨近部署時突然發現。。。。。 服務輸出的JSON 數據中 date 類型數據輸出格式要麽是時間戳,要麽是 {"date":26,"day":1,"hours":21,"minutes":38,"month":5,"seconds":22,"time":1498484302259,"timezoneOffset":-480,"year":117} 這種格式。 妹的,急死我也! 感謝百度,感謝各位前輩解我之急,在家苦幹三小時總結出幾種date類數據格式轉換的方法;

前提:需要架包 jackson-annotations-2.7.4.jar ,jackson-core-2.7.4.jar, jackson-databind-2.7.4.jar

第一種:直接上配置 在springmvc 的配置文件中 註解配置改為:

<mvc:annotation-driven>
		<mvc:message-converters>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>application/json;charset=UTF-8</value>
					</list>
				</property>
			</bean>
			<!-- Json 轉換配置 -->
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
				<property name="objectMapper">  
                                      <bean class="com.fasterxml.jackson.databind.ObjectMapper">  
                                           <property name="dateFormat">  
                                               <bean class="java.text.SimpleDateFormat">  
                                                 <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />  
                                               </bean>  
                                           </property>  
                                      </bean>  
                                </property>  
				
				
				<property name="supportedMediaTypes">
					<list>
						<value>text/plain;charset=utf-8</value>
	                	                 <value>text/html;charset=utf-8</value>
	                	                <value>text/json;charset=utf-8</value>
	                	                <value>application/json;charset=utf-8</value>
					</list>
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

這種方法簡單。。太簡單了。無需其他配置,全局有效。

第二種 針對需獨立轉換的數據(部分轉換)

以上配置可以不用了,需要自定義json序列化日期數據的實現方式

//內容不多,主要為了指定轉換方式
import
java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import
com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; public class CustomDateSerializer extends JsonSerializer<Date> { @Override public void serialize(Date arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException, JsonProcessingException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //轉換格式 arg1.writeString(sdf.format(arg0)); //寫入轉換後的值 } }

好了,寫好了。現在我們只需在需要轉換的date字段上添加 註解 @JsonSerialize 即可:

@JsonSerialize(using = CustomDateSerializer.class)  //使用註解 @JsonFormat(pattern="yyyy/MM/dd HH:mm:ss",timezone = "GMT+8") 也可以
    private Date time2;

再沒有其他操作了。

第三種:也是針對全局轉換的方式,需要些一個工具類(仔細觀察和第二種很多相似的地方)

/*
+--------------------------------------------------------------------------
|   Mblog [#RELEASE_VERSION#]
|   ========================================
|   Copyright (c) 2014, 2015 mtons. All Rights Reserved
|   http://www.mtons.com
|
+---------------------------------------------------------------------------
*/
package com.dm.restWeb.config;

import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

/**
 * @author langhsu
 * 
 */
@Component
public class JsonUtils {
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    private static final ObjectMapper mapper;

    public ObjectMapper getMapper() {
        return mapper;
    }

    static {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);

        mapper = new ObjectMapper();
        mapper.setDateFormat(dateFormat);
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
            private static final long serialVersionUID = -5854941510519564900L;

            @Override
            public Object findSerializer(Annotated a) {
                if (a instanceof AnnotatedMethod) {
                    AnnotatedElement m = a.getAnnotated();
                    DateTimeFormat an = m.getAnnotation(DateTimeFormat.class);
                    if (an != null) {
                        if (!DEFAULT_DATE_FORMAT.equals(an.pattern())) {
                            return new JsonDateSerializer(an.pattern());
                        }
                    }
                }
                return super.findSerializer(a);
            }
        });
    }

    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException("轉換json字符失敗!");
        }
    }

    public <T> T toObject(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException("將json字符轉換為對象時失敗!");
        }
    }

    public static class JsonDateSerializer extends JsonSerializer<Date> {
        private SimpleDateFormat dateFormat;

        public JsonDateSerializer(String format) {
            dateFormat = new SimpleDateFormat(format);
        }

        @Override
        public void serialize(Date date, JsonGenerator gen,
                SerializerProvider provider) throws IOException,
                JsonProcessingException {
            String value = dateFormat.format(date);
            gen.writeString(value);
        }
    }
}

其實就是用靜態方法來實現獲取 ObjectMapper 對象;

還需要在springmvc 配置文件中寫入配置:

<mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <!-- Json -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" value="#{jsonUtils.mapper}"/> <!-- 和第一種方法配置模式一樣 -->
               
                
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=utf-8</value>
                        <value>text/html;charset=utf-8</value>
                        <value>text/json;charset=utf-8</value>
                        <value>application/json;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

你會發現第三種方法和第一種方法是差不多的 , 但是第三種方法支持 使用 @JsonFormat 註解來實現指定日期格式特定輸出。

所以從代碼實現看來 第三種方式功能最全面,第一種方式配置最簡便 ,第二種配置方式不推薦。

  

【巨坑】springmvc 輸出json格式數據的幾種方式!