REST标准,支持多终端。resteasy + spring + spring security + spring aop + hibernate + c# + jquery mobile
2013-11-08 14:50
381 查看
【需求】
1. 完全前后台,多终端分离式开发,互补影响进度。开发中在本地自建JSON文本测试即可,无需依赖服务端。完全解耦。
2. 本着 客户需求易变,前端应快速搭建不同形式,终端。
3. Java服务端一个服务多终端享用,兼容性强。
4. 大量使用 泛型,反射,重载,重写。
泛型:为了规范程序员使用方式,但不脱离根本。
反射:减少大量重复性工作。
重载、重写:对原有通用型CRUD做进一步扩展,强化验证等。
【架构】
服务端:resteasy + spring + spring security + spring aop + hibernate
windows:C# Winform
手 机:Html5 + jquery mobile + mobiscroll
其 它:Html (略)
传输格式 :"application/json;charset=UTF-8"
C# 端架构跳转:C#Winform客户端
Html5 + jquery mobile + mobiscroll跳转:
spring security:点击打开链接
【测试工具】
FireFox RESTClient
![](http://img.blog.csdn.net/20131108145732875?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTI4NjM1MjI1MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
【JAVA服务端架构】
CURD复用框架,主要使用Java泛型、反射、方法重载。
主要解决问题:
减少重复代码工作量。
符合接口隔离原则,每一个接口对应一种角色。
规范接口类型。
类型自动转换,不需要而外强制类型转换。
重点讲述:Crudable-源码说明,模糊查询方法实现。
因模糊查询方法,包含潜在的规则,设计后台、前台页面使用者的关系。
案例【BaseService 使用】
1. 自定义Restful接口继承BaseService<T extends BaseEntity>(即定义基础CRUD接口)
2. 泛型BaseService<T>为必填项,必须为BaseEntity子类(因后台自动转换类型,避免强制类型转换)
3. 使用Restful注解,配置@Path、@Producess,保证访问路径唯一性。
4. Restful实现继承BaseServiceImpl<T extends BaseEntity>,即实现基础CRUD方法
5. 泛型BaseServiceImpl<T>为必填项,必须为BaseEntity子类(因后台自动转换类型,ORM映射等)
【BaseService 源码】
1. BaseService 提供复用 增删改查 方法,减少程序员工作。
2. BaseServiceImpl 构造方法中 获取 子类泛型,实现基础增删改查。
3. 增删改查 代码比较单一(略)
4. 重点讲解 findEntitiesInPageByProperties
1. 完全前后台,多终端分离式开发,互补影响进度。开发中在本地自建JSON文本测试即可,无需依赖服务端。完全解耦。
2. 本着 客户需求易变,前端应快速搭建不同形式,终端。
3. Java服务端一个服务多终端享用,兼容性强。
4. 大量使用 泛型,反射,重载,重写。
泛型:为了规范程序员使用方式,但不脱离根本。
反射:减少大量重复性工作。
重载、重写:对原有通用型CRUD做进一步扩展,强化验证等。
【架构】
服务端:resteasy + spring + spring security + spring aop + hibernate
windows:C# Winform
手 机:Html5 + jquery mobile + mobiscroll
其 它:Html (略)
传输格式 :"application/json;charset=UTF-8"
C# 端架构跳转:C#Winform客户端
Html5 + jquery mobile + mobiscroll跳转:
spring security:点击打开链接
【测试工具】
FireFox RESTClient
【JAVA服务端架构】
CURD复用框架,主要使用Java泛型、反射、方法重载。
主要解决问题:
减少重复代码工作量。
符合接口隔离原则,每一个接口对应一种角色。
规范接口类型。
类型自动转换,不需要而外强制类型转换。
重点讲述:Crudable-源码说明,模糊查询方法实现。
因模糊查询方法,包含潜在的规则,设计后台、前台页面使用者的关系。
案例【BaseService 使用】
1. 自定义Restful接口继承BaseService<T extends BaseEntity>(即定义基础CRUD接口)
2. 泛型BaseService<T>为必填项,必须为BaseEntity子类(因后台自动转换类型,避免强制类型转换)
3. 使用Restful注解,配置@Path、@Producess,保证访问路径唯一性。
4. Restful实现继承BaseServiceImpl<T extends BaseEntity>,即实现基础CRUD方法
5. 泛型BaseServiceImpl<T>为必填项,必须为BaseEntity子类(因后台自动转换类型,ORM映射等)
package com.xiazhi.basemanger.service; import javax.ws.rs.Path; import com.xiazhi.basemanger.entity.AclResources; import com.xiazhi.common.service.BaseService; @Path("/basemanager/aclresources/") public interface AclResourcesService extends BaseService<AclResources> { }
package com.xiazhi.basemanger.service.impl; import org.springframework.stereotype.Repository; import com.xiazhi.basemanger.entity.AclResources; import com.xiazhi.basemanger.service.AclResourcesService; import com.xiazhi.common.service.impl.BaseServiceImpl; @Repository("aclResourcesService") public class AclResourcesServiceImpl extends BaseServiceImpl<AclResources> implements AclResourcesService { }
【BaseService 源码】
1. BaseService 提供复用 增删改查 方法,减少程序员工作。
2. BaseServiceImpl 构造方法中 获取 子类泛型,实现基础增删改查。
3. 增删改查 代码比较单一(略)
4. 重点讲解 findEntitiesInPageByProperties
“属性名_类型(Int、String等)_值_比较模式(EQ、LIKE等)_联合模式(AND/OR)” “orderNo_S_NO201301240001_LIKE_”,订单单号_字符串类型_值_模糊查询_and联合,sql:orderNo like ’% NO201301240001%’ and “productInto.pn_S_iphone5_EQ_OR”,产品属性.型号_字符串类型_值_相等查询_or联合,sql: pn=’iphone5’ or 。(productInto.pn可能是当前表列,也有可能是外键,与实体数据库结构有关) “isSet_B_True_EQ”,属性_Boolean_True_相等_and联合,sql:isSer=1 and 。(Boolean类型数据库使用Bit:0/1) 类型选项: S(String.class), I(Integer.class), L(Long.class), B(Boolean.class), C(Collection.class); 比较选项: IN, EQ, LIKE, LT, GT, LE, GE; 联合选项: AND, OR OR 复杂条件查询说明: String filterStr = ""; filterStr += "id_I_1_EQ_OR_,"; filterStr += "id_I_40_EQ__,"; filterStr += "description_S_PolicyForTest_EQ__,"; SQL效果为: where (id=1 or id=40) and description='PolicyForTest'
@Produces({ "application/json;charset=UTF-8" }) @Consumes({ "application/json;charset=UTF-8" }) public interface BaseService<T extends EntityId> { /** * 新增实体 * @param entity */ @POST @Transactional public T newEntity(T entity); /** * 更新实体 * @param entity */ @PUT @Path("{id}") @Transactional public T updateEntity(T entity); /** * 根据Id删除实体 * @param id */ @DELETE @Path("{id}") @Transactional public Integer deleteEntityById(@PathParam("id") Long id); /** * Read Operation for Single Entity * 根据Id查询实体 * @return entity */ @GET @Path("{id}") @Transactional public T getEntityById(@PathParam("id") Long id); /** * 根据查询条件查询实体 */ public T findEntityByDetachedCriteria(final DetachedCriteria detachedCriteria); /** * 根据查询条件查询实体 */ public List<T> findEntitysByDetachedCriteria(final DetachedCriteria detachedCriteria); public List<T> findEntitysByDetachedCriteria(final Class<T> entityClass, final List<PropertyFilter> filters); /** * 根据查询条件查询实体 * @param detachedCriteria 查询条件 * @param sindex 开始坐标 * @param size 多少行记录 */ public List<T> findEntitysByDetachedCriteriaLimit(final DetachedCriteria detachedCriteria, final Integer sindex, final Integer size); public List<T> findEntitysByDetachedCriteriaLimit(final Class<T> entityClass, final List<PropertyFilter> filters, final Integer sindex, final Integer size); /** * 根据条件查询记录数 * @param detachedCriteria 查询条件 * @return 记录数 */ public Integer findRowCount(final DetachedCriteria detachedCriteria); /** * 查询所有实体 */ @GET @Path("/all") @Transactional public List<T> findAllEntitys(); /** * 分页模糊查询 * * 查询条件说明:&filter= * id_L_3_EQ__, * * 属性(id) _ 类型(Long) _ 值(3) _ EQ(精确查询) _ AND(默认And查询) _ , * * 类型: * S(String.class), I(Integer.class), L(Long.class), B(Boolean.class), * C(Collection.class) 例:1,2,3,4,5。使用,间隔。 * * 匹配模式: * IN 例: select * from tableName where id in (1,2,3,4,5); * EQ, 例: select * from tableName where id = 1; * LIKE, 例: select * from tableName where name like '%张三%'; * LT, 例: select * from tableName where id < 100; * GT, 例: select * from tableName where id > 100; * LE, 例: select * from tableName where id <= 100; * GE 例: select * from tableName where id >= 100; * * * 完整案例: * select * from tableName where id = 3 and name = '张三' limit 0, 10 * http://localhost:8080/dsp/resteasy/basemanager/aclresources/inPage/?pageNumber=1&pageSize=10&orderBy=&filter=id_L_2_EQ__,name_S_资源_LIKE__& * * OR案例: * select * from tableName where (id = 3 or name = '张三') or name = '李四' limit 0, 10 * &filter=id_L_3_EQ_OR_,name_S_张三_EQ_OR_,name_S_李四_EQ_OR_ * */ @GET @Path("inPage") @Transactional public List<T> findEntitiesInPageByProperties(@QueryParam("pageNumber") Integer pageNumber, @QueryParam("pageSize") Integer pageSize, @QueryParam("orderBy") String orderBy, @QueryParam("filter") String filterStr); @GET @Path("rowCount") @Transactional public Integer findEntitiesInPageByPropertiesRowCount(@QueryParam("pageNumber") Integer pageNumber, @QueryParam("pageSize") Integer pageSize, @QueryParam("orderBy") String orderBy, @QueryParam("filter") String filterStr); }
public class BaseServiceImpl<T extends EntityId> implements BaseService<T> { private Class<T> entityClass = null; @SuppressWarnings("unchecked") public BaseServiceImpl() { super(); if (this.getClass().getGenericSuperclass() instanceof ParameterizedType) { this.entityClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } } @Resource(name = "baseDao") private BaseDao<T> baseDao; public T newEntity(T entity) { baseDao.addEntity(entity); return entity; } public T updateEntity(T entity) { baseDao.updateEntity(entity); return entity; } public Integer deleteEntityById(Long id) { baseDao.deleteEntityById(entityClass, id); return 1; } public T getEntityById(Long id) { return baseDao.findEntityById(entityClass, id); } public List<T> findAllEntitys() { return baseDao.findEntitysByDetachedCriteria(DetachedCriteria.forClass(entityClass)); } public List<T> findAllEntitys(String filterStr) { List<PropertyFilter> filters = PropertyFilter.parsePropertyFilterExp(filterStr); return baseDao.findEntitysByDetachedCriteria(entityClass, filters); } public List<T> findEntitiesInPageByProperties(Integer pageNumber, Integer pageSize, String orderBy, String filterStr) { Integer sIndex = (pageNumber-1)*pageSize; List<PropertyFilter> filters = PropertyFilter.parsePropertyFilterExp(filterStr); Order order = this.getOrder(orderBy); List<T> list = baseDao.findEntitysByDetachedCriteriaLimit(entityClass, filters, order, sIndex, pageSize); long seq = (pageNumber-1)*pageSize+1; for (T entity : list) { entity.setSeq(seq); seq++; } return list; } private Order getOrder(String orderByStr){ Order order = Order.desc("id"); if (null != orderByStr && orderByStr.length() > 0) { String orderName = orderByStr.split("-")[0]; String orderValue = orderByStr.split("-")[1]; order = "desc".equals(orderName) ? Order.desc(orderValue) : Order.asc(orderValue); } return order; } public Integer findEntitiesInPageByPropertiesRowCount(Integer pageNumber, Integer pageSize, String orderBy, String filterStr) { Integer sIndex = (pageNumber-1)*pageSize; List<PropertyFilter> filters = PropertyFilter.parsePropertyFilterExp(filterStr); return baseDao.findRowCount(entityClass, filters, sIndex, pageSize); } protected BaseDao<T> getBaseDao() { return baseDao; } public T findEntityByDetachedCriteria(DetachedCriteria detachedCriteria) { return baseDao.findEntityByDetachedCriteria(detachedCriteria); } public List<T> findEntitysByDetachedCriteria(DetachedCriteria detachedCriteria) { return baseDao.findEntitysByDetachedCriteria(detachedCriteria); } public List<T> findEntitysByDetachedCriteria(Class<T> entityClass, List<PropertyFilter> filters) { return baseDao.findEntitysByDetachedCriteria(entityClass, filters); } public List<T> findEntitysByDetachedCriteriaLimit(DetachedCriteria detachedCriteria, Integer sindex, Integer size) { return baseDao.findEntitysByDetachedCriteriaLimit(detachedCriteria, sindex, size); } public List<T> findEntitysByDetachedCriteriaLimit(Class<T> entityClass, List<PropertyFilter> filters, Integer sindex, Integer size) { return baseDao.findEntitysByDetachedCriteriaLimit(entityClass, filters, sindex, size); } public Integer findRowCount(DetachedCriteria detachedCriteria) { return baseDao.findRowCount(detachedCriteria); } }
相关文章推荐
- Cordova+jQuery Mobile+Spring REST
- Spring Aop支持的两种方式
- 实例简述Spring AOP之对AspectJ语法的支持
- 十四、C# 支持标准查询运算符的集合接口
- MyEclipse中删除对Struts、Hibernate、Spring的支持
- struts2+hibernate+spring+jquery返回json List列表
- spring对AOP的支持(JDK的动态代理实现AOP和CGLIB实现AOP)
- SpringBoot RestController 同时支持返回xml和json格式数据
- C# Web开发 标准读写Cookies的方法 支持跨二级域和虚拟目录
- Html5 + jquery mobile + mobiscroll ,REST手机客户端
- spring对AOP的支持
- C#版OPOS打印(基于北洋OPOS SDK二次开发包,支持EPSON和北洋、佳博、商祺等支持标准ESC/POS指令的POS打印机)
- jquery获取特定name所有选中的checkbox,支持IE9标准模式
- 深入学习SSH框架(Spring MVC +Spring FrameWork +Hibernate +Spring Security)《四:Spring Framework配置篇》
- Spring Security + Hibernate Annotation Example
- spring+hibernate ---含AOP--事务--laobai
- 不要重复DAO!使用Hibernate 和Spring AOP 构建泛型类型安全的DAO
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
- spring-security3.1 + spring mvc + Hibernate 控制系统权限
- 整合spring 支持声明式事务的hibernate