这是第一次做项目,跟着B站动力节点的CRM项目做的,从中收获了很多东西,里面一些我觉得有用的东西将它记录在此。随便写的,可能很乱,主要是我自己看
前端使用了bootstrap框架,后端用到了mybatis。纯新手小白。记录学习的东西
项目后端结构(搭建相关的domain,dao,service,controller)
1.1 一些相关的工具类,日后可能会用到
1、获取系统当前时间(年月日时分秒)
public class DateTimeUtil {
public static String getSysTime(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String dateStr = sdf.format(date);
return dateStr;
}
}
2、MD5加密
public class MD5Util {
public static String getMD5(String password) {
try {
// 得到一个信息摘要器
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] result = digest.digest(password.getBytes());
StringBuffer buffer = new StringBuffer();
// 把每一个byte 做一个与运算 0xff;
for (byte b : result) {
// 与运算
int number = b & 0xff;// 加盐
String str = Integer.toHexString(number);
if (str.length() == 1) {
buffer.append("0");
}
buffer.append(str);
}
// 标准的md5加密后的结果
return buffer.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
}
}
}
3、将数据转换为JSON格式(将boolean值转换为json值和将对象解析为json值)
public class PrintJson {
//将boolean值解析为json串
public static void printJsonFlag(HttpServletResponse response, boolean flag){
Map<String,Boolean> map = new HashMap<String,Boolean>();
map.put("success",flag);
ObjectMapper om = new ObjectMapper();
try {
//{"success":true}
String json = om.writeValueAsString(map);
response.getWriter().print(json);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//将对象解析为json串
public static void printJsonObj(HttpServletResponse response,Object obj){
/*
*
* Person p
* id name age
* {"id":"?","name":"?","age":?}
*
* List<Person> pList
* [{"id":"?","name":"?","age":?},{"id":"?","name":"?","age":?},{"id":"?","name":"?","age":?}...]
*
* Map
* key value
* {key:value}
*
*
*/
ObjectMapper om = new ObjectMapper();
try {
String json = om.writeValueAsString(obj);
response.getWriter().print(json);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4、ServiceFactory
public class ServiceFactory {
public static Object getService(Object service){
return new TransactionInvocationHandler(service).getProxy();
}
}
5、SqlSessionUtil
public class SqlSessionUtil {
private SqlSessionUtil(){}
private static SqlSessionFactory factory;
static{
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
factory =
new SqlSessionFactoryBuilder().build(inputStream);
}
private static ThreadLocal<SqlSession> t = new ThreadLocal<SqlSession>();
public static SqlSession getSqlSession(){
SqlSession session = t.get();
if(session==null){
session = factory.openSession();
t.set(session);
}
return session;
}
public static void myClose(SqlSession session){
if(session!=null){
session.close();
t.remove();
}
}
}
6、TransactionInvocationHandler
public class TransactionInvocationHandler implements InvocationHandler{
private Object target;
public TransactionInvocationHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession session = null;
Object obj = null;
try{
session = SqlSessionUtil.getSqlSession();
obj = method.invoke(target, args);
session.commit();
}catch(Exception e){
session.rollback();
e.printStackTrace();
//处理的是什么异常,继续往上抛什么异常
throw e.getCause();
}finally{
SqlSessionUtil.myClose(session);
}
return obj;
}
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
}
7、生成UUID
public class UUIDUtil {
public static String getUUID(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
2、对于web.xml文件中的url-pattern
=
/abc/myServlet.do
/abc/*
/*
*.do
/abc/*.do 错误
abc/*.do 错误
3、键盘事件
$(window).keydown(function(event){
// event只是一个变量名,随意编写,是一个引用,指向了一个事件对象,所 有的键盘事件对象都有一个keyCode属性,用来获取键值。
if(event.keyCode == 13){ // 回车键是13
login();
}
});
4、过滤器
登录验证的过滤器。
所有用户必须登录之后才能访问该web资源。
拦截什么?
*.do
*.jsp
不拦截什么?
/login.jsp
/login.do
5、顶层窗口
使login.jsp始终在顶层窗口中打开
关键代码:
if(window.top!=window){
window.top.location=window.location;
}
6、怎么让下拉列表默认选中某一项?
怎么让下拉列表默认选中某一项?
$("#grade").val("2");
<select id="grade">
<option value="1">高中</option>
<option value="2">专科</option>
<option value="3">本科</option>
</select>
7、bootstrap日历控件的引入
引用bootstrap datetimepicker插件的步骤:
(1)引入jQuery的库
(2)引入bootstrap的库
(3)引入datetimepicker的css库和js库(注意引入先后顺序)
<link rel="stylesheet" type="text/css" href="jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css">
<script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script>
<script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js"></script>
(4)设置time类属性
$(".time").datetimepicker({
language: "zh-CN",
format: "yyyy-mm-ddhh:ii:ss",//显示格式
minView: "hour",//设置只显示到月份
initialDate: new Date(),//初始化当前日期
autoclose: true,//选中自动关闭
todayBtn: true, //显示今日按钮
clearBtn : true,
pickerPosition: "bottom-left"
});
$(".time").datetimepicker({
minView: "month",
language: 'zh-CN',
format: 'yyyy-mm-dd',
autoclose: true,
todayBtn: true,
pickerPosition: "bottom-left"
});
(5)在相关组件的class下引入time类标识
例如:
class = "form-control time"
8、分页查询的实现
前端处理:
1、动态展现列表数据
2、使用pagination分页插件
(1)导入pagination插件相关css和js
<link rel="stylesheet" type="text/css" href="jquery/bs_pagination/jquery.bs_pagination.min.css">
<script type="text/javascript" src="jquery/bs_pagination/jquery.bs_pagination.min.js"></script>
<script type="text/javascript" src="jquery/bs_pagination/en.js"></script>
(2)在列表下面导入分页组件div(将原有默认分页div去掉)
<div id="activityPage"></div>
(3)在pageList.do处理ajax返回值后,加入分页组件
$("#activityPage").bs_pagination({
currentPage: pageNo, // 页码
rowsPerPage: pageSize, // 每页显示的记录条数
maxRowsPerPage: 20, // 每页最多显示的记录条数
totalPages: totalPages, // 总页数
totalRows: data.total, // 总记录条数
visiblePageLinks: 3, // 显示几个卡片
showGoToPage: true,
showRowsPerPage: true,
showRowsInfo: true,
showRowsDefaultInfo: true,
onChangePage : function(event, data){
pageList(data.currentPage , data.rowsPerPage);
}
});
处理总页数totalPages
(4)调用分页插件
例如点击查询按钮(注意:查询按钮需要设施type="button")
$("#searchBtn").click(function(){
pageList(1 ,$("#activityPage").bs_pagination('getOption', 'rowsPerPage'));
});
(5)js中对于totalPages的处理
vartotalPages = data.total%pageSize==0 ? data.total/pageSize :parseInt(data.total/pageSize)+1;
(6)ajax对于时间戳的加入
cache : false
更新后,在哪一页还回到哪一页
关键代码
pageList($("#activityPage").bs_pagination('getOption', 'currentPage')
,$("#activityPage").bs_pagination('getOption', 'rowsPerPage'));
9、复选框的全选和取消全选的实现
使用jQuery实现。
重点1:jQuery支持多个元素一块处理。很多地方是不需要使用each遍历的。
重点2:为后期ajax动态生成的元素绑定事件,必须用on。
10、一些零碎的记忆
转发与重定向
当往request域中绑定数据后,使用转发。其他地方全部使用重定向
转发: 使用的是一种特殊的绝对路径的使用方式,这种绝对路径前面不加 /项目名 ,这种路径也称之为内部路径/login.jsp 重定向: 使用的是传统绝对路径的写法,前面必须以/项目名开始,后面跟具体的资源路径/crm/login.jsp 为什么使用重定向,使用转发不行吗? 转发之后,路径会停留在老路径上,不是跳转之后的新路径 我们应该在为用户跳转到登录页的同时,将浏览器的地址栏应该自动设置为当前的登录页的路径
上下文域
/* 该方法是用来监听上下文域对象的方法,当服务器启动,上下文域对象创建 对象创建完毕后,马上执行该方法 event:该参数能够取得监听的对象 监听的是什么对象,就可以通过该参数能取得什么对象 例如我们现在监听的是上下文域对象,通过该参数就可以取得上下文域对象 */ public void contextInitialized(ServletContextEvent event)