- 浏览: 325556 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
无忧何往:
实际用了,发现有点问题;1.redis发布的message应该 ...
扩展spring boot cache实现redis一二级分布式缓存 -
ly8951677:
可以运行了。不过怎么进行多任务添加呢?
Quartz 在 Spring 中如何动态配置时间 -
chenqu:
Lz你好,我点击maven的install按钮,出现以下错误: ...
Quartz 在 Spring 中如何动态配置时间 -
href2008:
你好,请教下,如果不同应用,用一个quartz库可以吗?是不是 ...
Quartz在Spring中集群 -
cwjattop:
Many thanks to your sharing.
Quartz 在 Spring 中如何动态配置时间
网上有关gxt学习资料相对还是比较少,写一个gxt结合spring、hibernate、Mysql对数据库进行增删改查的简单例
子,以供大家参加学习。
一、创建项目工程
用eclispe 3.4创建一个Dynamic web project工程,命名为gxtcurd
二、添加如下依赖类库到WEB-INF/lib下
antlr-2.7.6.jar
aspectjrt-1.5.2a.jar
aspectjweaver-1.5.2a.jar
c3p0-0.9.0.4.jar
cglib-nodep-2.1_3.jar
commons-collections-3.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
javassist-3.4.GA.jar
jta-1.1.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.3-rc-bin.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
spring.jar 版本2.5.6
gwt-servlet.jar 版本1.5.3
gwt-user.jar 版本1.5.3
gxt.jar 版本1.2.3
gxt-servlet.jar 版本1.2.3
hibernate3.jar 版本3.3.1
hibernate-annotations.jar 版本3.4.0
hibernate-commons-annotations.jar 版本3.4.0
三、编写自己的gwt Servlet以支持spring
四、在web.xml文件加入:
五、建立数据库
用Mysql建立数据库gxtcurd,其它数据库,比如oracle也行
在classpath/config下加入文件jdbc.properties:
在classpath/spring目录下加入文件applicationContext.xml:
在classpath/spring目录下加入文件dataAccessContext-hibernate.xml:
在web.xml加入
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
六、建立实体类
七、建立DAO类
八、建立Service类
package com.sundoctor.customer.server;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.sundoctor.customer.client.CustomerService;
import com.sundoctor.customer.client.model.Customer;
import com.sundoctor.customer.server.dao.CustomerDao;
@SuppressWarnings("unchecked")
@Service("customerService")
public class CustomerServiceImpl implements CustomerService {
private CustomerDao customerDao;
@Override
public PagingLoadResult<Customer> getCustomers(PagingLoadConfig config) {
Map<String,Object> map = customerDao.getCustomers("from Customer", config.getOffset(), config.getLimit());
if(CollectionUtils.isEmpty(map)){
return null;
}
List<Customer> customers = (List<Customer>)map.get("list");
long count = (Long)map.get("count");
return new BasePagingLoadResult<Customer>(customers, config.getOffset(), (int)count);
}
@Override
public Customer getCustomer(Integer id) {
return customerDao.getCustomer(id);
}
@Override
public void saveCustomer(Customer customer) {
customerDao.saveCustomer(customer);
}
@Override
public void removeCustomers(List<Customer> customers) {
customerDao.removeCustomers(customers);
}
@Autowired
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
}
九、spring 事务配置
在dataAccessContext-hibernate.xml加入
<!--Hibernate SessionFatory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.sundoctor.customer.client.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.connection.provider_class">${hibernate.connection.provider_class}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
在applicationContext.xml中加入
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution(* com.sundoctor.customer.server..*ServiceImpl.*(..))" advice-ref="txAdvice"/>
</aop:config>
<!-- 基本事务定义,使用transactionManager作事务管理,默认get*方法的事务为readonly,其余方法按默认设置.
默认的设置请参考Spring文档事务一章. -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--Hibernate TransactionManager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
十、建立gxt界面组件相关类
package com.sundoctor.customer.client.grid;
import java.util.ArrayList;
import java.util.List;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.ToolBarEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.PagingToolBar;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToggleToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sundoctor.customer.client.CustomerServiceAsync;
import com.sundoctor.customer.client.model.Customer;
import com.sundoctor.customer.client.widget.CustomerDialog;
public class CustomerBeanModelGrid extends LayoutContainer {
private CustomerServiceAsync customerService;
public CustomerBeanModelGrid() {
}
public CustomerBeanModelGrid(CustomerServiceAsync customerService) {
this.customerService = customerService;
}
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
if (customerService == null) {
MessageBox box = new MessageBox();
box.setButtons(MessageBox.OK);
box.setIcon(MessageBox.INFO);
box.setTitle("Information");
box.setMessage("No service detected");
box.show();
return;
}
// setStyleAttribute("padding", "20px");
// proxy and reader
RpcProxy<PagingLoadConfig, PagingLoadResult<Customer>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<Customer>>() {
@Override
public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<Customer>> callback) {
customerService.getCustomers(loadConfig, callback);
}
};
BeanModelReader<Customer> reader = new BeanModelReader<Customer>();
// loader and store
BasePagingLoader<PagingLoadConfig, PagingLoadResult<Customer>> loader = new BasePagingLoader<PagingLoadConfig, PagingLoadResult<Customer>>(
proxy, reader);
loader.load(0, 50);
final ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
// column model
List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
ColumnConfig id = new ColumnConfig("id", "序号", 50);
id.setHidden(true);
columns.add(id);
columns.add(new ColumnConfig("name", "姓名", 250));
columns.add(new ColumnConfig("email", "Email", 150));
columns.add(new ColumnConfig("age", "年龄", 100));
ColumnModel cm = new ColumnModel(columns);
final Grid<BeanModel> grid = new Grid<BeanModel>(store, cm);
grid.setAutoExpandColumn("name");
// grid.setWidth(600);
// grid.setAutoHeight(true);
grid.setBorders(true);
grid.setLoadMask(true);
ContentPanel panel = new ContentPanel();
panel.setFrame(true);
panel.setCollapsible(true);
panel.setAnimCollapse(false);
panel.setButtonAlign(HorizontalAlignment.CENTER);
panel.setIconStyle("icon-table");
panel.setHeading("客户列表");
panel.setLayout(new FitLayout());
panel.setSize(600, 350);
// HeadToolBar
ToolBar headToolBar = new ToolBar();
ToggleToolItem toggle = new ToggleToolItem("新增");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
new CustomerDialog(customerService,store, new Customer());
}
});
headToolBar.add(toggle);
toggle = new ToggleToolItem("修改");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
if (grid.getSelectionModel().getSelectedItems() == null
|| grid.getSelectionModel().getSelectedItems().size() <= 0) {
MessageBox.alert("提示信息", "请选择一条记录!", null);
} else {
Customer customer = grid.getSelectionModel().getSelectedItem().getBean();
customerService.getCustomer(customer.getId(), new AsyncCallback<Customer>() {
public void onFailure(Throwable caught) {
MessageBox.alert("提示信息", "操作失败!", null);
}
public void onSuccess(Customer result) {
new CustomerDialog(customerService, store,result == null ? new Customer() : result);
}
});
}
}
});
headToolBar.add(toggle);
toggle = new ToggleToolItem("删除");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
final List<BeanModel> beanModels = grid.getSelectionModel().getSelectedItems();
if (beanModels == null || beanModels.size() <= 0) {
MessageBox.alert("提示信息", "请至少选择一条记录!", null);
} else {
customerService.removeCustomers(transform(beanModels), new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
MessageBox.alert("提示信息", "删除失败!", null);
}
public void onSuccess(Void result) {
for(BeanModel beanModel : beanModels){
store.remove(beanModel);
}
MessageBox.alert("提示信息", "删除成功!", null);
}
});
}
}
});
headToolBar.add(toggle);
panel.setTopComponent(headToolBar);
// add grid
panel.add(grid);
// PagingToolBar
final PagingToolBar pagingToolBar = new PagingToolBar(50);
pagingToolBar.bind(loader);
panel.setBottomComponent(pagingToolBar);
add(panel);
}
private List<Customer> transform(List<BeanModel> beanModels) {
List<Customer> customers = new ArrayList<Customer>();
for (BeanModel beanModel : beanModels) {
customers.add((Customer) beanModel.getBean());
}
return customers;
}
}
十一、运行效果如下
在eclipse中用ant运行工程目录下build.xml的gwt-shell任务
效果如下:
在eclipse中用ant运行工程目录下build.xml的gwt-compile任务后,用tomcat6布署,在ie7中效果如下:
十二、工程源码
附件中包括一个war包与工程源码,war放到tomcat6下即可自动运行,工程源码用eclispe3.4直接导入即可使用,
JDK需要1.5以上版本,最好使用JDK6。数据库配置文件在源码gxtcurd\resources\config\jdbc.properties与
gxtcurd\resources\config\hibernate.properties,请大家根据自己情况做相应修改,只需要建库,表会在应用服
务器第一次启动时自己创建。
因为使用了spring、hibernate,需要大量第三方类库,上传附件大小有限,war包与工程源码中不包括任何jar类库
,需要自己补齐以下jar类库,方能正常运行!
antlr-2.7.6.jar
aspectjrt-1.5.2a.jar
aspectjweaver-1.5.2a.jar
c3p0-0.9.0.4.jar
cglib-nodep-2.1_3.jar
commons-collections-3.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
javassist-3.4.GA.jar
jta-1.1.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.3-rc-bin.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
spring.jar 版本2.5.6
gwt-servlet.jar 版本1.5.3
gwt-user.jar 版本1.5.3
gxt.jar 版本1.2.3
gxt-servlet.jar 版本1.2.3
hibernate3.jar 版本3.3.1
hibernate-annotations.jar 版本3.4.0
hibernate-commons-annotations.jar 版本3.4.0
子,以供大家参加学习。
一、创建项目工程
用eclispe 3.4创建一个Dynamic web project工程,命名为gxtcurd
二、添加如下依赖类库到WEB-INF/lib下
引用
antlr-2.7.6.jar
aspectjrt-1.5.2a.jar
aspectjweaver-1.5.2a.jar
c3p0-0.9.0.4.jar
cglib-nodep-2.1_3.jar
commons-collections-3.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
javassist-3.4.GA.jar
jta-1.1.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.3-rc-bin.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
spring.jar 版本2.5.6
gwt-servlet.jar 版本1.5.3
gwt-user.jar 版本1.5.3
gxt.jar 版本1.2.3
gxt-servlet.jar 版本1.2.3
hibernate3.jar 版本3.3.1
hibernate-annotations.jar 版本3.4.0
hibernate-commons-annotations.jar 版本3.4.0
三、编写自己的gwt Servlet以支持spring
引用
public class MyGWTServlet extends RemoteServiceServlet {
private final ThreadLocal<HttpServletRequest> perThreadRequest = new ThreadLocal<HttpServletRequest>();
private final ThreadLocal<HttpServletResponse> perThreadResponse = new ThreadLocal<HttpServletResponse>();
private WebApplicationContext springContext;
@Override
public void init(ServletConfig Config) throws ServletException {
super.init(Config);
springContext = (WebApplicationContext) Config.getServletContext().getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (springContext == null) {
throw new RuntimeException("Check Your Web.Xml Setting, No Spring Context Configured");
}
}
@Override
protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL,
String strongName) {
return super.doGetSerializationPolicy((HttpServletRequest) perThreadRequest.get(), moduleBaseURL, strongName);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
perThreadRequest.set(req);
perThreadResponse.set(resp);
String requestURI = req.getRequestURI();
String beanname = requestURI.substring(requestURI.lastIndexOf("/") + 1,requestURI.lastIndexOf(".gwt"));
RemoteService service = (RemoteService) springContext.getBean(beanname);
String requestPayload = readPayloadAsUtf8(req);
// Let subclasses see the serialized request.
//
onBeforeRequestDeserialized(requestPayload);
// Invoke the core dispatching logic, which returns the serialized
// result.
//
String responsePayload = processCall(service, requestPayload);
// Let subclasses see the serialized response.
//
onAfterResponseSerialized(responsePayload);
// Write the response.
//
writeResponse(req, resp, responsePayload);
} catch (Throwable e) {
// Give a subclass a chance to either handle the exception or
// rethrow it
//
doUnexpectedFailure(e);
} finally {
// HttpRequestContext.ThreadLocalHttpRequestContext.remove();
perThreadRequest.set(null);
perThreadResponse.set(null);
}
}
/**
* rewrite processCall
*
* @param bean
* @param payload
* @return
* @throws SerializationException
*/
public String processCall(RemoteService bean, String payload) throws SerializationException {
try {
RPCRequest rpcRequest = RPC.decodeRequest(payload, bean.getClass(), this);
return RPC.invokeAndEncodeResponse(bean, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest
.getSerializationPolicy());
} catch (IncompatibleRemoteServiceException ex) {
getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
return RPC.encodeResponseForFailure(null, ex);
}
}
private String readPayloadAsUtf8(HttpServletRequest request) throws IOException, ServletException {
return RPCServletUtils.readContentAsUtf8(request, true);
}
private void writeResponse(HttpServletRequest request, HttpServletResponse response, String responsePayload)
throws IOException {
boolean gzipEncode = RPCServletUtils.acceptsGzipEncoding(request)
&& shouldCompressResponse(request, response, responsePayload);
RPCServletUtils.writeResponse(getServletContext(), response, responsePayload, gzipEncode);
}
}
private final ThreadLocal<HttpServletRequest> perThreadRequest = new ThreadLocal<HttpServletRequest>();
private final ThreadLocal<HttpServletResponse> perThreadResponse = new ThreadLocal<HttpServletResponse>();
private WebApplicationContext springContext;
@Override
public void init(ServletConfig Config) throws ServletException {
super.init(Config);
springContext = (WebApplicationContext) Config.getServletContext().getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (springContext == null) {
throw new RuntimeException("Check Your Web.Xml Setting, No Spring Context Configured");
}
}
@Override
protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL,
String strongName) {
return super.doGetSerializationPolicy((HttpServletRequest) perThreadRequest.get(), moduleBaseURL, strongName);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
perThreadRequest.set(req);
perThreadResponse.set(resp);
String requestURI = req.getRequestURI();
String beanname = requestURI.substring(requestURI.lastIndexOf("/") + 1,requestURI.lastIndexOf(".gwt"));
RemoteService service = (RemoteService) springContext.getBean(beanname);
String requestPayload = readPayloadAsUtf8(req);
// Let subclasses see the serialized request.
//
onBeforeRequestDeserialized(requestPayload);
// Invoke the core dispatching logic, which returns the serialized
// result.
//
String responsePayload = processCall(service, requestPayload);
// Let subclasses see the serialized response.
//
onAfterResponseSerialized(responsePayload);
// Write the response.
//
writeResponse(req, resp, responsePayload);
} catch (Throwable e) {
// Give a subclass a chance to either handle the exception or
// rethrow it
//
doUnexpectedFailure(e);
} finally {
// HttpRequestContext.ThreadLocalHttpRequestContext.remove();
perThreadRequest.set(null);
perThreadResponse.set(null);
}
}
/**
* rewrite processCall
*
* @param bean
* @param payload
* @return
* @throws SerializationException
*/
public String processCall(RemoteService bean, String payload) throws SerializationException {
try {
RPCRequest rpcRequest = RPC.decodeRequest(payload, bean.getClass(), this);
return RPC.invokeAndEncodeResponse(bean, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest
.getSerializationPolicy());
} catch (IncompatibleRemoteServiceException ex) {
getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
return RPC.encodeResponseForFailure(null, ex);
}
}
private String readPayloadAsUtf8(HttpServletRequest request) throws IOException, ServletException {
return RPCServletUtils.readContentAsUtf8(request, true);
}
private void writeResponse(HttpServletRequest request, HttpServletResponse response, String responsePayload)
throws IOException {
boolean gzipEncode = RPCServletUtils.acceptsGzipEncoding(request)
&& shouldCompressResponse(request, response, responsePayload);
RPCServletUtils.writeResponse(getServletContext(), response, responsePayload, gzipEncode);
}
}
四、在web.xml文件加入:
引用
<servlet>
<servlet-name>MyGWTServlet</servlet-name>
<servlet-class>com.sundoctor.gwt.spring.servlet.MyGWTServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyGWTServlet</servlet-name>
<url-pattern>*.gwt</url-pattern>
</servlet-mapping>
<servlet-name>MyGWTServlet</servlet-name>
<servlet-class>com.sundoctor.gwt.spring.servlet.MyGWTServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyGWTServlet</servlet-name>
<url-pattern>*.gwt</url-pattern>
</servlet-mapping>
五、建立数据库
用Mysql建立数据库gxtcurd,其它数据库,比如oracle也行
在classpath/config下加入文件jdbc.properties:
引用
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/gxtcurd?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
jdbc.username=root
jdbc.password=kfs
# Time to wait for an open connection before timing out
# (in milliseconds)
cpool.checkoutTimeout=5000
# Connection pool size
cpool.minPoolSize=10
cpool.maxPoolSize=25
# How long to keep unused connections around(in seconds)
# Note: MySQL times out idle connections after 8 hours(28,800 seconds)
# so ensure this value is below MySQL idle timeout
cpool.maxIdleTime=7200
# Acquiring new connections is slow, so eagerly retrieve extra connections
# when current pool size is reached
cpool.acquireIncrement=5
cpool.autoCommitOnClose=true
jdbc.url=jdbc:mysql://localhost:3306/gxtcurd?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
jdbc.username=root
jdbc.password=kfs
# Time to wait for an open connection before timing out
# (in milliseconds)
cpool.checkoutTimeout=5000
# Connection pool size
cpool.minPoolSize=10
cpool.maxPoolSize=25
# How long to keep unused connections around(in seconds)
# Note: MySQL times out idle connections after 8 hours(28,800 seconds)
# so ensure this value is below MySQL idle timeout
cpool.maxIdleTime=7200
# Acquiring new connections is slow, so eagerly retrieve extra connections
# when current pool size is reached
cpool.acquireIncrement=5
cpool.autoCommitOnClose=true
在classpath/spring目录下加入文件applicationContext.xml:
引用
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd" default-autowire="byName" >
<context:component-scan base-package="com.sundoctor"/>
<!-- 支持 @Transactional 标记 -->
<tx:annotation-driven/>
<!-- 支持 @AspectJ 标记-->
<aop:aspectj-autoproxy/>
<!-- 属性文件读入 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:config/jdbc.properties</value>
<value>classpath*:config/hibernate.properties</value>
</list>
</property>
</bean>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd" default-autowire="byName" >
<context:component-scan base-package="com.sundoctor"/>
<!-- 支持 @Transactional 标记 -->
<tx:annotation-driven/>
<!-- 支持 @AspectJ 标记-->
<aop:aspectj-autoproxy/>
<!-- 属性文件读入 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:config/jdbc.properties</value>
<value>classpath*:config/hibernate.properties</value>
</list>
</property>
</bean>
</beans>
在classpath/spring目录下加入文件dataAccessContext-hibernate.xml:
引用
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans default-autowire="byName" >
<!-- 数据源定义,使用c3p0 连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialPoolSize" value="${cpool.minPoolSize}"/>
<property name="minPoolSize" value="${cpool.minPoolSize}" />
<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
<property name="maxIdleTime" value="${cpool.maxIdleTime}"/>
</bean>
</beans>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans default-autowire="byName" >
<!-- 数据源定义,使用c3p0 连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialPoolSize" value="${cpool.minPoolSize}"/>
<property name="minPoolSize" value="${cpool.minPoolSize}" />
<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
<property name="maxIdleTime" value="${cpool.maxIdleTime}"/>
</bean>
</beans>
在web.xml加入
引用
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
六、建立实体类
引用
package com.sundoctor.customer.client.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Customer implements Serializable {
private Integer id;
private String name;
private String email;
private Integer age;
public Customer() {
}
public Customer(Integer id, String name, String email, Integer age) {
this.id = id;
this.age = age;
this.email = email;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Customer implements Serializable {
private Integer id;
private String name;
private String email;
private Integer age;
public Customer() {
}
public Customer(Integer id, String name, String email, Integer age) {
this.id = id;
this.age = age;
this.email = email;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
七、建立DAO类
引用
package com.sundoctor.customer.server.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
import com.sundoctor.customer.client.model.Customer;
@SuppressWarnings("unchecked")
@Repository("customerDao")
public class CustomerDao extends HibernateDaoSupport {
public Map<String,Object> getCustomers(String hql, int pageNo, int pageSize) {
Assert.hasText(hql);
pageNo = pageNo <= 0 ? 1 : pageNo;
// Count查询
String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
List countlist = getHibernateTemplate().find(countQueryString);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return null;
// 实际查询返回分页对象
int startIndex = (pageNo - 1) * pageSize;
Query query = this.getSession().createQuery(hql);
List<Customer> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
Map<String,Object> map = new HashMap<String,Object>();
map.put("count",totalCount);
map.put("list",list);
return map;
}
public Customer getCustomer(Integer id) {
return (Customer) this.getHibernateTemplate().get(Customer.class, id);
}
public void saveCustomer(Customer customer) {
this.getHibernateTemplate().saveOrUpdate(customer);
}
public void removeCustomers(List<Customer> customers) {
this.getHibernateTemplate().deleteAll(customers);
}
/**
* 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
*
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeSelect(String hql) {
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
return hql.substring(beginPos);
}
/**
* 去除hql的orderby 子句,用于pagedQuery.
*
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
import com.sundoctor.customer.client.model.Customer;
@SuppressWarnings("unchecked")
@Repository("customerDao")
public class CustomerDao extends HibernateDaoSupport {
public Map<String,Object> getCustomers(String hql, int pageNo, int pageSize) {
Assert.hasText(hql);
pageNo = pageNo <= 0 ? 1 : pageNo;
// Count查询
String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
List countlist = getHibernateTemplate().find(countQueryString);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return null;
// 实际查询返回分页对象
int startIndex = (pageNo - 1) * pageSize;
Query query = this.getSession().createQuery(hql);
List<Customer> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
Map<String,Object> map = new HashMap<String,Object>();
map.put("count",totalCount);
map.put("list",list);
return map;
}
public Customer getCustomer(Integer id) {
return (Customer) this.getHibernateTemplate().get(Customer.class, id);
}
public void saveCustomer(Customer customer) {
this.getHibernateTemplate().saveOrUpdate(customer);
}
public void removeCustomers(List<Customer> customers) {
this.getHibernateTemplate().deleteAll(customers);
}
/**
* 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
*
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeSelect(String hql) {
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
return hql.substring(beginPos);
}
/**
* 去除hql的orderby 子句,用于pagedQuery.
*
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}
}
八、建立Service类
引用
package com.sundoctor.customer.server;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.sundoctor.customer.client.CustomerService;
import com.sundoctor.customer.client.model.Customer;
import com.sundoctor.customer.server.dao.CustomerDao;
@SuppressWarnings("unchecked")
@Service("customerService")
public class CustomerServiceImpl implements CustomerService {
private CustomerDao customerDao;
@Override
public PagingLoadResult<Customer> getCustomers(PagingLoadConfig config) {
Map<String,Object> map = customerDao.getCustomers("from Customer", config.getOffset(), config.getLimit());
if(CollectionUtils.isEmpty(map)){
return null;
}
List<Customer> customers = (List<Customer>)map.get("list");
long count = (Long)map.get("count");
return new BasePagingLoadResult<Customer>(customers, config.getOffset(), (int)count);
}
@Override
public Customer getCustomer(Integer id) {
return customerDao.getCustomer(id);
}
@Override
public void saveCustomer(Customer customer) {
customerDao.saveCustomer(customer);
}
@Override
public void removeCustomers(List<Customer> customers) {
customerDao.removeCustomers(customers);
}
@Autowired
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
}
九、spring 事务配置
在dataAccessContext-hibernate.xml加入
引用
<!--Hibernate SessionFatory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>com.sundoctor.customer.client.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.connection.provider_class">${hibernate.connection.provider_class}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
在applicationContext.xml中加入
引用
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution(* com.sundoctor.customer.server..*ServiceImpl.*(..))" advice-ref="txAdvice"/>
</aop:config>
<!-- 基本事务定义,使用transactionManager作事务管理,默认get*方法的事务为readonly,其余方法按默认设置.
默认的设置请参考Spring文档事务一章. -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--Hibernate TransactionManager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
十、建立gxt界面组件相关类
引用
package com.sundoctor.customer.client.grid;
import java.util.ArrayList;
import java.util.List;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.ToolBarEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.PagingToolBar;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToggleToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sundoctor.customer.client.CustomerServiceAsync;
import com.sundoctor.customer.client.model.Customer;
import com.sundoctor.customer.client.widget.CustomerDialog;
public class CustomerBeanModelGrid extends LayoutContainer {
private CustomerServiceAsync customerService;
public CustomerBeanModelGrid() {
}
public CustomerBeanModelGrid(CustomerServiceAsync customerService) {
this.customerService = customerService;
}
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
if (customerService == null) {
MessageBox box = new MessageBox();
box.setButtons(MessageBox.OK);
box.setIcon(MessageBox.INFO);
box.setTitle("Information");
box.setMessage("No service detected");
box.show();
return;
}
// setStyleAttribute("padding", "20px");
// proxy and reader
RpcProxy<PagingLoadConfig, PagingLoadResult<Customer>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<Customer>>() {
@Override
public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<Customer>> callback) {
customerService.getCustomers(loadConfig, callback);
}
};
BeanModelReader<Customer> reader = new BeanModelReader<Customer>();
// loader and store
BasePagingLoader<PagingLoadConfig, PagingLoadResult<Customer>> loader = new BasePagingLoader<PagingLoadConfig, PagingLoadResult<Customer>>(
proxy, reader);
loader.load(0, 50);
final ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
// column model
List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
ColumnConfig id = new ColumnConfig("id", "序号", 50);
id.setHidden(true);
columns.add(id);
columns.add(new ColumnConfig("name", "姓名", 250));
columns.add(new ColumnConfig("email", "Email", 150));
columns.add(new ColumnConfig("age", "年龄", 100));
ColumnModel cm = new ColumnModel(columns);
final Grid<BeanModel> grid = new Grid<BeanModel>(store, cm);
grid.setAutoExpandColumn("name");
// grid.setWidth(600);
// grid.setAutoHeight(true);
grid.setBorders(true);
grid.setLoadMask(true);
ContentPanel panel = new ContentPanel();
panel.setFrame(true);
panel.setCollapsible(true);
panel.setAnimCollapse(false);
panel.setButtonAlign(HorizontalAlignment.CENTER);
panel.setIconStyle("icon-table");
panel.setHeading("客户列表");
panel.setLayout(new FitLayout());
panel.setSize(600, 350);
// HeadToolBar
ToolBar headToolBar = new ToolBar();
ToggleToolItem toggle = new ToggleToolItem("新增");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
new CustomerDialog(customerService,store, new Customer());
}
});
headToolBar.add(toggle);
toggle = new ToggleToolItem("修改");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
if (grid.getSelectionModel().getSelectedItems() == null
|| grid.getSelectionModel().getSelectedItems().size() <= 0) {
MessageBox.alert("提示信息", "请选择一条记录!", null);
} else {
Customer customer = grid.getSelectionModel().getSelectedItem().getBean();
customerService.getCustomer(customer.getId(), new AsyncCallback<Customer>() {
public void onFailure(Throwable caught) {
MessageBox.alert("提示信息", "操作失败!", null);
}
public void onSuccess(Customer result) {
new CustomerDialog(customerService, store,result == null ? new Customer() : result);
}
});
}
}
});
headToolBar.add(toggle);
toggle = new ToggleToolItem("删除");
toggle.setIconStyle("icon-add");
toggle.addSelectionListener(new SelectionListener<ToolBarEvent>() {
@Override
public void componentSelected(ToolBarEvent ce) {
final List<BeanModel> beanModels = grid.getSelectionModel().getSelectedItems();
if (beanModels == null || beanModels.size() <= 0) {
MessageBox.alert("提示信息", "请至少选择一条记录!", null);
} else {
customerService.removeCustomers(transform(beanModels), new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
MessageBox.alert("提示信息", "删除失败!", null);
}
public void onSuccess(Void result) {
for(BeanModel beanModel : beanModels){
store.remove(beanModel);
}
MessageBox.alert("提示信息", "删除成功!", null);
}
});
}
}
});
headToolBar.add(toggle);
panel.setTopComponent(headToolBar);
// add grid
panel.add(grid);
// PagingToolBar
final PagingToolBar pagingToolBar = new PagingToolBar(50);
pagingToolBar.bind(loader);
panel.setBottomComponent(pagingToolBar);
add(panel);
}
private List<Customer> transform(List<BeanModel> beanModels) {
List<Customer> customers = new ArrayList<Customer>();
for (BeanModel beanModel : beanModels) {
customers.add((Customer) beanModel.getBean());
}
return customers;
}
}
引用
package com.sundoctor.customer.client.widget;
import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.StatusButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.HiddenField;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sundoctor.customer.client.CustomerServiceAsync;
import com.sundoctor.customer.client.model.Customer;
public class CustomerDialog extends Dialog {
protected Button reset;
protected Button save;
protected FormPanel form;
protected StatusButtonBar buttonBar;
protected CustomerServiceAsync customerService;
protected BeanModel customerModel;
protected ListStore<BeanModel> store;
public CustomerDialog(final CustomerServiceAsync customerService, final ListStore<BeanModel> store,final Customer customer) {
this.customerService = customerService;
this.store = store;
FormLayout layout = new FormLayout();
layout.setLabelWidth(90);
layout.setDefaultWidth(155);
setLayout(layout);
setButtons("");
setIconStyle("user");
setHeading("客户表单");
setModal(true);
setBodyBorder(true);
setBodyStyle("padding: 8px;background: none");
setSize(500, 300);
setResizable(false);
form = new FormPanel();
form.setHeading("客户表单");
form.setHeaderVisible(false);
final HiddenField<Integer> id = new HiddenField<Integer>();
id.setName("id");
id.setFieldLabel("id");
// id.setVisible(false);
form.add(id);
final TextField<String> name = new TextField<String>();
name.setName("name");
name.setFieldLabel("姓名");
name.setAllowBlank(false);
name.setMinLength(3);
name.setMaxLength(50);
form.add(name);
final TextField<String> email = new TextField<String>();
email.setName("email");
email.setFieldLabel("Email");
email.setAllowBlank(false);
email.setMaxLength(200);
//email.setRegex("/^([\\w-])+@([\\w-])+(\\.[\\w-])+/");
//email.setMessageTarget("邮件格式错误!");
form.add(email);
final NumberField age = new NumberField();
age.setName("age");
age.setFieldLabel("年龄");
age.setPropertyEditorType(Integer.class);
age.setAllowBlank(false);
age.setMinValue(1);
age.setMaxValue(150);
form.add(age);
customerModel = BeanModelLookup.get().getFactory(Customer.class).createModel(customer);
final FormBinding formBinding = new FormBinding(form, true);
formBinding.bind(customerModel);
// formBinding.autoBind();
// formBinding.addFieldBinding(new FieldBinding(age,"age"));
add(form);
buttonBar = new StatusButtonBar();
setButtonBar(buttonBar);
show();
}
@Override
protected void createButtons() {
reset = new Button("重置");
reset.addSelectionListener(new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
//CustomerDialog.this.hide();
form.reset();
}
});
save = new Button("保存");
save.addSelectionListener(new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
if (form.isValid()) {
buttonBar.getStatusBar().showBusy("正在处理,请稍后...");
buttonBar.disable();
final Customer customer = customerModel.getBean();
customerService.saveCustomer(customer, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
buttonBar.getStatusBar().hide();
buttonBar.enable();
MessageBox.alert("提示信息", "保存失败!", null);
}
public void onSuccess(Void result) {
buttonBar.getStatusBar().hide();
buttonBar.enable();
store.add(customerModel);
store.getLoader().load();
MessageBox.alert("提示信息", "保存成功!", null);
}
});
}
}
});
buttonBar.add(save);
buttonBar.add(reset);
}
}
import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.StatusButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.HiddenField;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sundoctor.customer.client.CustomerServiceAsync;
import com.sundoctor.customer.client.model.Customer;
public class CustomerDialog extends Dialog {
protected Button reset;
protected Button save;
protected FormPanel form;
protected StatusButtonBar buttonBar;
protected CustomerServiceAsync customerService;
protected BeanModel customerModel;
protected ListStore<BeanModel> store;
public CustomerDialog(final CustomerServiceAsync customerService, final ListStore<BeanModel> store,final Customer customer) {
this.customerService = customerService;
this.store = store;
FormLayout layout = new FormLayout();
layout.setLabelWidth(90);
layout.setDefaultWidth(155);
setLayout(layout);
setButtons("");
setIconStyle("user");
setHeading("客户表单");
setModal(true);
setBodyBorder(true);
setBodyStyle("padding: 8px;background: none");
setSize(500, 300);
setResizable(false);
form = new FormPanel();
form.setHeading("客户表单");
form.setHeaderVisible(false);
final HiddenField<Integer> id = new HiddenField<Integer>();
id.setName("id");
id.setFieldLabel("id");
// id.setVisible(false);
form.add(id);
final TextField<String> name = new TextField<String>();
name.setName("name");
name.setFieldLabel("姓名");
name.setAllowBlank(false);
name.setMinLength(3);
name.setMaxLength(50);
form.add(name);
final TextField<String> email = new TextField<String>();
email.setName("email");
email.setFieldLabel("Email");
email.setAllowBlank(false);
email.setMaxLength(200);
//email.setRegex("/^([\\w-])+@([\\w-])+(\\.[\\w-])+/");
//email.setMessageTarget("邮件格式错误!");
form.add(email);
final NumberField age = new NumberField();
age.setName("age");
age.setFieldLabel("年龄");
age.setPropertyEditorType(Integer.class);
age.setAllowBlank(false);
age.setMinValue(1);
age.setMaxValue(150);
form.add(age);
customerModel = BeanModelLookup.get().getFactory(Customer.class).createModel(customer);
final FormBinding formBinding = new FormBinding(form, true);
formBinding.bind(customerModel);
// formBinding.autoBind();
// formBinding.addFieldBinding(new FieldBinding(age,"age"));
add(form);
buttonBar = new StatusButtonBar();
setButtonBar(buttonBar);
show();
}
@Override
protected void createButtons() {
reset = new Button("重置");
reset.addSelectionListener(new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
//CustomerDialog.this.hide();
form.reset();
}
});
save = new Button("保存");
save.addSelectionListener(new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
if (form.isValid()) {
buttonBar.getStatusBar().showBusy("正在处理,请稍后...");
buttonBar.disable();
final Customer customer = customerModel.getBean();
customerService.saveCustomer(customer, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
buttonBar.getStatusBar().hide();
buttonBar.enable();
MessageBox.alert("提示信息", "保存失败!", null);
}
public void onSuccess(Void result) {
buttonBar.getStatusBar().hide();
buttonBar.enable();
store.add(customerModel);
store.getLoader().load();
MessageBox.alert("提示信息", "保存成功!", null);
}
});
}
}
});
buttonBar.add(save);
buttonBar.add(reset);
}
}
引用
package com.sundoctor.customer.client;
import java.util.List;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.sundoctor.customer.client.model.Customer;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface CustomerServiceAsync {
void getCustomers(PagingLoadConfig config, AsyncCallback<PagingLoadResult<Customer>> callback);
void getCustomer(Integer id, AsyncCallback<Customer> callback);
void saveCustomer(Customer customer, AsyncCallback<Void> callback);
void removeCustomers(List<Customer> cs, AsyncCallback<Void> callback);
}
import java.util.List;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.sundoctor.customer.client.model.Customer;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface CustomerServiceAsync {
void getCustomers(PagingLoadConfig config, AsyncCallback<PagingLoadResult<Customer>> callback);
void getCustomer(Integer id, AsyncCallback<Customer> callback);
void saveCustomer(Customer customer, AsyncCallback<Void> callback);
void removeCustomers(List<Customer> cs, AsyncCallback<Void> callback);
}
引用
package com.sundoctor.customer.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;
import com.sundoctor.customer.client.grid.CustomerBeanModelGrid;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Customer implements EntryPoint {
public void onModuleLoad() {
RootPanel.get().add(new CustomerBeanModelGrid(initServiceEntryPoint()));
}
private CustomerServiceAsync initServiceEntryPoint() {
CustomerServiceAsync calculator = CustomerService.Util.getInstance();
ServiceDefTarget endpoint = (ServiceDefTarget) calculator;
endpoint.setServiceEntryPoint(CustomerService.Util.getModuleRelativeURL());
return calculator;
}
}
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;
import com.sundoctor.customer.client.grid.CustomerBeanModelGrid;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Customer implements EntryPoint {
public void onModuleLoad() {
RootPanel.get().add(new CustomerBeanModelGrid(initServiceEntryPoint()));
}
private CustomerServiceAsync initServiceEntryPoint() {
CustomerServiceAsync calculator = CustomerService.Util.getInstance();
ServiceDefTarget endpoint = (ServiceDefTarget) calculator;
endpoint.setServiceEntryPoint(CustomerService.Util.getModuleRelativeURL());
return calculator;
}
}
十一、运行效果如下
在eclipse中用ant运行工程目录下build.xml的gwt-shell任务
效果如下:
在eclipse中用ant运行工程目录下build.xml的gwt-compile任务后,用tomcat6布署,在ie7中效果如下:
十二、工程源码
附件中包括一个war包与工程源码,war放到tomcat6下即可自动运行,工程源码用eclispe3.4直接导入即可使用,
JDK需要1.5以上版本,最好使用JDK6。数据库配置文件在源码gxtcurd\resources\config\jdbc.properties与
gxtcurd\resources\config\hibernate.properties,请大家根据自己情况做相应修改,只需要建库,表会在应用服
务器第一次启动时自己创建。
因为使用了spring、hibernate,需要大量第三方类库,上传附件大小有限,war包与工程源码中不包括任何jar类库
,需要自己补齐以下jar类库,方能正常运行!
引用
antlr-2.7.6.jar
aspectjrt-1.5.2a.jar
aspectjweaver-1.5.2a.jar
c3p0-0.9.0.4.jar
cglib-nodep-2.1_3.jar
commons-collections-3.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
javassist-3.4.GA.jar
jta-1.1.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.3-rc-bin.jar
slf4j-api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
spring.jar 版本2.5.6
gwt-servlet.jar 版本1.5.3
gwt-user.jar 版本1.5.3
gxt.jar 版本1.2.3
gxt-servlet.jar 版本1.2.3
hibernate3.jar 版本3.3.1
hibernate-annotations.jar 版本3.4.0
hibernate-commons-annotations.jar 版本3.4.0
- gxtcurd.rar (2.5 MB)
- 下载次数: 826
评论
3 楼
g27_lzg
2010-04-15
作者你好:
感谢你的无私奉献。我对你的代码做了很小的改动,以便于在GXT2.0下运行。现在运行
后 ,删除按钮没问题,但增加和修改按钮点击后都没有反映。
修改增加 的代码没变
Customer customer = grid.getSelectionModel().getSelectedItem().getBean();
运行时也没有报错,跟踪我看不出问题。。。。
再就是翻页按钮,前面几十页翻页没问题,但翻到后面就是空白了,可数据库里是有数据的。
还请多多 指教!!!
感谢你的无私奉献。我对你的代码做了很小的改动,以便于在GXT2.0下运行。现在运行
后 ,删除按钮没问题,但增加和修改按钮点击后都没有反映。
修改增加 的代码没变
Customer customer = grid.getSelectionModel().getSelectedItem().getBean();
运行时也没有报错,跟踪我看不出问题。。。。
再就是翻页按钮,前面几十页翻页没问题,但翻到后面就是空白了,可数据库里是有数据的。
还请多多 指教!!!
2 楼
sundoctor
2009-12-14
gwt里用的是servlet: RemoteServiceServlet ,servlet怎么用seesion应该很清楚吧,这里也一样。
1 楼
menglinxi
2009-12-13
这里面如果需要登录,session
怎么处理???
怎么处理???
相关推荐
GXT(GWT-Ext)是一个基于Google Web Toolkit (GWT) 的JavaScript UI库,它扩展了GWT的功能,提供了丰富的用户界面组件和强大的数据网格处理能力。GXT的一个核心特性是支持CRUD(创建、读取、更新、删除)操作,这...
GXT增删改查的demo,很好的。很简单明了,值得下载好好学习研究。
强大的ajax框架gwt与ext的整合,完全的java开发。不用学习ajax就可以使用axaj.
在级联下拉框的例子中,这个类可能包含了一些预定义的国家和省份对象,用于模拟数据库查询返回的结果。开发者通常会在这里创建数据模型,定义字段,并提供获取数据的方法。 `Country.java`和`Province.java`是两个...
**GXT项目详解** GXT,全称是GWT eXtensions,是Sencha公司为Google Web Toolkit(GWT)开发的一套丰富的用户界面组件库。GXT项目旨在为Web应用程序提供桌面级别的用户体验,利用JavaScript和HTML5技术,使得在...
- **第一个GXT项目**:从零开始创建一个简单的GXT应用程序,熟悉基本流程。 2. **UI组件与布局管理** - **常用UI组件**:介绍GXT提供的各种UI组件,如按钮、文本框、复选框等。 - **布局管理器**:讲解如何使用...
标题中的"Gxt"指的是Sencha GXT,这是一个基于Google Web Toolkit (GWT) 的Java库,专门用于构建富互联网应用程序(Rich Internet Applications, RIA)。GXT提供了丰富的组件、数据绑定、布局管理以及主题定制等功能...
通过简单的配置和集成,开发者可以使用GXT组件来构建出与桌面应用相媲美的Web应用。同时,开发者需要注意环境配置、浏览器兼容性以及服务器配置的问题,确保开发和部署过程的顺畅。通过这篇教程,开发者可以一步一步...
这意味着你可以定义一个简单的Java类,包含公共属性和getter/setter方法,然后GXT会自动将其转化为可交互的UI组件。这种方式极大地简化了数据绑定和更新过程,提高了开发效率。 2. **初识ExtGWT**: 在这个文档中...
**GXT软件包和API详解** GXT,全称为GWT Ext,是基于Google Web Toolkit (GWT) 的一个强大的Java UI库。它为开发者提供了丰富的用户界面组件和功能,使得构建复杂的、企业级的Web应用程序变得更加便捷。GXT不仅在...
在IT行业中,GXT(Ext GWT)和GWT(Google Web Toolkit)是两种流行的JavaScript库,用于构建富互联网应用程序(Rich Internet Applications, RIA)。它们都是基于Java语言的,可以提供丰富的用户界面组件和高效的...
**GXT v2.2.1 API 文档详解** GXT (Ext GWT) 是一个基于Google Web Toolkit (GWT) 的用户界面库,它提供了一系列丰富的组件和样式,用于构建复杂的、高性能的Web应用程序。GXT v2.2.1 API文档是官方提供的详细参考...
《GXT 2.2.5:Ext-GWT的增强工具包详解》 GXT,全称为GWT eXtension,是由EXTJS团队开发的一个用于Google Web Toolkit(GWT)的扩展库,旨在为GWT开发者提供更丰富、更强大的用户界面组件和功能。GXT 2.2.5是该系列...
GWT(Google Web Toolkit)和GXT(EXT GWT)是两个重要的Java开发框架,用于构建富互联网应用程序(RIA)。GWT是由Google开发的一个开源工具,它允许开发者使用Java语言来编写前端用户界面,然后自动将Java代码编译...
标题 "gxt-1.2.3.jar.zip" 指的是一个包含GXT库的压缩文件,版本为1.2.3。GXT,全称为Google Web Toolkit EXT,是Google Web Toolkit(GWT)的一个扩展,它提供了一系列丰富的用户界面组件,用于构建功能强大的Web...
在`Libraries`选项卡中,点击`Add External JARs`,导航到你的GXT SDK安装目录,选择`gxt-x.x.x-client.jar`(x.x.x代表你的GXT版本号)添加进来。 4. **创建GXT模块**:打开`src/main/java`目录下的`...
### ExtGWT、GWT与GXT初学教程:打造企业级富客户端Web应用 #### 构建初识:ExtGWT与GWT的协同工作 ExtGWT,作为GWT(Google Web Toolkit)的有力补充,旨在为Java开发者提供更为丰富、功能全面的组件库,从而构建...
标题 "gwt gxt demo" 暗示我们正在探讨一个基于 Google Web Toolkit (GWT) 和 Sencha GXT 的演示项目。GWT 是一个由Google开发的开源框架,允许开发者使用Java语言来编写Web应用,然后编译成优化过的JavaScript代码...
《X_GXT_Editor-V-2-3_gta_》是一款专为《侠盗猎车手:圣安地列斯》(GTA: San Andreas)设计的GXT编辑工具,它允许玩家对游戏中的文本和语言数据进行自定义,从而实现个性化的游戏体验。GXT文件是Rockstar Games为...
标题 "GXT MVC设计" 指向的是一个关于使用GXT(Google Web Toolkit Extensions)进行Model-View-Controller(MVC)架构设计的主题。GXT是Google Web Toolkit(GWT)的一个扩展库,提供了丰富的用户界面组件和高级UI...