【SSH網上商城專案實戰07】Struts2和Json的整合
轉自:https://blog.csdn.net/eson_15/article/details/51332758
上一節我們完成了DataGrid顯示jason資料,但是沒有和後臺聯絡在一起,只是單純地顯示了我們自己弄的json資料,這一節我們將json和Struts2整合,打通EasyUI和Struts2之間的互動。
1. json環境的搭建
json環境搭建很簡單,匯入json的jar包即可,如下:
---------------------
作者:eson_15
來源:CSDN
原文:https://blog.csdn.net/eson_15/article/details/51332758?utm_source=copy
版權宣告:本文為博主原創文章,轉載請附上博文連結!
2. 完善Action
在DataGrid控制元件中有個屬性是url,可以指定請求資料的url地址,在上一節我們將這個地址直接設定成了一個具體的json檔案,這裡我們將這個url設定成一個action,如url:'category_queryJoinAccount.action',表示會去請求categoryAction的queryJoinAccount方法(文章最後會給出query.jsp的程式碼)。所以我們需要去完成categoryAction中的queryJoinAccount方法。
在Struts2和json整合前,我們先看一下之前顯示一次json資料都發了哪些請求:
因為type是Category類的一個屬性,我們在BaseAction中已經實現了ModelDriven<Category>介面,所以這個type會被封裝到model中,我們不需要管它,可以通過model來獲取,但是EasyUI自動發過來的page和rows引數我們需要自己獲取了,所以我們可以在BaseModel中增加兩個成員變數page和rows並實現get和set方法,最後還要考慮一點,這些引數都獲得了後,我們根據這些引數去資料庫中查詢資料,那麼我們查出來的資料放到哪呢?而且還要打包成json格式發到前臺才能被DataGrid顯示。我們先不考慮將查詢到的資料如何打包成json格式,我們先考慮把這些資料放到一個地方,很自然的想到了使用Map,因為json格式的資料就是key-value形式的。想到這裡,我們繼續完善BaseAction:
1 @Controller("baseAction") 2 @Scope("prototype") 3 public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> { 4 5 //page和rows和分頁有關,pageMap存放查詢的資料,然後打包成json格式用的 6 //page和rows實現get和set方法,pageMap只需要實現get方法即可,因為pageMap不是接收前臺引數的,是讓struts獲取的 7 protected Integer page; 8 protected Integer rows; 9 protected Map<String, Object> pageMap = null;//讓不同的Action自己去實現 10 //省略get和set方法…… 11 12 /******************* 下面還是原來BaseAction部分 *************************/ 13 //service物件 14 @Resource 15 protected CategoryService categoryService; 16 @Resource 17 protected AccountService accountService; 18 19 //域物件 20 protected Map<String, Object> request; 21 protected Map<String, Object> session; 22 protected Map<String, Object> application; 23 24 @Override 25 public void setApplication(Map<String, Object> application) { 26 this.application = application; 27 } 28 @Override 29 public void setSession(Map<String, Object> session) { 30 this.session = session; 31 } 32 @Override 33 public void setRequest(Map<String, Object> request) { 34 this.request = request; 35 } 36 37 //ModelDriven 38 protected T model; 39 @Override 40 public T getModel() { 41 ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass(); 42 Class clazz = (Class)type.getActualTypeArguments()[0]; 43 try { 44 model = (T)clazz.newInstance(); 45 } catch (Exception e) { 46 throw new RuntimeException(e); 47 } 48 return model; 49 } 50 }
好,完善了BaseCategory後,我們可以寫categoryAction中的queryJoinAccount方法了,我們將categoryAction中原來的方法全刪掉,因為那些都是之前搭建環境時候測試用的,都不用了,現在真正開始專案程式碼了:
1 @Controller("categoryAction") 2 @Scope("prototype") 3 public class CategoryAction extends BaseAction<Category> { 4 5 public String queryJoinAccount() { 6 7 //用來儲存分頁的資料 8 pageMap = new HashMap<String, Object>(); 9 10 //根據關鍵字和分頁的引數查詢相應的資料。這個方法我們在Service中寫過了,當時完成級聯查詢 11 List<Category> categoryList = categoryService.queryJoinAccount(model.getType(), page, rows); 12 pageMap.put("rows", categoryList); //儲存為JSON格式,從上一節的json檔案可以看出,一個key是total,一個key是rows,這裡先把rows存放好 13 //根據關鍵字查詢總記錄數 14 Long total = categoryService.getCount(model.getType()); //這個方法沒寫,我們等會兒去Service層完善一下 15 // System.out.println(total); 16 pageMap.put("total", total); //儲存為JSON格式,再把total存放好 17 18 return "jsonMap"; 19 } 20 }
這樣Action我們就寫好了,現在Action拿到前臺傳來的引數,然後根據引數查詢了指定type的總記錄數,以及指定type的所有商品,並且按照json中指定的key(即total和rows)進行存放,放在HashMap中了,之後只要將這個HashMap中的資料打包成json格式傳送到前臺就可以被DataGrid顯示了。我們先把這個HashMap放這,先去完善了Service層的程式碼後,再來打包這個HashMap中的資料。
3. 完善categoryService
從上面的categoryAction中可知,需要在categoryService中增加一個getCount方法,並且要在具體實現類中實現好,實現如下:
1 //CategoryService介面 2 public interface CategoryService extends BaseService<Category> { 3 //查詢類別資訊,級聯管理員 4 public List<Category> queryJoinAccount(String type, int page, int size); //使用類別的名稱查詢 5 //根據關鍵字查詢總記錄數 6 public Long getCount(String type); 7 } 8 9 //CategoryServiceImpl實現類 10 @SuppressWarnings("unchecked") 11 @Service("categoryService") 12 public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService { 13 14 @Override 15 public List<Category> queryJoinAccount(String type, int page, int size) { 16 String hql = "from Category c left join fetch c.account where c.type like :type"; 17 return getSession().createQuery(hql) 18 .setString("type", "%" + type + "%") 19 .setFirstResult((page-1) * size) //從第幾個開始顯示 20 .setMaxResults(size) //顯示幾個 21 .list(); 22 } 23 24 @Override 25 public Long getCount(String type) { 26 String hql = "select count(c) from Category c where c.type like :type"; 27 return (Long) getSession().createQuery(hql) 28 .setString("type", "%" + type + "%") 29 .uniqueResult(); //返回一條記錄:總記錄數 30 } 31 }
到現在為止,這個資料庫中資料的獲取這條路就打通了,前面兩步完成了從前臺-->資料庫-->取資料,接下來就開始打包HashMap中存放的資料,然後發給前臺了。
4. 配置struts.xml
在struts.xml中通過配置就可以完成對指定資料的打包,我們先看一下struts.xml中的配置:
1 <struts> 2 3 <constant name="struts.devMode" value="true" /> 4 5 <package name="shop" extends="json-default"><!-- jason-default繼承了struts-default --> 6 7 <global-results> 8 <result name="aindex">/WEB-INF/main/aindex.jsp</result> 9 </global-results> 10 11 <!-- class對應的是Spring中配置該Action的id值,因為要交給Spring管理 --> 12 <action name="category_*" class="categoryAction" method="{1}"> 13 <!-- 必須要先新增json包,然後上面繼承json-default --> 14 <result name="jsonMap" type="json"> 15 <!-- 要轉換成json物件的資料 --> 16 <param name="root">pageMap</param> 17 <!-- 配置黑名單,過濾不需要的選項 ,支援正則表示式 18 json格式:{total:3,rows:[{account:{id:2,login:"user",name:"客服A",pass:"user"},hot:true,id:3,…}]} 19 --> 20 <param name="excludeProperties"> 21 <!-- rows[0].account.pass--> 22 <!-- 這裡顯示不了正則表示式, CSDN的一個bug,我接個圖放下面 --> 23 </param> 24 </result> 25 </action> 26 27 <action name="account_*" class="accountAction" method="{1}"> 28 <result name="index">/index.jsp</result> 29 </action> 30 31 <!-- 用來完成系統 請求轉發的action,所有的請求都交給execute--> 32 <action name="send_*_*" class="sendAction"> 33 <result name="send">/WEB-INF/{1}/{2}.jsp</result> 34 </action> 35 </package> 36 37 </struts>
從上面的配置可以看出,首先package要繼承json-default,因為json-default繼承了struts-default,因為在json的jar包裡有個struts2-json-plugin-2.3.24.1.jar,開啟即可看到裡面有個struts-plugin.xml,開啟即可看到json-default是繼承了struts-default:
接下來我配置<result>,name是剛剛action返回的字串,type一定要配成json。然後就是result中的引數了,首先必須要配的就是name為root的引數,這個引數要配成剛剛需要轉換的HashMap物件,即我們定義的pageMap,有了這個引數的配置,struts才會將pageMap中的資料打包成json格式。然後就是配置黑名單,黑名單的意思就是告訴struts在打包的時候,哪些欄位不需要打包,比如管理員密碼之類的資訊,由上面註釋中的jason格式可以看出rows[0].account.pass表示密碼欄位,但是資料肯定不止一條,所以我們得用正則表示式來表示,這樣所有密碼都不會被打包到json中。
5. 修改query.jsp內容
到此,我們已經將資料打包成了json格式了,接下來我們完善一下前臺query.jsp的內容就可以讓DataGrid正確顯示了:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <%@ include file="/public/head.jspf" %> 6 <script type="text/javascript"> 7 $(function(){ 8 $('#dg').datagrid({ 9 //url地址改為請求categoryAction 10 url:'category_queryJoinAccount.action', 11 loadMsg:'Loading......', 12 queryParams:{type:''},//type引數,這裡不需要傳具體的type,因為我們要顯示所有的 13 //width:300, 14 fitColumns:true, 15 striped:true, 16 nowrap:true, 17 singleSelect:true, 18 pagination:true, 19 rowStyler: function(index,row){ 20 console.info("index" + index + "," + row) 21 if(index % 2 == 0) { 22 return ''; 23 } else { 24 return ''; 25 } 26 27 }, 28 frozenColumns:[[ 29 {field:'checkbox',checkbox:true}, 30 {field:'id',title:'編號',width:200} //這裡的field欄位要和json資料中的一樣 31 ]], 32 columns:[[ 33 {field:'type',title:'類別名稱',width:100, //欄位type 34 formatter: function(value,row,index){ 35 return "<span title=" + value + ">" + value + "</span>"; 36 } 37 }, 38 {field:'hot',title:'熱賣',width:100, //欄位hot 39 formatter: function(value,row,index){ 40 if(value) { //如果是hot,該值為true,value是boolean型變數 41 return "<input type='checkbox' checked='checked' disabled='true'"; //勾選 42 } else { 43 return "<input type='checkbox' disable='true'"; //不勾選 44 } 45 } 46 }, 47 {field:'account.login',title:'所屬管理員',width:200, //account.login管理員登入名 48 formatter: function(value,row,index){ 49 if(row.account != null && row.account.login != null) { 50 return row.account.login; //如果登入名不為空,顯示登入名 51 } else { 52 return "此類別沒有管理員"; 53 } 54 } 55 } 56 ]] 57 }); 58 }); 59 </script> 60 </head> 61 62 <body> 63 <table id="dg"></table> 64 </body> 65 </html>
6. 測試顯示結果
最後我們測試一下DataGrid的顯示結果,如下:
到這裡,我們成功整合了Struts2和json,現在可以和前臺傳輸json格式的資料了。
轉自:https://blog.csdn.net/eson_15/article/details/51332758
上一節我們完成了DataGrid顯示jason資料,但是沒有和後臺聯絡在一起,只是單純地顯示了我們自己弄的json資料,這一節我們將json和Struts2整合,打通EasyUI和Struts2之間的互動。
1. json環境的搭建
json環境搭建很簡單,匯入json的jar包即可,如下:
---------------------
作者:eson_15
來源:CSDN
原文:https://blog.csdn.net/eson_15/article/details/51332758?utm_source=copy
版權宣告:本文為博主原創文章,轉載請附上博文連結!
2. 完善Action
在DataGrid控制元件中有個屬性是url,可以指定請求資料的url地址,在上一節我們將這個地址直接設定成了一個具體的json檔案,這裡我們將這個url設定成一個action,如url:'category_queryJoinAccount.action',表示會去請求categoryAction的queryJoinAccount方法(文章最後會給出query.jsp的程式碼)。所以我們需要去完成categoryAction中的queryJoinAccount方法。
在Struts2和json整合前,我們先看一下之前顯示一次json資料都發了哪些請求:
因為type是Category類的一個屬性,我們在BaseAction中已經實現了ModelDriven<Category>介面,所以這個type會被封裝到model中,我們不需要管它,可以通過model來獲取,但是EasyUI自動發過來的page和rows引數我們需要自己獲取了,所以我們可以在BaseModel中增加兩個成員變數page和rows並實現get和set方法,最後還要考慮一點,這些引數都獲得了後,我們根據這些引數去資料庫中查詢資料,那麼我們查出來的資料放到哪呢?而且還要打包成json格式發到前臺才能被DataGrid顯示。我們先不考慮將查詢到的資料如何打包成json格式,我們先考慮把這些資料放到一個地方,很自然的想到了使用Map,因為json格式的資料就是key-value形式的。想到這裡,我們繼續完善BaseAction:
1 @Controller("baseAction") 2 @Scope("prototype") 3 public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> { 4 5 //page和rows和分頁有關,pageMap存放查詢的資料,然後打包成json格式用的 6 //page和rows實現get和set方法,pageMap只需要實現get方法即可,因為pageMap不是接收前臺引數的,是讓struts獲取的 7 protected Integer page; 8 protected Integer rows; 9 protected Map<String, Object> pageMap = null;//讓不同的Action自己去實現 10 //省略get和set方法…… 11 12 /******************* 下面還是原來BaseAction部分 *************************/ 13 //service物件 14 @Resource 15 protected CategoryService categoryService; 16 @Resource 17 protected AccountService accountService; 18 19 //域物件 20 protected Map<String, Object> request; 21 protected Map<String, Object> session; 22 protected Map<String, Object> application; 23 24 @Override 25 public void setApplication(Map<String, Object> application) { 26 this.application = application; 27 } 28 @Override 29 public void setSession(Map<String, Object> session) { 30 this.session = session; 31 } 32 @Override 33 public void setRequest(Map<String, Object> request) { 34 this.request = request; 35 } 36 37 //ModelDriven 38 protected T model; 39 @Override 40 public T getModel() { 41 ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass(); 42 Class clazz = (Class)type.getActualTypeArguments()[0]; 43 try { 44 model = (T)clazz.newInstance(); 45 } catch (Exception e) { 46 throw new RuntimeException(e); 47 } 48 return model; 49 } 50 }
好,完善了BaseCategory後,我們可以寫categoryAction中的queryJoinAccount方法了,我們將categoryAction中原來的方法全刪掉,因為那些都是之前搭建環境時候測試用的,都不用了,現在真正開始專案程式碼了:
1 @Controller("categoryAction") 2 @Scope("prototype") 3 public class CategoryAction extends BaseAction<Category> { 4 5 public String queryJoinAccount() { 6 7 //用來儲存分頁的資料 8 pageMap = new HashMap<String, Object>(); 9 10 //根據關鍵字和分頁的引數查詢相應的資料。這個方法我們在Service中寫過了,當時完成級聯查詢 11 List<Category> categoryList = categoryService.queryJoinAccount(model.getType(), page, rows); 12 pageMap.put("rows", categoryList); //儲存為JSON格式,從上一節的json檔案可以看出,一個key是total,一個key是rows,這裡先把rows存放好 13 //根據關鍵字查詢總記錄數 14 Long total = categoryService.getCount(model.getType()); //這個方法沒寫,我們等會兒去Service層完善一下 15 // System.out.println(total); 16 pageMap.put("total", total); //儲存為JSON格式,再把total存放好 17 18 return "jsonMap"; 19 } 20 }
這樣Action我們就寫好了,現在Action拿到前臺傳來的引數,然後根據引數查詢了指定type的總記錄數,以及指定type的所有商品,並且按照json中指定的key(即total和rows)進行存放,放在HashMap中了,之後只要將這個HashMap中的資料打包成json格式傳送到前臺就可以被DataGrid顯示了。我們先把這個HashMap放這,先去完善了Service層的程式碼後,再來打包這個HashMap中的資料。
3. 完善categoryService
從上面的categoryAction中可知,需要在categoryService中增加一個getCount方法,並且要在具體實現類中實現好,實現如下:
1 //CategoryService介面 2 public interface CategoryService extends BaseService<Category> { 3 //查詢類別資訊,級聯管理員 4 public List<Category> queryJoinAccount(String type, int page, int size); //使用類別的名稱查詢 5 //根據關鍵字查詢總記錄數 6 public Long getCount(String type); 7 } 8 9 //CategoryServiceImpl實現類 10 @SuppressWarnings("unchecked") 11 @Service("categoryService") 12 public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService { 13 14 @Override 15 public List<Category> queryJoinAccount(String type, int page, int size) { 16 String hql = "from Category c left join fetch c.account where c.type like :type"; 17 return getSession().createQuery(hql) 18 .setString("type", "%" + type + "%") 19 .setFirstResult((page-1) * size) //從第幾個開始顯示 20 .setMaxResults(size) //顯示幾個 21 .list(); 22 } 23 24 @Override 25 public Long getCount(String type) { 26 String hql = "select count(c) from Category c where c.type like :type"; 27 return (Long) getSession().createQuery(hql) 28 .setString("type", "%" + type + "%") 29 .uniqueResult(); //返回一條記錄:總記錄數 30 } 31 }
到現在為止,這個資料庫中資料的獲取這條路就打通了,前面兩步完成了從前臺-->資料庫-->取資料,接下來就開始打包HashMap中存放的資料,然後發給前臺了。
4. 配置struts.xml
在struts.xml中通過配置就可以完成對指定資料的打包,我們先看一下struts.xml中的配置:
1 <struts> 2 3 <constant name="struts.devMode" value="true" /> 4 5 <package name="shop" extends="json-default"><!-- jason-default繼承了struts-default --> 6 7 <global-results> 8 <result name="aindex">/WEB-INF/main/aindex.jsp</result> 9 </global-results> 10 11 <!-- class對應的是Spring中配置該Action的id值,因為要交給Spring管理 --> 12 <action name="category_*" class="categoryAction" method="{1}"> 13 <!-- 必須要先新增json包,然後上面繼承json-default --> 14 <result name="jsonMap" type="json"> 15 <!-- 要轉換成json物件的資料 --> 16 <param name="root">pageMap</param> 17 <!-- 配置黑名單,過濾不需要的選項 ,支援正則表示式 18 json格式:{total:3,rows:[{account:{id:2,login:"user",name:"客服A",pass:"user"},hot:true,id:3,…}]} 19 --> 20 <param name="excludeProperties"> 21 <!-- rows[0].account.pass--> 22 <!-- 這裡顯示不了正則表示式, CSDN的一個bug,我接個圖放下面 --> 23 </param> 24 </result> 25 </action> 26 27 <action name="account_*" class="accountAction" method="{1}"> 28 <result name="index">/index.jsp</result> 29 </action> 30 31 <!-- 用來完成系統 請求轉發的action,所有的請求都交給execute--> 32 <action name="send_*_*" class="sendAction"> 33 <result name="send">/WEB-INF/{1}/{2}.jsp</result> 34 </action> 35 </package> 36 37 </struts>
從上面的配置可以看出,首先package要繼承json-default,因為json-default繼承了struts-default,因為在json的jar包裡有個struts2-json-plugin-2.3.24.1.jar,開啟即可看到裡面有個struts-plugin.xml,開啟即可看到json-default是繼承了struts-default:
接下來我配置<result>,name是剛剛action返回的字串,type一定要配成json。然後就是result中的引數了,首先必須要配的就是name為root的引數,這個引數要配成剛剛需要轉換的HashMap物件,即我們定義的pageMap,有了這個引數的配置,struts才會將pageMap中的資料打包成json格式。然後就是配置黑名單,黑名單的意思就是告訴struts在打包的時候,哪些欄位不需要打包,比如管理員密碼之類的資訊,由上面註釋中的jason格式可以看出rows[0].account.pass表示密碼欄位,但是資料肯定不止一條,所以我們得用正則表示式來表示,這樣所有密碼都不會被打包到json中。
5. 修改query.jsp內容
到此,我們已經將資料打包成了json格式了,接下來我們完善一下前臺query.jsp的內容就可以讓DataGrid正確顯示了:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <%@ include file="/public/head.jspf" %> 6 <script type="text/javascript"> 7 $(function(){ 8 $('#dg').datagrid({ 9 //url地址改為請求categoryAction 10 url:'category_queryJoinAccount.action', 11 loadMsg:'Loading......', 12 queryParams:{type:''},//type引數,這裡不需要傳具體的type,因為我們要顯示所有的 13 //width:300, 14 fitColumns:true, 15 striped:true, 16 nowrap:true, 17 singleSelect:true, 18 pagination:true, 19 rowStyler: function(index,row){ 20 console.info("index" + index + "," + row) 21 if(index % 2 == 0) { 22 return ''; 23 } else { 24 return ''; 25 } 26 27 }, 28 frozenColumns:[[ 29 {field:'checkbox',checkbox:true}, 30 {field:'id',title:'編號',width:200} //這裡的field欄位要和json資料中的一樣 31 ]], 32 columns:[[ 33 {field:'type',title:'類別名稱',width:100, //欄位type 34 formatter: function(value,row,index){ 35 return "<span title=" + value + ">" + value + "</span>"; 36 } 37 }, 38 {field:'hot',title:'熱賣',width:100, //欄位hot 39 formatter: function(value,row,index){ 40 if(value) { //如果是hot,該值為true,value是boolean型變數 41 return "<input type='checkbox' checked='checked' disabled='true'"; //勾選 42 } else { 43 return "<input type='checkbox' disable='true'"; //不勾選 44 } 45 } 46 }, 47 {field:'account.login',title:'所屬管理員',width:200, //account.login管理員登入名 48 formatter: function(value,row,index){ 49 if(row.account != null && row.account.login != null) { 50 return row.account.login; //如果登入名不為空,顯示登入名 51 } else { 52 return "此類別沒有管理員"; 53 } 54 } 55 } 56 ]] 57 }); 58 }); 59 </script> 60 </head> 61 62 <body> 63 <table id="dg"></table> 64 </body> 65 </html>
6. 測試顯示結果
最後我們測試一下DataGrid的顯示結果,如下:
到這裡,我們成功整合了Struts2和json,現在可以和前臺傳輸json格式的資料了。