想把目前的项目优化一下,增加些用户体验.得知了Pjax.在网上看了很多例子,也看了官方文档.可是直接到项目里却处处碰壁.决定重新写个demo.网上的坑也比较复杂,所以我直接引用官方的写法.
本人的环境是spring mvc 使用的是Jsp.
新建两个jsp页面,test_mian_page.jsp和test_include_page.jsp.
test_mian_page.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'MyJsp.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<div>第一页</div>
<div>第二页</div>
<div id="loadpage"></div>
<a href="/include" οnclick="javascript:void(0)">点击我</a>
<script type="text/javascript" src="assets/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/jquery.pjax.js"></script>
<script type="text/javascript">
$(document).pjax('a','#loadpage');
</script>
</body>
</html>
test_include_page.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
This is my JSP page. <br>
<script type="text/javascript" src="assets/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/jquery.pjax.js"></script>
<script type="text/javascript">
$(function(){
console.log("加载进来了");
})
</script>
test_include_page.jsp中是没有<html><head><body>的,经测试如果是完整的页面,pjax会发送两个请求,一个是内部ajax请求,一个则会跳转页面,即直接进入目标页面,不是我想要的结果.
后端PjaxController:
@Controller
public class PjaxController {
@RequestMapping("/mian")
public String getMain(){
return "test_mian_page";
}
@RequestMapping("/include")
public String getInclude(HttpServletRequest request){
return "test_mian_page";
}
}
后端代码比较简单,直接返回页面名称就可以了.当运行起来后你会发现,点击前进后退是没有问题的,因为pjax已经使用history中pushState保存了状态.(但由于这属于html5属性,坑爹的项目应用环境及其简陋,所以只能放弃使用pjax,掀桌子有木有!).
当点击"刷新"时,你会懵逼,这特么是要放弃的节奏么?!没关系,Pjax会在Request中Head里塞入"X-PJAX":true,你只要获取一下就能判断是否是pjax请求了.所以扩展一下:
@RequestMapping("/include")
public String getInclude(HttpServletRequest request){
String str = request.getHeader("X-PJAX");
if("true".equals(str)){
return "test_include_page";
}
return "test_mian_page";
}
这样就可以刷新了,不过效果可能不是很理想.那么我的解决方案是在session中存好每次访问的页面,当刷新时,通过读取该session进行pjax请求访问.当然这只是方案,并没有得到证实(这是我上班的时候写的,怕被逼逼就没有继续证实了).
如果各位同人有实现了的,请告知一声,谢谢.
中午抽时间弄了下,按照上面所说的方案,基本能满足要求,上代码:
public class GlobalValue {
//获取session
public static HttpSession GetSession() {
HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
session.setMaxInactiveInterval(60*60*6);
return session;
}
public synchronized static void setUrl(String url){
GetSession().setAttribute("RefreshUrl", url);
}
public synchronized static String getUrl(){
return (String) GetSession().getAttribute("RefreshUrl");
}
}
这个类就不多说了.
接下来是test_main_page.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'MyJsp.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<div>第一页</div>
<div>第二页</div>
<div id="loadpage"></div>
<a href="/include" οnclick="javascript:void(0)">点击我</a>
<script type="text/javascript" src="assets/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/jquery.pjax.js"></script>
<script type="text/javascript">
$(document).pjax('a','#loadpage');
$(function(){
var url = "";
url = "${RefreshUrl}";
if(url!=""){
$.pjax.reload('#loadpage', url)
}
})
</script>
</body>
</html>
接下来是Controller
@RequestMapping("/main")
public String getMain(){
GlobalValue.setUrl("");
return "test_mian_page";
}
@RequestMapping("/include")
public String getInclude(HttpServletRequest request){
String str = request.getHeader("X-PJAX");
if("true".equals(str)){
GlobalValue.setUrl("");
return "test_include_page";
}
GlobalValue.setUrl("/include");
return "test_mian_page";
}
那么现在就差不多了,如果有更好的方法,麻烦留言或者联系我,谢谢