Java實作CRM項目過程中的細節記錄(二)
文章目錄
- Java實作CRM項目過程中的細節記錄(二)
-
- 一、線索子產品
-
- 1. 伺服器緩存
- 2. 監聽器
- 2. Spring管理JUnit
- 3. 當其它子產品已經有該功能的時候
- 4. 模态視窗中敲回車
- 二、交易子產品
-
- 1. 細節
-
- (1)web元件不往service層傳遞
- (2)native2ascii.exe工具
- (3)當從背景跳到前台頁面時
- (4)及時break
- (5)實體類中添加字段
- 2. 封裝工具類
- 3. 自動補全插件(typeahead)
- 3. ECharts可視化圖表插件
- 三、打包
-
- 1. linux系統項目中亂碼問題的解決
- 2. 打包的問題
上一篇:Java實作CRM項目過程中的細節記錄(一)
一、線索子產品
1. 伺服器緩存
-
什麼是伺服器緩存?
緩存:記憶體中的資料
浏覽器緩存:浏覽器記憶體中儲存的以前的伺服器做出的響應
伺服器緩存:儲存在伺服器記憶體中的資料
-
伺服器緩存通常都儲存些什麼?
一般來講,伺服器緩存就是用來儲存資料字典的,因為資料字典資料量大,而且值不是很容易發生變化。
-
處理伺服器緩存的最佳時機?
web開發三大元件:(
(Servlet
)、controller
、Filter
),這3個元件對象,是由Listener
伺服器幫我們維護的,一般把這些類寫在web包中,如監聽器在包中的位置:Tomcat
com.company.crm.web.listener.Listener.java
。
通過監聽器,監聽上下文(全局域)對象的建立,當
對象建立完畢後,監聽器中的application
方法就執行了,我們就可以在這個contextInitialized()
方法中将所有的資料字典值取出,将他們儲存到contextInitialized()
域對象中。所謂的伺服器緩存其實就是往application
application
域對象中存值。
将資料字典值儲存到
域對象中的過程,就是将資料字典儲存到伺服器記憶體中,産生緩存的過程。application
2. 監聽器
-
在監聽器中,我們需要使用到資料字典的業務層對象,而使用spring配置監聽器,再注入service是不行的
以下寫法是錯誤的:
public class SysInitListener implements ServletContextListener {
//這種寫法是錯誤的,因為監聽器對象是由Tomcat管理的,而Autowired是Spring才能實作自動注入
@Autowired
private DicService dicService;//null
@Override
public void contextInitialized(ServletContextEvent sce) {
//雖然new出來的service不是null,但是這個service中的dao也使用了自動注入,是以為null
DicServiceImpl dicService = new DicServiceImpl();
}
}
- 我們需要使用
工具類,該工具類的作用是擷取到WebApplicationContextUtils
容器的引用,進而擷取到我們需要的spring
執行個體bean
- 注意:配置監聽器時的上下順序:
- Spring提供監聽器(
)配置在上方,先由ContextLoaderListener
容器建立好spring
service
- 因為我們自定義的監聽器(
)要用到Spring,是以要配置在Spring監聽器的下方,再由SysInitListener
容器引用tomcat
對象service
- 擴充:
中三大web元件的一般配置順序:先web.xml
,然後是Filter
,最後是Listener
。特殊:字元集過濾器(Servlet
)要放在最後CharacterEncodingFilter
- Spring提供監聽器(
2. Spring管理JUnit
關于命名(要遵守駝峰命名法):
- 測試類的命名:子產品名(domain)+Test
- 方法的命名:test+功能
子產品:
- 一般都是對業務層進行測試,我們應該每完成一個業務功能,就應該對這個業務功能編寫一份單元測試方法,在測試方法上加
@Test
斷言(
Assert
):
- 表示測試的結果取得之後,要和我們提供的一個預期的結果進行比較,如果比較二者的值是相同的,測試成功,否則測試失敗
由Spring去管理JUnit,來進行單元測試:
- 在測試類上加上下面兩個注解,就可以在測試類中加入自動注入
Service
@RunWith(SpringJUnit4ClassRunner.class)//表示由spring去管理JUnit,來進行單元測試 @ContextConfiguration("classpath:spring/applicationContext.xml")
3. 當其它子產品已經有該功能的時候
功能(方法)一緻,也不能在這個子產品引用别的子產品,無形中增加了耦合度,
4. 模态視窗中敲回車
模态視窗中敲回車時,會強制重新整理頁面,通過
return false;
阻止頁面重新整理
$("#e").keydown(function (event) {
if (event.keyCode == 13) {
//do something
return false;
}
});
二、交易子產品
1. 細節
(1)web元件不往service層傳遞
session是web層的元件,使用在控制層,别往service層傳遞
(2)native2ascii.exe工具
java JDK bin 目錄下的工具
native2ascii.exe
可以将漢字轉為
ascii
碼(/uxxxx)
(3)當從背景跳到前台頁面時
正常流程:伺服器通路
toIndex.do
(沒有處理任何資料,單純傳回了一個位址)--------------->
index.jsp
當另一個請求
save.do
儲存完畢後要跳到
index.jsp
,這個時候有兩個選擇,為了之後的可維護性,要請求轉發到
toIndex.do
,再跳到
index.jsp
。
解釋:雖然現在
toIndex.do
中沒有做任何處理,隻是傳回了一個頁面,但日後可能會添加處理,那麼
save.do
就可以不用管了
(4)及時break
在循環查找時,如果找到了,就即時break
(5)實體類中添加字段
當某個字段在資料庫中不存在,但是又經常跟該實體類一起使用時,可以在實體類中添加該字段,一般多添加(與資料庫表字段不同)的字段不超過三個
2. 封裝工具類
當出現我們自己明明知道傳進來的是什麼類,但是卻不能調用其方法的時候,可以用反射
//這個工具類的作用是設定實體類的id、建立時間和建立人
public class SetUtil {
//形參分别是建立人名字,實體類對象,實體類簡單類名(因為實作類的位置相對固定,就在工具類中指定了實體類的包名)
public static void setWorkbench(String name, Object obj, String className) {
className = "com.bjpowernode.crm.workbench.domain." + className;
same(name, obj, className);
}
public static void setSettings(String name, Object obj, String className) {
className = "com.bjpowernode.crm.settings.domain." + className;
same(name, obj, className);
}
private static void same(String name, Object obj, String className) {
String id = UUIDUtil.getUUID();
String time = DateTimeUtil.getSysTime();
try {
Class c = Class.forName(className);
Method setId = c.getMethod("setId", String.class);
Method setCreateBy = c.getMethod("setCreateBy", String.class);
Method setCreateTime = c.getMethod("setCreateTime", String.class);
setId.invoke(obj, id);
setCreateBy.invoke(obj, name);
setCreateTime.invoke(obj, time);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 自動補全插件(typeahead)
query
代表輸入框中你的輸入值(即查詢值),
process
回調函數。
$("#create-customerName").typeahead({
source: function (query, process) {
$.get(
"workbench/tran/getCustomerNames.do",
{"name": query},
function (data) {
//alert(data);
process(data);
},
"json"
);
},
delay: 500
});
背景要傳回一個
String
的集合,注意這個集合中的元素是
String
@RequestMapping("/getCustomerNames.do")
@ResponseBody
public List<String> getCustomerNames(String name) {
return customerService.getCustomerNames(name);
}
更詳細的說明見:Bootstrap3-typeahead 文本自動補全填充
3. ECharts可視化圖表插件
官方網址https://www.echartsjs.com/zh/index.html
官方網站上有文檔,執行個體,可以直接将代碼拿過來,然後将資料改成自己的的資料就可以了,這裡隻用到了漏鬥圖,就拿漏鬥圖來舉例
ECharts隻能用原生JS的DOM對象,不能用jQuery對象
步驟:
- 通過标簽方式直接引入建構好的 echarts 檔案
- 在繪圖前我們需要為 ECharts 準備一個具備高寬的 DOM 容器。(
)<div></div>
- 以通過
方法初始化一個echarts.init
執行個體,建立一個myChar對象echarts
- 指定圖表的配置項和資料(對于資料項中的某些資料不知道是幹啥的,可以查文檔,或者改一下這個資料看看在圖表上有啥變化)
- 通過剛建立的
對象的myChar
方法,來生成圖表setOption()
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>title</title>
<script src="jquery/jquery-1.11.1-min.js"></script>
<script src="ECharts/echarts.min.js"></script>
<script>
$(function () {
getTranChart();
})
function getTranChart() {
$.ajax({
url : "workbench/chart/transaction/getChartData.do",
type : "get",
dataType : "json",
success : function (data) {
/*
data
int max
List<Map<String,Object>> dataList
List<String> stageNameList
{
"max":100,
"dataList":[{value:100,name:"01資質審查"},{value:10,name:"02需求分析"}...],
"stageNameList" : ["01資質審查","02需求分析"....]
}
*/
//alert("繪制統計圖表");
// 基于準備好的dom,初始化echarts執行個體
//myChart:繪圖者
var myChart = echarts.init(document.getElementById('main'));
// 指定圖表的配置項和資料
//option:我們要畫的圖
var option = {
title: {
text: '交易漏鬥圖',
subtext: '統計交易階段數量的漏鬥圖'
},
legend: {
data: data.stageNameList
},
calculable: true,
series: [
{
name:'交易漏鬥圖',
type:'funnel',
left: '10%',
top: 60,
//x2: 80,
bottom: 60,
width: '80%',
// height: {totalHeight} - y - y2,
min: 0,//最小值
max: data.max, //最大值
minSize: '0%',
maxSize: '100%',
sort: 'descending',
gap: 2,
label: {
show: true,
position: 'inside'
},
labelLine: {
length: 10,
lineStyle: {
width: 1,
type: 'solid'
}
},
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
emphasis: {
label: {
fontSize: 20
}
},
//統計項,統計數量
/*
value:統計的數量
name:統計項
我們想要的資料
[{value:100,name:"01資質審查"},{value:10,name:"02需求分析"}...]
*/
data: data.dataList
/*[
{value: 60, name: '通路'},
{value: 40, name: '咨詢'},
]*/
}
]
};
// 使用剛指定的配置項和資料顯示圖表。
//繪圖者,調用一個畫圖的方法來繪制統計圖表,參數就是我們要畫的圖
myChart.setOption(option);
}
})
}
</script>
</head>
<body>
<!-- 為 ECharts 準備一個具備大小(寬高)的 DOM -->
<div id="main" style="width: 850px;height:400px;"></div>
</body>
</html>
三、打包
1. linux系統項目中亂碼問題的解決
在jdbc的properties配置檔案中,在url後加入如下參數:
jdbc.url=jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
2. 打包的問題
- 先clean将target幹掉
- 再啟動伺服器将target建立
- 關閉服務
- 最後package打war包