为ExtJS的grid panel提供restful服务
ExtJS的grid panel集成了负责前端交互的分页、检索、排序。
用浏览器开发者工具查看,可以看到它提交给后台的restful形式:
page:1 start:0 limit:27 sort:[{"property":"id","direction":"DESC"}] filter:[{"operator":"like","value":"111","property":"title"}]
而它期待获得的返回结果格式如下:
{ "data" : [ { "id" : 1, "dtCreate" : null, "href" : null, "author" : null, "btop" : 0, "content" : "内容第1行<div>内容第2行</div>", "pid" : 0, "plain" : null, "postto" : "政策法规;用户中心#办理流程", "stitle" : "rrrr", "stype" : null, "tag" : null, "title" : "题名11111", "uid" : 0, "status" : 2, "primaryKey" : 1 } ], "total" : 1 }
其中total是分页的依据。
我们以下图所示的思路为grid panel提供restful数据服务:
请求传到后台,先由controller对参数进行一次拆分,page、start、limit这样的简单参数直接就拿到了。
@RequestMapping(value = "/list/{entity}", method = RequestMethod.GET) @ResponseBody public ResultDTO getEntities(@PathVariable String entity, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "start", required = false) Integer start, @RequestParam(value = "limit", required = false) Integer limit, @RequestParam(value = "filter", required = false) String filter, @RequestParam(value = "sort", required = false) String sort) throws Exception { return restService.getEntities(page, start, limit, filter, sort, entity); }
然后对filter和sort进行进一步分析,这两个参数是json格式的复杂请求,分析的策略是:在java中定义与前台对应的请求对象,
通过com.fasterxml.jackson.databind.ObjectMapper 直接读入json内容,获得java请求对象。
package net.bat.filter; public class ExtJSFilter { private String operator; private Object value; private String property; private Boolean exactMatch; public Boolean getExactMatch() { return exactMatch; } public void setExactMatch(Boolean exactMatch) { this.exactMatch = exactMatch; } /** * @return the operator */ public String getOperator() { return this.operator; } /** * @param operator the operator to set */ public void setOperator(String operator) { this.operator = operator; } /** * @return the value */ public Object getValue() { return this.value; } /** * @param value the value to set */ public void setValue(Object value) { this.value = value; } /** * @return the property */ public String getProperty() { return property; } /** * @param property the property to set */ public void setProperty(String property) { this.property = property; } }
package net.bat.filter; public class ExtJSSort { private String property; private String direction; /** * @return the property */ public String getProperty() { return property; } /** * @param property the property to set */ public void setProperty(String property) { this.property = property; } /** * @return the direction */ public String getDirection() { return direction; } /** * @param direction the direction to set */ public void setDirection(String direction) { this.direction = direction; } }
ExtJSFilter[] fliters = mapper.readValue(filter, ExtJSFilter[].class); ... ExtJSSort[] sorts = mapper.readValue(sort, ExtJSSort[].class);
接下来,需要将请求转化为JPA检索能接受的请求形式:
public <T> JPAReq parse(String filter, String sort, Class<T> cls) throws Exception { JPAReq req = new JPAReq(); if (filter != null) { StringBuffer sbuf = new StringBuffer(); int pos = 0; ExtJSFilter[] fliters = mapper.readValue(filter, ExtJSFilter[].class); Object[] queryParams = new Object[fliters.length]; for (ExtJSFilter ef : fliters) { String filedName = ef.getProperty(); // 处理外键 many-to-many if ((ef.getExactMatch() != null) && ef.getExactMatch()) { // TODO add ename filter if (cls == Attach.class) { filedName = "eid"; ef.setOperator("eq"); } else { filedName = "pid"; ef.setOperator("eq"); } } if (pos == 0) { sbuf.append(" " + filedName); } else { sbuf.append(" and " + filedName); } Oper oper = Oper.valueOf(ef.getOperator().toUpperCase()); Object val = ef.getValue(); // EQ, LIKE, GT, LT, GTE, LTE String paraPos = "(?" + (pos + 1) + ")"; switch (oper) { case EQ: sbuf.append(" =" + paraPos); break; case LIKE: sbuf.append(" like " + paraPos); val = "%" + val + "%"; break; case GT: sbuf.append(" >" + paraPos); break; case LT: sbuf.append(" <" + paraPos); break; case GE: sbuf.append(" >=" + paraPos); break; case LE: sbuf.append(" <=" + paraPos); break; case IN: sbuf.append(" in " + paraPos); queryParams[pos++] = val; continue; } // 如果参数值与目标属性不匹配,需要特殊处理,例如:日期 Field f = null; try { f = cls.getDeclaredField(filedName); } catch (Exception e) { // getDeclaredField 无法获得 extend的父类field f = cls.getSuperclass().getDeclaredField(filedName); } Class<?> fcl = f.getType(); if ((val != null) && !fcl.isAssignableFrom(val.getClass())) { if (fcl.isAssignableFrom(Date.class)) { // val = fmt_date.parse(val.toString()); // dateformat: time val = new Date(Long.parseLong(val.toString())); } else if (fcl.isAssignableFrom(Long.class)) { // 检索传值integer与期待值long不匹配 val = Long.parseLong(val.toString()); } } queryParams[pos++] = val; } req.setWhereql(sbuf.toString()); req.setQueryParams(queryParams); } if (sort != null) { LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>(); ExtJSSort[] sorts = mapper.readValue(sort, ExtJSSort[].class); for (ExtJSSort es : sorts) { orderby.put(es.getProperty(), es.getDirection()); } req.setOrderby(orderby); } return req; } }
调用JPA分页检索,返回结果:
private <T extends IdEntity> QueryResult<T> getEntity(Integer page, Integer start, Integer limit, String filter, String sort, String entity_name) throws Exception { Class<T> cls = UserDAO.classForName(entity_name); JPAReq req = parser.parse(filter, sort, cls); if (start == null) { start = 0; } if (limit == null) { limit = -1; } QueryResult<T> result = dao.getScrollData(cls, start, limit, req.getWhereql(), req.getQueryParams(), req.getOrderby()); return result; }
通用的dao实现借用了网友的工作。
相关推荐
ExtJS4.1+MVC4+Spring.NET1.3+EF5 整合项目数据库(pdm、sql及sqlite数据库) 原文地址:http://blog.csdn.net/xz2001/article/details/8723266
"Hibernate+Spring+Struts2+ExtJS整合开发实例"就是一个典型的Java Web应用程序开发案例,它将四个关键组件结合在一起,以实现高效、模块化的后端和前端功能。 **Hibernate** 是一个流行的Java对象关系映射(ORM)...
【标题】"spring+mvc+mybatis+extjs整合"是一个经典的Java Web开发框架组合,广泛应用于企业级应用。这个项目结合了Spring MVC作为控制层,MyBatis作为数据访问层,以及ExtJS作为前端展示层,构建了一个完整的三层...
"Spring3+iBatis3+Struts2.18+ExtJS3整合增删查改"是一个典型的Java Web开发组合,用于实现高效的数据管理和用户界面交互。下面我们将深入探讨这个组合中的每个组件及其在整体架构中的作用。 **Spring3**: Spring...
三、Spring与ExtJS整合 1. RESTful API:Spring MVC可以通过配置轻松实现RESTful接口,供ExtJS前端调用。 2. JSON数据交换:Spring支持JSON序列化与反序列化,与ExtJS的数据模型对接,实现前后端数据交互。 3. ...
extjs dwr hibernate spring 整合的树!
Spring3MVC、MyBatis和ExtJs3的整合开发旨在创建一个高效的、灵活的Web应用程序。整合的关键在于如何协调这些框架的工作,使得Spring3MVC处理HTTP请求和控制流程,MyBatis负责数据访问和SQL执行,而ExtJs3则作为前端...
总结来说,"ssh+extjs4整合开发"涉及到的技术栈是Java后端开发的强大组合,结合了Spring的灵活性、Struts2的MVC架构以及Hibernate的对象关系映射,再加上EXTJS4的富客户端能力。这种整合使得开发者能够构建出高效、...
在现代Web开发中,Spring MVC和ExtJS是两个常见的技术,用于构建强大的后端和前端应用。本篇文章将深入探讨如何使用Spring MVC 3与ExtJS进行数据交互,特别是通过JSON格式来实现这一过程。 首先,Spring MVC 3引入...
ExtJS4.1+MVC3+Spring.NET1.3+EF5 整合项目用到的数据库 原文地址: http://blog.csdn.net/xz2001/article/details/8716541 注:该数据库是20130411日修改后的。
6. 安全性考虑:可能需要整合Spring Security或其他安全框架,以保护应用程序免受未经授权的访问。 7. 测试:编写单元测试和集成测试,确保每个部分的功能正常,同时优化性能和响应时间。 通过这个整合,开发者...
在本项目中,我们探讨的是一个基于Java技术栈的图书管理系统实现,具体采用了Spring、Struts2、iBatis和ExtJS这四个核心技术。这个系统旨在提供全面的图书管理功能,包括图书的增删改查、用户管理以及可能的借阅、...
【标题】"Extjs struts2 spring 图书馆"是一个基于流行Java技术栈构建的图书馆管理系统,它将前端的富互联网应用(RIA)框架Extjs与后端的MVC框架Struts2和企业级服务管理框架Spring进行了深度融合。这个项目为...
ExtJS4、Spring、Struts2和iBatis是Java Web开发中常用的技术栈,它们在构建企业级应用中发挥着各自的关键作用。下面将详细解释这些技术以及它们如何协同工作。 1. ExtJS4:这是一款强大的JavaScript库,用于构建富...
Extjs5.0从入门到实战开发信息管理系统(Extjs基础、Extjs5新特性、Spring、Spring mvc、Mybatis),完整版,提供课件和代码下载! 本教程从Extjs5的开发环境搭建开始,讲解了Extjs5的项目结构(包括核心文件的作用...
在本篇博文中,我们将深入探讨“Spring3MVC+MyBatis+ExtJs3整合开发系列之四:角色管理模块”。这个主题涉及到三个关键的技术栈:Spring MVC作为后端MVC框架,MyBatis作为持久层解决方案,以及Ext Js 3作为前端UI库...
**整合DWR、EXTJS、Spring和Hibernate** 将这四者结合,可以创建出高性能的Web应用。DWR处理客户端与服务器的通信,EXTJS负责用户界面,Spring作为应用的架构基础,提供服务层和数据访问层的支持,而Hibernate则用于...
标题“Spring+JPA+ExtJS(Grid)”涉及的是一个整合了Spring框架、Java Persistence API (JPA) 和ExtJS Grid的项目。这个项目的核心在于利用这些技术构建一个数据展示和管理的前端后端系统。 首先,Spring是企业级...