版本01:
先说下整体思路:
在这里只列举部分代码,IndexServlet代码如下:
package cn.itcast.store.web.servlet;
import cn.itcast.store.domain.Category;
import cn.itcast.store.service.CategoryService;
import cn.itcast.store.service.serviceImp.CategoryServiceImp;
import cn.itcast.store.web.base.BaseServlet;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IndexServlet extends BaseServlet {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
//调用业务层获取全部分类数据
CategoryService categoryService=new CategoryServiceImp();
List<Category> list = categoryService.getAllCats();
//将全部分类信息放入request
request.setAttribute("allCats", list);
// 转发到真实的首页/jsp/index.jsp
return "/jsp/index.jsp";
}
}
为什么这里要使用execute()方法。看一下父类BaseServlet中,如果method为null,就执行execute()方法。
Servlet层代码处理完毕,现在开始处理jsp页面了。代码如下:
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse"
id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav" id="myUL">
<c:forEach items="${allCats}" var="c">
<li><a href="#">${c.cname}</a></li>
</c:forEach>
</ul>
访问http://localhost:8080/store_v5/,发现首页上分类信息确实是从数据中取出来的
1.2优化:Ajax 异步加载
1.2.1 分析
当访问首页时可以显示分类导航条,但访问其他模块时无法访问显示分类。通过比较程序我们 发现,显示首页前我们查询了所有分类,显示登录等其他模块时我们没有查询分类。为了所有模块 都可以显示分类,我们需要发送 ajax 单独查询分类。
1.2.2代码实现:
步骤 1:修改 IndexServlet,将查询分类代码注释
步骤 2:修改 header.jsp 给<ul>添加 id,并注释查询所有的遍历内容
<ul class="nav navbar-nav" id="myUL">
<%-- <c:forEach items="${allCats}" var="c">
<li><a href="#">${c.cname}</a></li>
</c:forEach> --%>
</ul>
步骤 3:修改 header.jsp 添加 js 函数,页面加载发送 ajax 查询所有分类
<script type="text/javascript">
/* 向服务端发送ajax请求,服务端经过处理,将所有分类的信息已json格式返回,
获取到所有的返回的所有分类绑定在页面的显示分类区域
*/
$(function() {
var url="${pageContext.request.contextPath}/CategoryServlet?method=findAllCats";
/*var url="/store_v5/CategoryServlet";
var obj={"method":"findAllCats"}; */
$.post(url,function(data){
// console.log(data);
//获取到服务端响应的数据,观察发现data中存放的是json格式的数组,遍历数组,动态的显示分类区域的代码
$.each( data, function(i, obj){
var li="<li><a href='#'>"+obj.cname+"</a></li>" ;
$("#myUL").append(li);
})
},
"json"
);
});
</script>
步骤 4:编写 CategoryServlet,提供 findAllCats()方法
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.store.domain.Category;
import cn.itcast.store.service.CategoryService;
import cn.itcast.store.service.serviceImp.CategoryServiceImp;
import cn.itcast.store.utils.JedisUtils;
import cn.itcast.store.web.base.BaseServlet;
import net.sf.json.JSONArray;
import redis.clients.jedis.Jedis;
public class CategoryServlet extends BaseServlet {
public String findAllCats(HttpServletRequest request, HttpServletResponse response) throws Exception{
//调用业务层获取全部分类数据
CategoryService categoryService=new CategoryServiceImp();
List<Category> list = categoryService.getAllCats();
//将集合list转换为json
String jsonStr=JSONArray.fromObject(list).toString();
//将全部分类信息响应到客户端
//告诉浏览器响应的是json格式
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(jsonStr);
return null;
}
}
步骤 5:web.xmlservlet 的配置
<servlet>
<servlet-name>CategoryServlet</servlet-name>
<servlet-class>cn.itcast.store.web.servlet.CategoryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CategoryServlet</servlet-name>
<url-pattern>/CategoryServlet</url-pattern>
</servlet-mapping>
1.3增强:缓存技术
1.3.1 分析
当我们在不同模块之间切换时,发现菜单栏显示的分类数据都是一样的。浏览器每发送一次请 求,服务器端都会查询一次数据库,从而对数据库服务器造成不必要的访问。实际开发中,我们采用缓存技术来解决此类问题
缓存redis相关技术:
1.先运行redis-server服务(在D:\BaiduNetdiskDownload\day02__6天项目用户登录-首页分类\day02__6天项目用户登录-首页分类\day23_案例\resource)
2.打开Windows下redis的客户端:redis-cli
3. Redis工具类(将参数192.168.146.135修改为127.0.0.1)
package com.itheima.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisUtils {
//创建连接池
private static JedisPoolConfig config;
private static JedisPool pool;
static{
config=new JedisPoolConfig();
config.setMaxTotal(30);
config.setMaxIdle(2);
pool=new JedisPool(config, "192.168.146.135", 6379);
}
//获取连接的方法
public static Jedis getJedis(){
return pool.getResource();
}
//释放连接
public static void closeJedis(Jedis j){
j.close();
}
}
步骤二:代码实现
package cn.itcast.store.web.servlet;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.store.domain.Category;
import cn.itcast.store.service.CategoryService;
import cn.itcast.store.service.serviceImp.CategoryServiceImp;
import cn.itcast.store.utils.JedisUtils;
import cn.itcast.store.web.base.BaseServlet;
import net.sf.json.JSONArray;
import redis.clients.jedis.Jedis;
public class CategoryServlet extends BaseServlet {
public String findAllCats(HttpServletRequest request, HttpServletResponse response) throws Exception{
//在redis中获取分类信息
Jedis jedis = JedisUtils.getJedis();
String jsonStr=jedis.get("allCats");
if(null==jsonStr || "".equals(jsonStr)) {
//调用业务层获取全部分类数据
CategoryService categoryService=new CategoryServiceImp();
List<Category> list = categoryService.getAllCats();
//将集合list转换为json
jsonStr=JSONArray.fromObject(list).toString();
System.out.println("redis中没有缓存数据");
//将获取到的json格式字符串保存到redis中
jedis.set("allCats", jsonStr);
//将全部分类信息响应到客户端
//告诉浏览器响应的是json格式
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(jsonStr);
}else {
System.out.println("redis中有缓存数据");
//将全部分类信息响应到客户端
//告诉浏览器响应的是json格式
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(jsonStr);
}
//释放jedis
JedisUtils.closeJedis(jedis);
return null;
}
}