struts2 json 定义全局Date格式
使用struts2的json插件时,自己定义日期格式经常使用的方式是在get属性上加入@JSON注解,这个对于少量Date属性还能够,可是假设date字段多了,总不可能去给每一个date get方法加入json注解吧!
发现极大不便后查看了sturts-plugin.xml 中的json-default定义,源代码跟踪到json拦截器内部一点发现都没有,自己定义
org.apache.struts2.json.JSONPopulator中的dateFormatter属性全然不起效果。可是在同一个包下:org.apache.struts2.json 发现了类:JSONWriter 在这里才找到了一些端倪
将源代码中的
- /**
- * Add date to buffer
- */
- protected void date(Date date, Method method) {
- JSON json = null;
- if (method != null)
- json = method.getAnnotation(JSON.class);
- if (this.formatter == null)
- this.formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- DateFormat formatter = (json != null) && (json.format().length() > 0) ? new SimpleDateFormat(json
- .format()) : this.formatter;
- this.string(formatter.format(date));
- }
- SimpleDateFormat 格式改成自己定义日期格式就可以,这样全局json 日期格式就自己定义完毕了!
- 注意:覆盖时仅仅须要自己定义包:org.apache.struts2.json将改动后的<span style="font-family: Arial, Helvetica, sans-serif;">JSONWriter放到包下就可以,没有必要去改动插件中的源代码信息 </span>
以下附上整个类的源代码:
- /*
- * $Id$
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.struts2.json;
- import com.opensymphony.xwork2.util.logging.Logger;
- import com.opensymphony.xwork2.util.logging.LoggerFactory;
- import org.apache.struts2.json.annotations.JSON;
- import org.apache.struts2.json.annotations.JSONFieldBridge;
- import org.apache.struts2.json.annotations.JSONParameter;
- import org.apache.struts2.json.bridge.FieldBridge;
- import org.apache.struts2.json.bridge.ParameterizedBridge;
- import java.beans.BeanInfo;
- import java.beans.IntrospectionException;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.Array;
- import java.lang.reflect.Method;
- import java.text.CharacterIterator;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- import java.text.StringCharacterIterator;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
- import java.util.regex.Pattern;
- /**
- * <p>
- * Serializes an object into JavaScript Object Notation (JSON). If cyclic
- * references are detected they will be nulled out.
- * </p>
- */
- public class JSONWriter {
- private static final Logger LOG = LoggerFactory.getLogger(JSONWriter.class);
- /**
- * By default, enums are serialised as name=value pairs
- */
- public static final boolean ENUM_AS_BEAN_DEFAULT = false;
- private static char[] hex = "0123456789ABCDEF".toCharArray();
- private static final ConcurrentMap<Class<?>, BeanInfo> BEAN_INFO_CACHE_IGNORE_HIERARCHY = new ConcurrentHashMap<Class<?>, BeanInfo>();
- private static final ConcurrentMap<Class<?>, BeanInfo> BEAN_INFO_CACHE = new ConcurrentHashMap<Class<?>, BeanInfo>();
- private StringBuilder buf = new StringBuilder();
- private Stack<Object> stack = new Stack<Object>();
- private boolean ignoreHierarchy = true;
- private Object root;
- private boolean buildExpr = true;
- private String exprStack = "";
- private Collection<Pattern> excludeProperties;
- private Collection<Pattern> includeProperties;
- private DateFormat formatter;
- private boolean enumAsBean = ENUM_AS_BEAN_DEFAULT;
- private boolean excludeNullProperties;
- /**
- * @param object Object to be serialized into JSON
- * @return JSON string for object
- * @throws JSONException
- */
- public String write(Object object) throws JSONException {
- return this.write(object, null, null, false);
- }
- /**
- * @param object Object to be serialized into JSON
- * @return JSON string for object
- * @throws JSONException
- */
- public String write(Object object, Collection<Pattern> excludeProperties,
- Collection<Pattern> includeProperties, boolean excludeNullProperties) throws JSONException {
- this.excludeNullProperties = excludeNullProperties;
- this.buf.setLength(0);
- this.root = object;
- this.exprStack = "";
- this.buildExpr = ((excludeProperties != null) && !excludeProperties.isEmpty())
- || ((includeProperties != null) && !includeProperties.isEmpty());
- this.excludeProperties = excludeProperties;
- this.includeProperties = includeProperties;
- this.value(object, null);
- return this.buf.toString();
- }
- /**
- * Detect cyclic references
- */
- protected void value(Object object, Method method) throws JSONException {
- if (object == null) {
- this.add("null");
- return;
- }
- if (this.stack.contains(object)) {
- Class clazz = object.getClass();
- // cyclic reference
- if (clazz.isPrimitive() || clazz.equals(String.class)) {
- this.process(object, method);
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Cyclic reference detected on " + object);
- }
- this.add("null");
- }
- return;
- }
- this.process(object, method);
- }
- /**
- * Serialize object into json
- */
- protected void process(Object object, Method method) throws JSONException {
- this.stack.push(object);
- if (object instanceof Class) {
- this.string(object);
- } else if (object instanceof Boolean) {
- this.bool((Boolean) object);
- } else if (object instanceof Number) {
- this.add(object);
- } else if (object instanceof String) {
- this.string(object);
- } else if (object instanceof Character) {
- this.string(object);
- } else if (object instanceof Map) {
- this.map((Map) object, method);
- } else if (object.getClass().isArray()) {
- this.array(object, method);
- } else if (object instanceof Iterable) {
- this.array(((Iterable) object).iterator(), method);
- } else if (object instanceof Date) {
- this.date((Date) object, method);
- } else if (object instanceof Calendar) {
- this.date(((Calendar) object).getTime(), method);
- } else if (object instanceof Locale) {
- this.string(object);
- } else if (object instanceof Enum) {
- this.enumeration((Enum) object);
- } else {
- processCustom(object, method);
- }
- this.stack.pop();
- }
- /**
- * Serialize custom object into json
- */
- protected void processCustom(Object object, Method method) throws JSONException {
- this.bean(object);
- }
- /**
- * Instrospect bean and serialize its properties
- */
- protected void bean(Object object) throws JSONException {
- this.add("{");
- BeanInfo info;
- try {
- Class clazz = object.getClass();
- info = ((object == this.root) && this.ignoreHierarchy)
- ? getBeanInfoIgnoreHierarchy(clazz)
- : getBeanInfo(clazz);
- PropertyDescriptor[] props = info.getPropertyDescriptors();
- boolean hasData = false;
- for (PropertyDescriptor prop : props) {
- String name = prop.getName();
- Method accessor = prop.getReadMethod();
- Method baseAccessor = findBaseAccessor(clazz, accessor);
- if (baseAccessor != null) {
- if (baseAccessor.isAnnotationPresent(JSON.class)) {
- JSONAnnotationFinder jsonFinder = new JSONAnnotationFinder(baseAccessor).invoke();
- if (!jsonFinder.shouldSerialize()) continue;
- if (jsonFinder.getName() != null) {
- name = jsonFinder.getName();
- }
- }
- // ignore "class" and others
- if (this.shouldExcludeProperty(prop)) {
- continue;
- }
- String expr = null;
- if (this.buildExpr) {
- expr = this.expandExpr(name);
- if (this.shouldExcludeProperty(expr)) {
- continue;
- }
- expr = this.setExprStack(expr);
- }
- Object value = accessor.invoke(object);
- if (baseAccessor.isAnnotationPresent(JSONFieldBridge.class)) {
- value = getBridgedValue(baseAccessor, value);
- }
- boolean propertyPrinted = this.add(name, value, accessor, hasData);
- hasData = hasData || propertyPrinted;
- if (this.buildExpr) {
- this.setExprStack(expr);
- }
- }
- }
- // special-case handling for an Enumeration - include the name() as
- // a property */
- if (object instanceof Enum) {
- Object value = ((Enum) object).name();
- this.add("_name", value, object.getClass().getMethod("name"), hasData);
- }
- } catch (Exception e) {
- throw new JSONException(e);
- }
- this.add("}");
- }
- protected BeanInfo getBeanInfoIgnoreHierarchy(final Class<?> clazz) throws IntrospectionException {
- BeanInfo beanInfo = BEAN_INFO_CACHE_IGNORE_HIERARCHY.get(clazz);
- if (beanInfo != null) {
- return beanInfo;
- }
- beanInfo = Introspector.getBeanInfo(clazz, clazz.getSuperclass());
- BEAN_INFO_CACHE_IGNORE_HIERARCHY.put(clazz, beanInfo);
- return beanInfo;
- }
- protected BeanInfo getBeanInfo(final Class<?> clazz) throws IntrospectionException {
- BeanInfo beanInfo = BEAN_INFO_CACHE.get(clazz);
- if (beanInfo != null) {
- return beanInfo;
- }
- beanInfo = Introspector.getBeanInfo(clazz);
- BEAN_INFO_CACHE.put(clazz, beanInfo);
- return beanInfo;
- }
- protected Object getBridgedValue(Method baseAccessor, Object value) throws InstantiationException, IllegalAccessException {
- JSONFieldBridge fieldBridgeAnn = baseAccessor.getAnnotation(JSONFieldBridge.class);
- if (fieldBridgeAnn != null) {
- Class impl = fieldBridgeAnn.impl();
- FieldBridge instance = (FieldBridge) impl.newInstance();
- if (fieldBridgeAnn.params().length > 0 && ParameterizedBridge.class.isAssignableFrom(impl)) {
- Map<String, String> params = new HashMap<String, String>(fieldBridgeAnn.params().length);
- for (JSONParameter param : fieldBridgeAnn.params()) {
- params.put(param.name(), param.value());
- }
- ((ParameterizedBridge) instance).setParameterValues(params);
- }
- value = instance.objectToString(value);
- }
- return value;
- }
- protected Method findBaseAccessor(Class clazz, Method accessor) {
- Method baseAccessor = null;
- if (clazz.getName().contains("$$EnhancerByCGLIB$$")) {
- try {
- baseAccessor = Thread.currentThread().getContextClassLoader().loadClass(
- clazz.getName().substring(0, clazz.getName().indexOf("$$"))).getMethod(
- accessor.getName(), accessor.getParameterTypes());
- } catch (Exception ex) {
- LOG.debug(ex.getMessage(), ex);
- }
- } else if (clazz.getName().contains("$$_javassist")) {
- try {
- baseAccessor = Class.forName(
- clazz.getName().substring(0, clazz.getName().indexOf("_$$")))
- .getMethod(accessor.getName(), accessor.getParameterTypes());
- } catch (Exception ex) {
- LOG.debug(ex.getMessage(), ex);
- }
- } else {
- return accessor;
- }
- return baseAccessor;
- }
- /**
- * Instrospect an Enum and serialize it as a name/value pair or as a bean
- * including all its own properties
- */
- protected void enumeration(Enum enumeration) throws JSONException {
- if (enumAsBean) {
- this.bean(enumeration);
- } else {
- this.string(enumeration.name());
- }
- }
- protected boolean shouldExcludeProperty(PropertyDescriptor prop) throws SecurityException, NoSuchFieldException {
- String name = prop.getName();
- return name.equals("class")
- || name.equals("declaringClass")
- || name.equals("cachedSuperClass")
- || name.equals("metaClass");
- }
- protected String expandExpr(int i) {
- return this.exprStack + "[" + i + "]";
- }
- protected String expandExpr(String property) {
- if (this.exprStack.length() == 0) {
- return property;
- }
- return this.exprStack + "." + property;
- }
- protected String setExprStack(String expr) {
- String s = this.exprStack;
- this.exprStack = expr;
- return s;
- }
- protected boolean shouldExcludeProperty(String expr) {
- if (this.excludeProperties != null) {
- for (Pattern pattern : this.excludeProperties) {
- if (pattern.matcher(expr).matches()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Ignoring property because of exclude rule: " + expr);
- }
- return true;
- }
- }
- }
- if (this.includeProperties != null) {
- for (Pattern pattern : this.includeProperties) {
- if (pattern.matcher(expr).matches()) {
- return false;
- }
- }
- if (LOG.isDebugEnabled()){
- LOG.debug("Ignoring property because of include rule: " + expr);
- }
- return true;
- }
- return false;
- }
- /**
- * Add name/value pair to buffer
- */
- protected boolean add(String name, Object value, Method method, boolean hasData) throws JSONException {
- if (excludeNullProperties && value == null) {
- return false;
- }
- if (hasData) {
- this.add(',');
- }
- this.add('"');
- this.add(name);
- this.add("\":");
- this.value(value, method);
- return true;
- }
- /**
- * Add map to buffer
- */
- protected void map(Map map, Method method) throws JSONException {
- this.add("{");
- Iterator it = map.entrySet().iterator();
- boolean warnedNonString = false; // one report per map
- boolean hasData = false;
- while (it.hasNext()) {
- Map.Entry entry = (Map.Entry) it.next();
- if (excludeNullProperties && entry.getValue() == null) {
- continue;
- }
- Object key = entry.getKey();
- if (key == null) {
- LOG.error("Cannot build expression for null key in #0", exprStack);
- continue;
- }
- String expr = null;
- if (this.buildExpr) {
- expr = this.expandExpr(key.toString());
- if (this.shouldExcludeProperty(expr)) {
- continue;
- }
- expr = this.setExprStack(expr);
- }
- if (hasData) {
- this.add(',');
- }
- hasData = true;
- if (!warnedNonString && !(key instanceof String)) {
- if (LOG.isWarnEnabled()) {
- LOG.warn("JavaScript doesn't support non-String keys, using toString() on #0", key.getClass().getName());
- }
- warnedNonString = true;
- }
- this.value(key.toString(), method);
- this.add(":");
- this.value(entry.getValue(), method);
- if (this.buildExpr) {
- this.setExprStack(expr);
- }
- }
- this.add("}");
- }
- /**
- * Add date to buffer
- */
- protected void date(Date date, Method method) {
- JSON json = null;
- if (method != null)
- json = method.getAnnotation(JSON.class);
- if (this.formatter == null)
- this.formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- DateFormat formatter = (json != null) && (json.format().length() > 0) ? new SimpleDateFormat(json
- .format()) : this.formatter;
- this.string(formatter.format(date));
- }
- /**
- * Add array to buffer
- */
- protected void array(Iterator it, Method method) throws JSONException {
- this.add("[");
- boolean hasData = false;
- for (int i = 0; it.hasNext(); i++) {
- String expr = null;
- if (this.buildExpr) {
- expr = this.expandExpr(i);
- if (this.shouldExcludeProperty(expr)) {
- it.next();
- continue;
- }
- expr = this.setExprStack(expr);
- }
- if (hasData) {
- this.add(',');
- }
- hasData = true;
- this.value(it.next(), method);
- if (this.buildExpr) {
- this.setExprStack(expr);
- }
- }
- this.add("]");
- }
- /**
- * Add array to buffer
- */
- protected void array(Object object, Method method) throws JSONException {
- this.add("[");
- int length = Array.getLength(object);
- boolean hasData = false;
- for (int i = 0; i < length; ++i) {
- String expr = null;
- if (this.buildExpr) {
- expr = this.expandExpr(i);
- if (this.shouldExcludeProperty(expr)) {
- continue;
- }
- expr = this.setExprStack(expr);
- }
- if (hasData) {
- this.add(',');
- }
- hasData = true;
- this.value(Array.get(object, i), method);
- if (this.buildExpr) {
- this.setExprStack(expr);
- }
- }
- this.add("]");
- }
- /**
- * Add boolean to buffer
- */
- protected void bool(boolean b) {
- this.add(b ? "true" : "false");
- }
- /**
- * escape characters
- */
- protected void string(Object obj) {
- this.add('"');
- CharacterIterator it = new StringCharacterIterator(obj.toString());
- for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
- if (c == '"') {
- this.add("\\\"");
- } else if (c == '\\') {
- this.add("\\\\");
- } else if (c == '/') {
- this.add("\\/");
- } else if (c == '\b') {
- this.add("\\b");
- } else if (c == '\f') {
- this.add("\\f");
- } else if (c == '\n') {
- this.add("\\n");
- } else if (c == '\r') {
- this.add("\\r");
- } else if (c == '\t') {
- this.add("\\t");
- } else if (Character.isISOControl(c)) {
- this.unicode(c);
- } else {
- this.add(c);
- }
- }
- this.add('"');
- }
- /**
- * Add object to buffer
- */
- protected void add(Object obj) {
- this.buf.append(obj);
- }
- /**
- * Add char to buffer
- */
- protected void add(char c) {
- this.buf.append(c);
- }
- /**
- * Represent as unicode
- *
- * @param c character to be encoded
- */
- protected void unicode(char c) {
- this.add("\\u");
- int n = c;
- for (int i = 0; i < 4; ++i) {
- int digit = (n & 0xf000) >> 12;
- this.add(hex[digit]);
- n <<= 4;
- }
- }
- public void setIgnoreHierarchy(boolean ignoreHierarchy) {
- this.ignoreHierarchy = ignoreHierarchy;
- }
- /**
- * If true, an Enum is serialized as a bean with a special property
- * _name=name() as all as all other properties defined within the enum.<br/>
- * If false, an Enum is serialized as a name=value pair (name=name())
- *
- * @param enumAsBean true to serialize an enum as a bean instead of as a name=value
- * pair (default=false)
- */
- public void setEnumAsBean(boolean enumAsBean) {
- this.enumAsBean = enumAsBean;
- }
- protected static class JSONAnnotationFinder {
- private boolean serialize = true;
- private Method accessor;
- private String name;
- public JSONAnnotationFinder(Method accessor) {
- this.accessor = accessor;
- }
- public boolean shouldSerialize() {
- return serialize;
- }
- public String getName() {
- return name;
- }
- public JSONAnnotationFinder invoke() {
- JSON json = accessor.getAnnotation(JSON.class);
- serialize = json.serialize();
- if (serialize && json.name().length() > 0) {
- name = json.name();
- }
- return this;
- }
- }
- }
struts2 json 定义全局Date格式的更多相关文章
- vue定义全局date过滤器(自定义JS文件模块和Moment.js库)
自定义dateFormat.js文件模块 dateFormat.js /** * 时间字符串 转 时间戳 * @param {String} time_str 时间字符串(格式"2014-0 ...
- 字定义JSON序列化支持datetime格式序列化
字定义JSON序列化支持datetime格式序列化 由于json.dumps无法处理datetime日期,所以可以通过自定义处理器来做扩展,如: import json from datetime i ...
- struts2 json 输出日期格式不正确
struts2 输出json中 日期出现:2013-12-17T15:57:47 错误格式的数据 原因:struts2 json插件对日期的格式化有问题 解决方法:在实体类的日期的get方法上加注解: ...
- webapi返回json格式,并定义日期解析格式
1.webapi返回json格式 var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferen ...
- struts2异常处理,global-results定义全局结果处理
<global-results>定义全局结果处理 一般发生异常之后 结果返回errHandler 因为errHandler是由<global-exception-mappings&g ...
- 使用 JSON.parse 反序列化 ISO 格式的日期字符串, 将返回Date格式对象
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 解决nodejs中json序列化时Date类型默认为UTC格式
在nodejs中,json序列化时Date类型时,默认转为UTC格式. 如下图 上面只是一个例子,下面我用一个更具体化的例子来展示一个这个情况,我们在开发WEB项目中,经常用到Express组件, 我 ...
- 解决nodejs中json序列化时Date类型为UTC格式
在nodejs中,json序列化时Date类型时,默认转为UTC格式. 如下图 zhupengfei@DESKTOP-HJASOE3 MINGW64 /d/MyProject/exp2 $ node ...
- Struts2中防止表单重复提交,global-results定义全局结果处理
1.在表单中加入<s:token/>标签 2.在动作类中加入token的拦截器 <!--如果单单写 name="token" 会丧失 defaultStack 拦 ...
随机推荐
- UI图标不用愁:矢量字体图标Font-Awesome
Font-Awesome,这个项目主要是css3的一个应用,准确的说是一段css,这里的把很多图标的东西做到了font文件里面,然后通过引用外部font文件的方式,来展现图标. Font Awesom ...
- LightOj_1079 Just another Robbery
题目链接 题意: 抢银行(这个背景最爱了), 有n家银行, 每家银行抢劫被抓的概率是p[i],你认为当你被抓的概率低于P的时候是安全的. 问, 你最多能抢劫到多少money. 思路: 抽象成背包问题, ...
- ExtJS中动态设置TextField的readOnly属性
第一种方式: textField, 如果知道textField的id = 'textField' 话,就可以利用如下的方法: 则代码如下:Ext.getCmp("textField" ...
- 通过CTAPI和Citect SCADA软件进行数据通讯
官方文档 Citect SCADA 7.20 Technical Reference 参考文献 基于Citect远程控制的变流量堆料控制系统 [王玉增,顾英妮,王维 济南大学,机械工程学院 ,Cite ...
- 区分html与css中的属性
CSS中id与Class的区别 1.在CSS文件里书写时,ID加前缀"#":CLASS用"." 2.id一个页面只可以使用一次:class可以多次引用. 3.I ...
- hadoop的一些重要配置参数
hadoop集群管理内存设置 Mapreduce内存使用设置 hadoop job重要性能参数
- Shoot the Bullet
zoj3229:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题意:一个摄影师,在n天内给m个女神拍照.每个女神至少要 ...
- Javascript禁止网页复制粘贴效果,或者复制时自动添加来源信息
一.禁止复制 使用方法:在oncopy事件中return false oncopy="return false;" 1.禁止复制网页内容 <body oncopy=" ...
- JqueryUI 为什么TypeError: $(...).slides is not a function
单独写一个html发现一切没有问题,但放在自己的网页中作为一部分却出现了问题,最后发现是那些js文件引入顺序出现了问题,
- LeetCode解题报告:LRU Cache
LRU Cache Design and implement a data structure for Least Recently Used (LRU) cache. It should suppo ...