首先这是一个人员与机构信息的管理模块,在这里主要是为了阐述一下利用ExtJS与SSH进行前后台交互的几种方式:
下面我就把页面中所用用到的一些业务逻辑类贴一下:
请求action类:
- @Controller("personAction")
- @Scope("prototype")
- public class PersonAction extends BaseAction implements ModelDriven{
- @Resource
- private PersonManager personManager;
- private Person person;
- private int orgId;
- private int[] ids;
- public Object getModel() {
- if(person == null){
- person = new Person();
- }
- return person;
- }
- public void execute(){
- //{"datas":[{id:xx},{name:xx},{...}],"totals":xx}
- toJSON(personManager.searchPersons());
- }
- public void save() {
- if(person.getId() == null || person.getId() == 0){
- personManager.addPerson(person, orgId);
- }else{
- personManager.updatePerson(person, orgId);
- }
- //需要向客户端应答成功或失败
- Map success = new HashMap();
- success.put("success", true);
- //{success:true}
- toJSON(success);
- //return "pub_add_success";
- }
- public void updateInput() {
- Person p = personManager.findPerson(person.getId());
- //Ext表单加载模型
- ExtLoadModel elm = new ExtLoadModel();
- elm.setSuccess(true);
- elm.setData(p);
- //
- // 也可以采用Map的方式:
- // Map map = new HashMap();
- // map.put("success",true);
- // map.put("data", p);
- //转换后格式:{success:true,data:{id:xx,name:xxx,sex:xx,address:xx}}
- toJSON(elm);
- }
- public void del() {
- //person!del.action?ids=24&ids=21&
- System.out.println(ids.toString());
- if(ids != null){
- for(int i=0; i<ids.length; i++){
- personManager.delPerson(ids[i]);
- }
- }
- }
- public int getOrgId() {
- return orgId;
- }
- public void setOrgId(int orgId) {
- this.orgId = orgId;
- }
- public int[] getIds() {
- return ids;
- }
- public void setIds(int[] ids) {
- this.ids = ids;
- }
- }
下面贴一下在我们action类中所用到一下类:
基类BaseAction
- public class BaseAction {
- static{
- //避免对象的解释陷入死循环,添加自己的JsonMapper解释器
- JSONMapper.addHelper(new MyJsonObjectMapper());
- }
- /**
- * 将一个对象转换为JSON的字符串,并写入HTTP SERVLET OUTPUT STREAM
- * @param o
- */
- protected void toJSON(Object o){
- try {
- ServletActionContext.getResponse().setCharacterEncoding("GB18030");
- ServletActionContext.getResponse().setContentType("text/html");
- //System.out.println(JSONMapper.toJSON( o ).render(true));
- ServletActionContext.getResponse().getOutputStream().write(
- JSONMapper.toJSON( o ).render(false).getBytes("GB18030")
- );
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (MapperException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- //清空
- MyJsonObjectMapper.clean();
- }
- }
- }
封装数据
- /**
- * 封装数据
- * @author Administrator
- *
- */
- public class ExtLoadModel {
- private boolean success;
- private Object data;
- public boolean isSuccess() {
- return success;
- }
- public void setSuccess(boolean success) {
- this.success = success;
- }
- public Object getData() {
- return data;
- }
- public void setData(Object data) {
- this.data = data;
- }
- }
在基类中用到处理JSON数据的类
- /**
- * 在jsonMapper处理之前做一个简单处理
- * 记录已经处理的对象,如果已经处理了。就不在处理否则交给jsonMapper去处理
- * @author Administrator
- *
- */
- public class MyJsonObjectMapper extends ObjectMapper {
- public static ThreadLocal dealedObject = new ThreadLocal();
- /**
- * 判断该对象是否已处理
- * 利用Map中key value来存放记录信息
- * @param o
- * @return
- */
- public static boolean hasDealed(Object o){
- Map map = (Map)dealedObject.get();
- if(map == null){
- map = new HashMap();
- dealedObject.set(map);//首次放到ThreadLocal中
- }
- //如果处理对象为空则不进行判断,交由父类处理
- if(o == null){
- return true;
- }
- //利用map中key记录处理对象的记录信息
- if(map.containsKey(o.toString())){
- return true;
- }else{
- //向map中添加一个key值,记录此对象
- map.put(o.toString(), null);
- return false;
- }
- }
- /**
- * 清空ThreadLocal中的数据
- */
- public static void clean(){
- dealedObject.remove();
- }
- @Override
- public JSONValue toJSON(Object obj) throws MapperException {
- //如果该对象没有处理则交给父类ObjectMapper去处理,完成后返回json格式的对象
- if(!hasDealed(obj)){
- return super.toJSON(obj);
- }
- return new JSONObject();
- }
- }
下面就来看看我们js文件:看看是如何与后台进行交互数据的。
- Ext.onReady(function(){
- Ext.QuickTips.init(); //显示提示信息
- // 相当于一个数据源
- var store = new Ext.data.JsonStore({
- url:"person.action",
- root:"datas",
- totalProperty:"total",
- fields:["id","name","sex","age","address","duty"]
- });
- //1将向后台发出一个请求,请求中包含的参数是start和limit(每页显示的行数)
- store.load({params:{start:0,limit:20}});
- //CheckBox选择框
- var sm = new Ext.grid.CheckboxSelectionModel();
- //创建表单的窗口
- var createFormWindow = function(){
- var postForm = new Ext.form.FormPanel({
- baseCls: 'x-plain',
- defaultType: 'textfield',
- items: [
- {
- xtype:"hidden",
- name:"id"
- },
- {
- fieldLabel:"姓名",
- name:"name"
- },
- {
- fieldLabel:"性别",
- name:"sex"
- },
- {
- fieldLabel:"年龄",
- name:"age"
- },
- {
- fieldLabel:"职务",
- name:"duty"
- },
- {
- fieldLabel:"电话",
- name:"phone"
- },
- {
- fieldLabel:"地址",
- name:"address"
- }
- ],
- buttons: [
- {
- xtype:'button',
- text: '保存',
- handler:function(){
- Ext.MessageBox.show({
- msg: '正在保存,请稍等...',
- progressText: 'Saving...',
- width:300,
- wait:true,
- waitConfig: {interval:200},
- icon:'download'
- });
- postForm.form.doAction('submit',{//2通过form向后台发出请求
- url:"person!save.action",
- method:'post',
- params:'',
- success:function(form,action){
- Ext.MessageBox.hide();
- Ext.Msg.alert('恭喜','保存目标成功');
- store.reload();
- postWindow.destroy();
- },
- failure:function(){
- Ext.Msg.alert('错误','服务器出现错误请稍后再试!');
- }
- });
- }
- },
- {
- text: '取消',
- handler:function(){
- postWindow.destroy();
- }
- }
- ]
- });
- //将表单放到一个窗口中,并显示
- var postWindow = new Ext.Window({
- title: "人员信息表单",
- width: 600,
- height:500,
- collapsible:true,
- maximizable:true,
- layout: 'fit',
- plain:true,
- bodyStyle:'padding:5px;',
- modal:true,
- items: postForm
- });
- postWindow.show();
- return postForm;
- };
- var tbars = [ //在GridPanel列表界面头部的按钮,包括:添加、删除按钮
- //添加按钮
- {
- text:'添加',
- tooltip:'添加记录',
- handler:createFormWindow
- },
- {xtype:'tbseparator'},
- //删除按钮
- {
- text:'删除',
- tooltip:'删除选中的记录',
- handler:function(){
- var _record = sm.getSelected();
- if(_record){
- //提示是否删除数据
- Ext.Msg.confirm("是否要删除?","是否要删除这些被选择的数据?",
- function(btn){
- if(btn == "yes"){
- var ss = sm.getSelections();
- var delUrl = "person!del.action?";
- for(var i=0; i<ss.length; i++){
- delUrl = delUrl + "ids=" + ss[i].data.id + "&";
- //ds.remove(ss[i]);
- }
- //3发出AJAX请求删除相应的数据!
- //delUrl=person!del.action?ids=1&ids=2&ids=3&;
- Ext.Ajax.request({
- url:delUrl,
- success:function(){
- Ext.Msg.alert("删除信息成功","您已经成功删除信息!");
- store.reload();
- },
- failure:function(){
- Ext.Msg.alert('错误','服务器出现错误请稍后再试!');
- }
- });
- }
- }
- );
- }else{
- Ext.Msg.alert('删除操作','您必须选择一行数据以便删除!');
- }
- }
- }
- ];
- // create the Grid
- var grid = new Ext.grid.GridPanel({
- store: store,
- columns: [
- sm,
- {header: "序号", width: 50, sortable: true, dataIndex: 'id'},
- {header: "姓名", width: 275, sortable: true, dataIndex: 'name'},
- {header: "性别", width: 100, sortable: true, dataIndex: 'sex'},
- {header: "年龄", width: 100, sortable: true, dataIndex: 'age'},
- {header: "地址", width: 300, sortable: true, dataIndex: 'address'},
- {header: "职务", width: 200, sortable: true, dataIndex: 'duty'}
- ],
- height:350,
- width:900,
- title:'人员数据信息列表',
- sm : sm,
- bbar:new Ext.PagingToolbar({
- pageSize: 20,
- store: store,
- displayInfo: true,
- displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
- emptyMsg: "没有记录"
- }),
- tbar:tbars
- });
- grid.on("rowdblclick",function(){
- var _record = sm.getSelected();
- if(_record){
- var postForm = createFormWindow();
- postForm.load({//4加载后台数据另一种方式
- url : 'person!updateInput.action?id='+_record.get("id"),
- waitMsg : '正在载入数据...',
- method:"get",
- failure : function(e) {
- Ext.Msg.alert('编辑', '载入失败'+e);
- }
- });
- }else{
- Ext.Msg.alert('修改操作','您必须选择一行数据以便修改!');
- }
- });
- grid.render('grid-example');
- });
在我们jsp页面中只需要引入这些js文件即可:
- <link rel="stylesheet" type="text/css"
- href="ext-3.1.1/resources/css/ext-all.css" />
- <script type="text/javascript"
- src="ext-3.1.1/adapter/ext/ext-base.js"></script>
- <script type="text/javascript"
- src="ext-3.1.1/ext-all.js"></script>
- <script type="text/javascript" src="index.js"></script>
- </head>
- <body>
- <div id="grid-example"></div>
- </body>
关于分页,我在这里并没有贴出相关代码,因为我在前面也说了。主要是为了看看ExtJS与后台业务逻辑进行交互传递数据的方式过程,在细节方面这里还是有许多需要改进的。下面贴出效果图: