- 浏览: 160915 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
semmy:
赞一个
displaytag的Excel导出实践 -
李君寻:
...
displaytag的Excel导出实践 -
xiaoz170:
不太明白为嘛包这一层 class ,反而使代码更复杂。难道是为 ...
试读《基于MVC的JavaScript Web富应用开发》— 不一样的JavaScript -
lingceng:
<mirror> <id>U ...
maven usage guide
背景
应用切面做日志记录,记录操作实体详情时可以使用JSON格式,这里是我使用Gson包做切面日志的一些实践,总结了遇到的问题。
软件包和学习方法
这里使用google的Gson包做JSON转换,这里是项目的地址,可以查看上面的API和User Guide。务必将源码和API配置好,文档中的记录不是很完善,很多时候需要查看源码。
注意,我使用的是2.2版,因为较早的1.4版本的FieldAttributes类中没有getDeclaringClass()这个方法,这个方法是获取field所属的类,在我的排除策略中会用到。
排除策略
最简单的gson转换可以是这样的,但却没有多少实际的作用。切面日志时,一个实体和其他实体存在关联,这时候就需要通过自定义排除策略决定如何转换关联对象,否则可能出现“爆炸式”的json字符串。
下面是我定义的一个排除策略的类,能基本满足需求,从内网搬过来的,未测试
使用的时候是这样的
HibernateProxy异常处理
在使用Hibernate时,那么很可能遇到这样的错误:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
因为gson在转换时是使用的反射机制,当获取的实体对象还在hibernate代理的时候,例如刚通过Id获取到,这时候获取到的便是代理对象HibernateProxy。这和直接调用实体对象的get方法不同,获取对象的属性就不能起作用。
解决的方法便是将代理对象实例化,见下面的代码
使用的时候将该TypeAdapter的Factory注册到GsonBuilder,上面的代码变为
Javascript格式化
默认情况下,在页面上显示json字符串时是连在一起的,格式化一下可以便于阅读:
这里要注意的是IE8在转换的时候会出现问题,所以需要引入json.js,将里面的JSON换为JSON2来使用,这时候代码便是这样的
应用切面做日志记录,记录操作实体详情时可以使用JSON格式,这里是我使用Gson包做切面日志的一些实践,总结了遇到的问题。
软件包和学习方法
这里使用google的Gson包做JSON转换,这里是项目的地址,可以查看上面的API和User Guide。务必将源码和API配置好,文档中的记录不是很完善,很多时候需要查看源码。
注意,我使用的是2.2版,因为较早的1.4版本的FieldAttributes类中没有getDeclaringClass()这个方法,这个方法是获取field所属的类,在我的排除策略中会用到。
排除策略
最简单的gson转换可以是这样的,但却没有多少实际的作用。切面日志时,一个实体和其他实体存在关联,这时候就需要通过自定义排除策略决定如何转换关联对象,否则可能出现“爆炸式”的json字符串。
Gson gson = new Gson(); int[] ints = {1, 2, 3, 4, 5}; String[] strings = {"abc", "def", "ghi"}; // Serialization gson.toJson(ints); ==> prints [1,2,3,4,5] gson.toJson(strings); ==> prints ["abc", "def", "ghi"]
下面是我定义的一个排除策略的类,能基本满足需求,从内网搬过来的,未测试
package com.lingceng.magic.logutil; import org.apache.commons.lang.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; public class TargetStrategy implements ExclusionStrategy { private static Logger log = LoggerFactory.getLogger(TargetStrategy.class); private Class<?> target; private String[] fields; private Class<?>[] clazz; private boolean reverse; public TargetStrategy(Class<?> target) { super(); this.target = target; } @Override public boolean shouldSkipClass(Class<?> class1) { return false; } @Override public boolean shouldSkipField(FieldAttributes fieldattributes) { Class<?> owner = fieldattributes.getDeclaringClass(); Class<?> c = fieldattributes.getDeclaredClass(); String f = fieldattributes.getName(); boolean isSkip = false; if (owner == target) { if (ArrayUtils.contains(fields, f)) { log.debug("fitler field:{} for class:{}", f, owner); isSkip = true; } if (ArrayUtils.contains(clazz, c)) { log.debug("fitler class:{} for class:{}", c, owner); isSkip = true; } if (reverse) { isSkip = !isSkip; } } return isSkip; } public void setFields(String[] fields) { this.fields = fields; } public void setClazz(Class<?>[] clazz) { this.clazz = clazz; } public void setReverse(boolean reverse) { this.reverse = reverse; } }
使用的时候是这样的
TargetStrategy ts = new TargetStrategy(Student.class); //这里是仅转换Student中的id和name属性 ts.setFields(new String[] {"id", "name"}); ts.setReverse(true); Gson gson = new GsonBuilder().setExcludeStrategy(ts).create(); gson.toJson(teacher);
HibernateProxy异常处理
在使用Hibernate时,那么很可能遇到这样的错误:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
因为gson在转换时是使用的反射机制,当获取的实体对象还在hibernate代理的时候,例如刚通过Id获取到,这时候获取到的便是代理对象HibernateProxy。这和直接调用实体对象的get方法不同,获取对象的属性就不能起作用。
解决的方法便是将代理对象实例化,见下面的代码
/** * This TypeAdapter unproxies Hibernate proxied objects, and serializes them * through the registered (or default) TypeAdapter of the base class. */ public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> { public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { @Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null); } }; private final Gson context; private HibernateProxyTypeAdapter(Gson context) { this.context = context; } @Override public HibernateProxy read(JsonReader in) throws IOException { throw new UnsupportedOperationException("Not supported"); } @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void write(JsonWriter out, HibernateProxy value) throws IOException { if (value == null) { out.nullValue(); return; } // Retrieve the original (not proxy) class Class<?> baseType = Hibernate.getClass(value); // Get the TypeAdapter of the original class, to delegate the serialization TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); // Get a filled instance of the original class Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer() .getImplementation(); // Serialize the value delegate.write(out, unproxiedValue); } }
使用的时候将该TypeAdapter的Factory注册到GsonBuilder,上面的代码变为
Gson gson = new GsonBuilder().setExcludeStrategy(ts) .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) .create(); gson.toJson(teacher);
Javascript格式化
默认情况下,在页面上显示json字符串时是连在一起的,格式化一下可以便于阅读:
// get text for textarea, do not use text() var msg= $("#jsonText").val(); // parse json msg = JSON.parse(msg); // return format string msg = JSON.stringify(msg, null, 4);
这里要注意的是IE8在转换的时候会出现问题,所以需要引入json.js,将里面的JSON换为JSON2来使用,这时候代码便是这样的
// get text for textarea, do not use text() var msg= $("#jsonText").val(); // parse json msg = JSON2.parse(msg); // return format string msg = JSON2.stringify(msg, null, 4);
发表评论
-
Hack struts2 json plugin: dynamically set includeProperty
2013-07-26 11:27 1295Here is not basic use of stru ... -
CoffeeScript notes: write less do more
2013-07-26 10:36 1062The Little Book on CoffeeScript ... -
JS中Date与字符串的转换
2013-07-22 10:23 3212string to date /** * parse ... -
简单使用highstock
2013-07-22 10:16 8731引用 Highstock lets you create ... -
jquery.column.picker
2013-07-09 11:20 925jquery.column.picker是基于jquery的表 ... -
使用jslint与qunit保障JS代码质量
2013-07-09 11:16 979使用jslint进行语法和风格的检查,可以预防错误。 ... -
Calender to Date snip
2013-05-30 10:25 944The format is not stored in the ... -
jQuery几个实用的方法
2013-05-18 15:49 743有段时间没有碰jQuery,回来继续用的时候,发现几个方法很有 ... -
Vim find & replace
2013-04-10 17:59 1173Vim find & replace (RT) To ... -
displaytag的Excel导出实践
2013-03-01 18:00 6129前言 Displaytag官网有1.0, 1.1, 1.2 ... -
Disable Element In HTML
2013-02-25 11:43 1294disabled attribute This Boole ... -
hibernate criteria can't cast to type
2013-01-23 11:54 1086描述 criteria动态查询中,先使用setProje ... -
requirejs处理前端JS依赖
2013-01-23 11:39 8227简介: Requrejs遵循AMD ... -
vim fast move tip
2013-01-23 11:03 871search: * to search current ... -
读《深入分析Java Web技术内幕》
2013-01-16 21:37 3345这里这本书的预读章节,看完预读部分,解答了一些疑惑 ... -
Vim good Tip
2013-01-07 00:35 0Most time is spent reading, ... -
Prevent IE crash console.log
2012-12-05 15:24 953origin When the console is cl ... -
Javascript对象封装的三种简单写法
2012-11-11 18:43 976这里的内容没有太多深入的东西,更深的理解请看秘 密花 ... -
Java泛型
2012-11-08 23:57 1622Java的泛型是5.0的特性,自己的业务代码中或许较少使用 ... -
lucene全文索引
2012-11-08 01:45 1512总听说lucene,总听到“全文检索”,一直不大明白什么意 ...
相关推荐
AOP则用于实现日志记录、权限验证等跨切面的功能。 2. **SpringMVC**:作为Spring的Web模块,SpringMVC处理HTTP请求并返回响应。它包括前端控制器DispatcherServlet、处理器映射器HandlerMapping、处理器适配器...
2. **面向切面编程(Aspect-Oriented Programming, AOP)**:Spring的AOP模块允许开发者定义“切面”,将关注点如日志、事务管理等与业务逻辑分离。这提供了更好的代码组织和模块化。 3. **数据访问集成(Data ...
Spring框架是Java开发中最常用的轻量级开源框架之一,它为开发者提供了强大的依赖注入(Dependency Injection,DI)、面向切面编程(Aspect Oriented Programming,AOP)以及事务管理等功能,极大地提高了开发效率和...
- AOP(面向切面编程):Spring提供切面编程能力,允许我们定义横切关注点,如日志、事务管理等。 - JDBC模板和数据源管理:Spring简化了数据库操作,通过JdbcTemplate和DataSource进行数据访问。 - MVC(模型-...
Spring的AOP(面向切面编程)模块可以用来实现日志记录、安全控制等跨切面关注点。 2. **SpringMVC**:作为Spring的一部分,SpringMVC是一个用于构建Web应用的Model-View-Controller(MVC)框架。它负责接收HTTP...
6. **spring-aop.jar**:实现 AOP 面向切面编程的库,允许定义横切关注点,如日志、事务管理等,并将其模块化。 7. **spring-aspects.jar**:提供了与特定编程语言(如 AspectJ)集成的 AOP 支持。 8. **jstl.jar*...
8. **Spring框架**:作为Java后端开发的主流框架,Spring可以简化项目开发,提供依赖注入、AOP(面向切面编程)等功能,可能被用在健康打卡服务的实现中。 9. **数据库操作**:如果项目需要存储用户信息或打卡记录...
其次,Spring的AOP(面向切面编程)允许开发者定义横切关注点,如日志、事务管理等,从而将这些通用功能与业务逻辑分离,提高代码复用。书中有专门章节讲述如何创建和使用自定义切面,以及如何结合Spring的事务管理...
首先,Spring是一个开源的应用框架,它提供了对Java EE的全面控制,包括依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented Programming,AOP)以及事务管理等核心功能。在SSM项目中,Spring作为...
总之,SSH整合涉及多个层面的技术,包括MVC设计模式、依赖注入、面向切面编程、对象关系映射等,而jar包的正确选用和管理是实现这一整合的基础。通过深入学习和实践,开发者可以充分利用SSH框架的强大功能,构建高效...
Spring 是一个广泛使用的 Java 应用框架,它提供了丰富的功能,包括依赖注入、AOP(面向切面编程)以及对各种数据访问技术的支持。 在深入解析源码之前,我们需要了解 JSON 和 Spring 的基本概念。JSON 是一种轻量...
7. Spring Framework: 一个全面的后端开发框架,包括依赖注入、AOP(面向切面编程)、数据库访问等组件。Spring Boot简化了Spring的配置,使得快速开发变得更加容易。 8. Hibernate: ORM(对象关系映射)框架,允许...
Spring的核心特性包括依赖注入(DI),面向切面编程(AOP),以及各种容器和工具支持,这些都极大地提高了代码的可测试性和模块化程度。 Spring MVC是Spring框架的一部分,专门用于处理Web请求。它为开发者提供了...
这些框架提供了快速开发、依赖注入和AOP(面向切面编程)等功能,简化了项目结构,提高了开发效率。 2. **数据库设计**:系统通常会使用MySQL、Oracle或PostgreSQL等关系型数据库存储用户信息、医生资料、预约记录...
4. MVC框架:如Spring MVC,提供一套完整的MVC解决方案,包含依赖注入、AOP(面向切面编程)等功能。 5. JSON处理:使用Jackson或Gson库进行JSON数据的序列化和反序列化,便于前后端数据交换。 6. 安全管理:Spring ...
1. **Spring框架**:Spring是Java开发中的核心框架,它提供了依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)的能力。Spring的IoC容器管理着应用对象的生命周期和配置,而...
而面向切面编程则提供了一种模块化代码的方式,使得业务逻辑与系统服务如日志、事务管理等可以分离。 2. **Spring MVC**:作为Spring框架的一部分,Spring MVC用于构建Web应用程序。它采用模型-视图-控制器(MVC)...
1. **Spring Framework**:这是一个全面的企业级应用开发框架,提供了依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等特性,是Java后端开发的基石。 2. **Hibernate**:作为一款流行的ORM(对象关系映射...
在这个用户模块中,Spring可能被用来管理Bean,实现依赖注入,以及提供AOP(面向切面编程)来处理如日志、事务管理等功能。 3. **Spring Security**:对于用户身份验证和授权,Spring Security是一个强大的工具。它...
Spring是一个广泛使用的Java企业级应用框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,极大地简化了Java应用的开发。 描述中提到的“BbsSpringDemo”可能是一个论坛系统的示例项目,它使用Spring框架...