19-Javaweb-实战2(商品分类 分页 浏览记录 IOC)
目录
一.案例1-分类展示
1-1.步骤分析
1-1-1.创建分类表
1-1-2.在indexservlet上查询分类信息
1-1-3.调用CategoryService.findAll() 返回值是:list
1-2.信息分类展示--通过发送异步请求
1-2-0.将jsp头部分开,其他页面包含页面
1-2-1.编写一个单独的 CategorySerlvet
1-2-2.findAll方法用来查询所有
1-2-3.在head.jsp加载成功之后发送一个ajax请求
1-3.常见的缓存技术
1-4.ehcache使用步骤
1-4-1.导入jar包
1-4-2.编写配置文件-src下的ehcache(项目运行时在 classes 目录下)
1-4-3.在service中动态从缓存中获取数据-使用api-service需要序列化
二.案例2-首页上的热门商品和最新商品
2-1.步骤分析
2-1-1.在indexServlet的index方法中实现
2-1-2.页面加载的时候 加载最新商品 和 热门商品即可
2-2.准备工作
2-2-1.数据库和表
2-2-2.javabean product
三.案例3-查询单个商品的详情
3-1.步骤分析
3-1-1.在首页上 点击每个商品
3-1-2.编写 getById方法
3-1-3.商品详情页面
四.案例4-分页展示商品
4-1.步骤分析
4-1-0.pageBean
4-1-1.在菜单上 点击一个分类 head.jsp
4-1-2.findByPage操作
4-1-3.在productSerivce需要封装成pagebean
4-1-4.在product_list.jsp展示数据
五.扩展 :浏览记录
5-1.步骤分析
5-1-1.获取指定的cookie
5-1-2.判断cookie是否为空
5-1-3.在product_list.jsp需要将cookie里面的商品展示出来
六.解耦合-ioc
一.案例1-分类展示
最初的设计
点击首页的时候,查询分类信息
1-1.步骤分析
1-1-1.创建分类表
CREATE TABLE `category` (
`cid` varchar(32) NOT NULL,
`cname` varchar(20) DEFAULT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `category` VALUES ('1','手机数码'),('172934bd636d485c98fd2d3d9cccd409','运动户外'),('2','电脑办公'),('3','家具家居'),('4','鞋靴箱包'),('5','图书音像'),('59f56ba6ccb84cb591c66298766b83b5','aaaa'),('6','母婴孕婴'),('afdba41a139b4320a74904485bdb7719','汽车用品');
import java.io.Serializable;/*** 分类实体* @author Administrator**/ public class Category implements Serializable {private String cid;private String cname;public String getCid() {return cid;}public void setCid(String cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}}
1-1-2.在indexservlet上查询分类信息
import java.io.IOException;
import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 和首页相关的servlet*/
public class IndexServlet extends BaseServlet {public String index(HttpServletRequest request, HttpServletResponse response) {//去数据库中查询最新商品和热门商品 将他们放入request域中 请求转发ProductService ps=(ProductService) BeanFactory.getBean("ProductService");//最新商品List<Product> newList=null;List<Product> hotList=null;try {newList = ps.findNew();hotList=ps.findHot();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//热门商品//将俩个list放入域中request.setAttribute("nList", newList);request.setAttribute("hList", hotList);return "/jsp/index.jsp";}}
1-1-3.调用CategoryService.findAll() 返回值是:list
public class CategoryServiceImpl implements CategoryService {/*** 查询所有的分类*/@Overridepublic List<Category> findAll() throws Exception {//从数据库中获取CategoryDao cd=new CategoryDaoImpl();return cd.findAll();}
}
1-2.信息分类展示--通过发送异步请求
完成之后 ,我们发现只有在访问首页的时候才能把分类列表展示出来,怎么办?????
要想让所有的页面上都有分类,只需要将 页面上 logo和菜单部分包含进来.怎么去查询分类信息呢????
只需要在页面加载成功之后 发送一个ajax请求 异步查询所有的分类信息即可
技术:
json
包含
ajax
步骤分析:
1-2-0.将jsp头部分开,其他页面包含页面
- 静态包含
<!-- 静态包含 --><%@include file="/jsp/head.jsp" %>
- 动态包含
<!-- 动态包含 --><jsp:include page="/jsp/head.jsp"></jsp:include>
1-2-1.编写一个单独的 CategorySerlvet
- 导入jar包
- 添加 JsonUtils
import java.util.List; import java.util.Map;import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import net.sf.json.util.CycleDetectionStrategy; import net.sf.json.xml.XMLSerializer;/*** 处理json数据格式的工具类* * @Date 2013-3-31* @version 1.0*/ public class JsonUtil {/*** 将数组转换成String类型的JSON数据格式* * @param objects* @return*/public static String array2json(Object[] objects){JSONArray jsonArray = JSONArray.fromObject(objects);return jsonArray.toString();}/*** 将list集合转换成String类型的JSON数据格式* * @param list* @return*/public static String list2json(List list){JSONArray jsonArray = JSONArray.fromObject(list);return jsonArray.toString();}/*** 将map集合转换成String类型的JSON数据格式* * @param map* @return*/public static String map2json(Map map){JSONObject jsonObject = JSONObject.fromObject(map);return jsonObject.toString();}/*** 将Object对象转换成String类型的JSON数据格式* * @param object* @return*/public static String object2json(Object object){JSONObject jsonObject = JSONObject.fromObject(object);return jsonObject.toString();}/*** 将XML数据格式转换成String类型的JSON数据格式* * @param xml* @return*/public static String xml2json(String xml){JSONArray jsonArray = (JSONArray) new XMLSerializer().read(xml);return jsonArray.toString();}/*** 除去不想生成的字段(特别适合去掉级联的对象)** @param excludes* @return*/public static JsonConfig configJson(String[] excludes) {JsonConfig jsonConfig = new JsonConfig();jsonConfig.setExcludes(excludes);jsonConfig.setIgnoreDefaultExcludes(true);jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);return jsonConfig;}}
import java.io.IOException; import java.util.List;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class CategoryServlet*/ public class CategoryServlet extends BaseServlet {/*** 查询所有的分类*/public String findAll(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 1.调用categoryservice 查询所有的分类 返回值listCategoryService cs = CategoryServicImpl();List<Category> clist = null;try {clist = cs.findAll();} catch (Exception e) {e.printStackTrace();}// 2.将返回值转成json格式 返回到页面上//request.setAttribute("clist", clist);//放入request域中String json = JsonUtil.list2json(clist);//3.写回去response.setContentType("text/html;charset=utf-8");response.getWriter().println(json);return null;}}
1-2-2.findAll方法用来查询所有
list通过json返回到页面上
1-2-3.在head.jsp加载成功之后发送一个ajax请求
$.get(url,params,function(data){},"json");
- 为ul标签添加id值
<ul id="menuId" class="nav navbar-nav"><%-- <c:forEach items="${clist }" var="c"><li><a href="#">${c.cname }</a></li></c:forEach> --%></ul>
- 遍历数组,写内容
<script>$(function(){//发送ajax请求$.get("${pageContext.request.contextPath}/category?method=findAll",function(data){//获取menu的ul标签-----为其添加id值var $ul=$("#menuId");//遍历数组$(data).each(function(){$ul.append($("<li><a href='${pageContext.request.contextPath}/product?method=findByPage&cid="+this.cid+"&currPage=1'>"+this.cname+"</a></li>"));});},"json");}); </script>
上面的操作我们已经可以在每个页面上查看到分类信息了,但是只要换一次页面就会查询一下数据库,增加服务器的压力,
对于数据不常变化的情况,我们可以使用缓存技术
1-3.常见的缓存技术
ehcache:今天用,hibernate中底层使用了ehcache
memcache
redis
1-4.ehcache使用步骤
1-4-1.导入jar包
1-4-2.编写配置文件-src下的ehcache(项目运行时在 classes 目录下)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><diskStore path="C:/ehcache"/><cachename="categoryCache"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"maxElementsOnDisk="10000000"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"/><!--默认缓存配置,以下属性是必须的:name :cache的标识符,在一个CacheManager中必须唯一。maxElementsInMemory : 在内存中缓存的element的最大数目。maxElementsOnDisk : 在磁盘上缓存的element的最大数目。eternal : 设定缓存的elements是否有有效期。如果为true,timeouts属性被忽略。overflowToDisk : 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上。以下属性是可选的:timeToIdleSeconds : 缓存element在过期前的空闲时间。timeToLiveSeconds : 缓存element的有效生命期。diskPersistent : 在VM重启的时候是否持久化磁盘缓存,默认是false。diskExpiryThreadIntervalSeconds : 磁盘缓存的清理线程运行间隔,默认是120秒.memoryStoreEvictionPolicy : 当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略。默认是LRU,可选的有LFU和FIFO--> </ehcache>
在service中获取文件路径(见 day9) D:\Tomcat8.5.40\wtpwebapps\test1\WEB-INF\classes
public static void main(String[] args) {InputStream is = CategoryServiceImpl.class.getClassLoader().getResourceAsStream("ehcache.xml");System.out.println(is);}
1-4-3.在service中动态从缓存中获取数据-使用api-service需要序列化
获取数据先从缓存中获取
若获取的值为空
再去查询数据库,
将数据放入缓存中public class CategoryServiceImpl implements CategoryService {/*** 查询所有的分类*/@Overridepublic List<Category> findAll() throws Exception {//1.创建缓存管理器CacheManager cm=CacheManager.create(CategoryServiceImpl.class.getClassLoader().getResourceAsStream("ehcache.xml"));//2.获取指定的缓存Cache cache = cm.getCache("categoryCache");//3.通过缓存获取数据 将cache看成一个map即可Element element = cache.get("clist");List<Category> list=null;//4.判断数据if(element==null){//从数据库中获取CategoryDao cd=(CategoryDao) BeanFactory.getBean("CategoryDao");list=cd.findAll();//将list放入缓存cache.put(new Element("clist", list));System.out.println("缓存中没有数据,已去数据库中获取");}else{//直接返回list=(List<Category>) element.getObjectValue();System.out.println("缓存中有数据");}return list;}public static void main(String[] args) {InputStream is = CategoryServiceImpl.class.getClassLoader().getResourceAsStream("ehcache.xml");System.out.println(is);}}
二.案例2-首页上的热门商品和最新商品
2-1.步骤分析
2-1-1.在indexServlet的index方法中实现
页面加载的时候 查询最新商品 和 热门商品即可
查询的结果两个list,将两个list放入request域中,请求转发到index.jsp即可
在index.jsp中展示/*** 和首页相关的servlet*/ public class IndexServlet extends BaseServlet {public String index(HttpServletRequest request, HttpServletResponse response) {//去数据库中查询最新商品和热门商品 将他们放入request域中 请求转发//ProductService ps=new ProductServiceImpl();ProductService ps=(ProductService) BeanFactory.getBean("ProductService");//最新商品List<Product> newList=null;List<Product> hotList=null;try {newList = ps.findNew();hotList=ps.findHot();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//热门商品//将俩个list放入域中request.setAttribute("nList", newList);request.setAttribute("hList", hotList);return "/jsp/index.jsp";}}
/*** 查询最新*/@Overridepublic List<Product> findNew() throws Exception {ProductDao pdao=(ProductDao) BeanFactory.getBean("ProductDao");return pdao.findNew();}/*** 查询热门*/@Overridepublic List<Product> findHot() throws Exception {ProductDao pdao=(ProductDao) BeanFactory.getBean("ProductDao");return pdao.findHot();}
/*** 查询最新*/@Overridepublic List<Product> findNew() throws Exception {QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());String sql="select * from product order by pdate desc limit 9";return qr.query(sql, new BeanListHandler<>(Product.class));}/*** 查询热门*/@Overridepublic List<Product> findHot() throws Exception {QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());String sql="select * from product where is_hot = 1 order by pdate desc limit 9";return qr.query(sql, new BeanListHandler<>(Product.class));}
2-1-2.页面加载的时候 加载最新商品 和 热门商品即可
<div class="container-fluid"><div class="col-md-12"><h2>热门商品 <img src="${pageContext.request.contextPath}/img/title2.jpg"/></h2></div><div class="col-md-2" style="border:1px solid #E7E7E7;border-right:0;padding:0;"><img src="${pageContext.request.contextPath}/products/hao/big01.jpg" width="205" height="404" style="display: inline-block;"/></div><div class="col-md-10"><div class="col-md-6" style="text-align:center;height:200px;padding:0px;"><a href="#"><img src="${pageContext.request.contextPath}/products/hao/middle01.jpg" width="516px" height="200px" style="display: inline-block;"></a></div><c:forEach items="${hList }" var="p"><div class="col-md-2" style="text-align:center;height:200px;padding:10px 0px;"><a href="${pageContext.request.contextPath }/product?method=getById&pid=${p.pid}"><img src="${pageContext.request.contextPath}/${p.pimage}" width="130" height="130" style="display: inline-block;"></a><p><a href="${pageContext.request.contextPath }/product?method=getById&pid=${p.pid}" style='color:#666'>${fn:substring(p.pname,0,10) }...</a></p><p><font color="#E4393C" style="font-size:16px">¥${p.shop_price }</font></p></div></c:forEach></div>
</div><div class="container-fluid"><div class="col-md-12"><h2>最新商品 <img src="${pageContext.request.contextPath}/img/title2.jpg"/></h2></div><div class="col-md-2" style="border:1px solid #E7E7E7;border-right:0;padding:0;"><img src="${pageContext.request.contextPath}/products/hao/big01.jpg" width="205" height="404" style="display: inline-block;"/></div><div class="col-md-10"><div class="col-md-6" style="text-align:center;height:200px;padding:0px;"><a href="product_info.htm"><img src="${pageContext.request.contextPath}/products/hao/middle01.jpg" width="516px" height="200px" style="display: inline-block;"></a></div><c:forEach items="${nList }" var="p"><div class="col-md-2" style="text-align:center;height:200px;padding:10px 0px;"><a href="${pageContext.request.contextPath }/product?method=getById&pid=${p.pid}"><img src="${pageContext.request.contextPath}/${p.pimage}" width="130" height="130" style="display: inline-block;"></a><p><a href="${pageContext.request.contextPath }/product?method=getById&pid=${p.pid}" style='color:#666'>${fn:substring(p.pname,0,10) }...</a></p><p><font color="#E4393C" style="font-size:16px">¥${p.shop_price }</font></p></div></c:forEach></div>
</div>
2-2.准备工作
2-2-1.数据库和表
CREATE TABLE `product` (
`pid` varchar(32) NOT NULL,
`pname` varchar(50) DEFAULT NULL,
`market_price` double DEFAULT NULL,
`shop_price` double DEFAULT NULL,
`pimage` varchar(200) DEFAULT NULL,
`pdate` date DEFAULT NULL,
`is_hot` int(11) DEFAULT NULL,
`pdesc` varchar(255) DEFAULT NULL,
`pflag` int(11) DEFAULT NULL,
`cid` varchar(32) DEFAULT NULL,
PRIMARY KEY (`pid`),
KEY `sfk_0001` (`cid`),
CONSTRAINT `sfk_0001` FOREIGN KEY (`cid`) REFERENCES `category` (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `product` VALUES ('1','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02',1,'小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待',0,'1')
2-2-2.javabean product
/*** 商品实体* @author Administrator**/ public class Product implements Serializable{/*** `pid` VARCHAR(32) NOT NULL,`pname` VARCHAR(50) DEFAULT NULL,`market_price` DOUBLE DEFAULT NULL,`shop_price` DOUBLE DEFAULT NULL,`pimage` VARCHAR(200) DEFAULT NULL,`pdate` DATE DEFAULT NULL,`is_hot` INT(11) DEFAULT NULL,`pdesc` VARCHAR(255) DEFAULT NULL,`pflag` INT(11) DEFAULT NULL,`cid` VARCHAR(32) DEFAULT NULL,*/private String pid;private String pname;private Double market_price;private Double shop_price;private String pimage;private Date pdate;private Integer is_hot=0;//是否热门 1:热门 0:否private String pdesc;private Integer pflag=0;//是否下架 1:下架 0:未下架//属于那个分类private Category category;
三.案例3-查询单个商品的详情
3-1.步骤分析
3-1-1.在首页上 点击每个商品
<a href="/store/product?method=getById&pid=${p.pid}">....</a>
<p><a href="${pageContext.request.contextPath }/product?method=getById&pid=${p.pid}" style='color:#666'>${fn:substring(p.pname,0,10) }...</a></p>
3-1-2.编写 getById方法
获取点击商品的pid
调用service查找商品 返回值 :Product
将product放入request域中,请求转发 product_info.jsp/*** 商品servlet*/ public class ProductServlet extends BaseServlet {private static final long serialVersionUID = 1L;/*** 通过id查询单个商品详情* @throws Exception */public String getById(HttpServletRequest request, HttpServletResponse response) throws Exception {//1.获取商品的idString pid=request.getParameter("pid");//2.调用service//ProductService ps=new ProductServiceImpl();ProductService ps=(ProductService) BeanFactory.getBean("ProductService");Product p=ps.getByPid(pid);//3.将结果放入request中 请求转发request.setAttribute("bean", p);return "/jsp/product_info.jsp";}
3-1-3.商品详情页面
<div class="col-md-6">
<div><strong>${bean.pname }</strong></div>
<div style="border-bottom: 1px dotted #dddddd;width:350px;margin:10px 0 10px 0;"><div>编号:${bean.pid }</div>
</div><div style="margin:10px 0 10px 0;">商城价: <strong style="color:#ef0101;">¥:${bean.shop_price }元/份</strong> 参 考 价: <del>¥${bean.market_price }元/份</del>
</div><div style="margin:10px 0 10px 0;">促销: <a target="_blank" title="限时抢购 (2014-07-30 ~ 2015-01-01)" style="background-color: #f07373;">限时抢购</a> </div><div style="padding:10px;border:1px solid #e7dbb1;width:330px;margin:15px 0 10px 0;;background-color: #fffee6;"><div style="margin:5px 0 10px 0;">白色</div><div style="border-bottom: 1px solid #faeac7;margin-top:20px;padding-left: 10px;">购买数量:<input id="quantity" name="quantity" value="1" maxlength="4" size="10" type="text"> </div><div style="margin:20px 0 10px 0;;text-align: center;"><a href="cart.htm"><input style="background: url('${pageContext.request.contextPath}/images/product.gif') no-repeat scroll 0 -600px rgba(0, 0, 0, 0);height:36px;width:127px;" value="加入购物车" type="button"></a> 收藏商品</div>
</div>
</div>
四.案例4-分页展示商品
按类别 分页展示
4-1.步骤分析
4-1-0.pageBean
import java.util.List;public class PageBean<E> {private List<E> list;private Integer currPage;private Integer pageSize;private Integer totalPage;//无set,get 需要计算private Integer totalCount;public List<E> getList() {return list;}public void setList(List<E> list) {this.list = list;}public Integer getCurrPage() {return currPage;}public void setCurrPage(Integer currPage) {this.currPage = currPage;}public Integer getPageSize() {return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}public Integer getTotalPage() {return (int)Math.ceil(totalCount*1.0/pageSize);}public Integer getTotalCount() {return totalCount;}public void setTotalCount(Integer totalCount) {this.totalCount = totalCount;}public PageBean() { }public PageBean(List<E> list, Integer currPage, Integer pageSize, Integer totalCount) {//添加没有 totalPage的构造器super();this.list = list;this.currPage = currPage;this.pageSize = pageSize;this.totalCount = totalCount;}}
4-1-1.在菜单上 点击一个分类 head.jsp
<a href="/store/product?method=findByPage&cid=${}&currPage=1"></a>
<script>$(function(){//发送ajax请求$.get("${pageContext.request.contextPath}/category?method=findAll",function(data){//获取menu的ul标签var $ul=$("#menuId");//遍历数组$(data).each(function(){$ul.append($("<li><a href='${pageContext.request.contextPath}/product?method=findByPage&cid="+this.cid+"&currPage=1'>"+this.cname+"</a></li>"));});},"json");}); </script>
4-1-2.findByPage操作
1.接受 cid currPage 设定一个每页显示的条数 pageSize
2.调用productSerivce 返回一个PageBean
pageBean中
list currPage pageSize totalPage totalCount
3.将pagebean放入request域中,请求转发/*** 分页查询数据* @param request* @param response* @return* @throws Exception*/public String findByPage(HttpServletRequest request, HttpServletResponse response) throws Exception {//1.获取类别 当前页 设置一个pagesizeString cid=request.getParameter("cid");int currPage=Integer.parseInt(request.getParameter("currPage"));int pageSize=12;//2.调用service 返回值pagebeanProductService ps=(ProductService) BeanFactory.getBean("ProductService");PageBean<Product> bean=ps.findByPage(currPage,pageSize,cid);//3.将结果放入request中 请求转发request.setAttribute("pb", bean);return "/jsp/product_list.jsp";}
4-1-3.在productSerivce需要封装成pagebean
/*** 按类别分页查询商品*/@Overridepublic PageBean<Product> findByPage(int currPage, int pageSize, String cid) throws Exception {ProductDao pdao=(ProductDao) BeanFactory.getBean("ProductDao");//当前页数据List<Product> list=pdao.findByPage(currPage,pageSize,cid);//总条数int totalCount = pdao.getTotalCount(cid);return new PageBean<>(list, currPage, pageSize, totalCount);}
/*** 查询当前也需要展示的数据*/@Overridepublic List<Product> findByPage(int currPage, int pageSize, String cid) throws Exception {QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());String sql="select * from product where cid = ? limit ?,?";return qr.query(sql, new BeanListHandler<>(Product.class), cid,(currPage-1)*pageSize,pageSize);}/*** 查询当前类别的总条数*/@Overridepublic int getTotalCount(String cid) throws Exception {QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());String sql="select count(*) from product where cid = ?";return ((Long)qr.query(sql, new ScalarHandler(), cid)).intValue();}
4-1-4.在product_list.jsp展示数据
<c:forEach items="${pb.list }" var="p"><div class="col-md-2"><a href="${pageContext.request.contextPath}/product?method=getById&pid=${p.pid}"><img src="${pageContext.request.contextPath}/${p.pimage}" width="170" height="170" style="display: inline-block;"></a><p><a href="${pageContext.request.contextPath}/product?method=getById&pid=${p.pid}" style='color:green'>${fn:substring(p.pname,0,10) }...</a></p><p><font color="#FF0000">商城价:¥${p.shop_price }</font></p></div> </c:forEach>
分页:获取Cid---el内置对象param获取 连接的cid
<!--分页 --> <div style="width:380px;margin:0 auto;margin-top:50px;"> <ul class="pagination" style="text-align:center; margin-top:10px;"><!-- 判断当前页是否是首页 --><c:if test="${pb.currPage == 1 }"><li class="disabled"><a href="javascript:void(0)" aria-label="Previous"><span aria-hidden="true">«</span></a></li></c:if><c:if test="${pb.currPage != 1 }"><li><a href="${pageContext.request.contextPath}/product?method=findByPage&currPage=${pb.currPage-1}&cid=${param.cid}" aria-label="Previous"><span aria-hidden="true">«</span></a></li></c:if><!-- 展示所有页码 --><c:forEach begin="${pb.currPage-5>0?pb.currPage-5:1 }" end="${pb.currPage+4>pb.totalPage?pb.totalPage:pb.currPage+4 }" var="n"><!-- 判断是否是当前页 --><c:if test="${pb.currPage==n }"><li class="active"><a href="javascript:void(0)">${n }</a></li></c:if><c:if test="${pb.currPage!=n }"><li><a href="${pageContext.request.contextPath}/product?method=findByPage&currPage=${n}&cid=${param.cid}">${n }</a></li></c:if></c:forEach><!-- 判断是否是最后一页 --><c:if test="${pb.currPage == pb.totalPage }"><li class="disabled"><a href="javascript:void(0)" aria-label="Next"><span aria-hidden="true">»</span></a></li></c:if><c:if test="${pb.currPage != pb.totalPage }"><li><a href="${pageContext.request.contextPath}/product?method=findByPage&currPage=${pb.currPage+1}&cid=${param.cid}" aria-label="Next"><span aria-hidden="true">»</span></a></li></c:if></ul> </div> <!-- 分页结束======================= -->
五.扩展 :浏览记录
技术分析:cookie
5-1.步骤分析
进入一个商品详情页面的时候需要记录当前的商品id
<a href="/store/product?method=getById&pid=xxxx"></a>
我们需要在 getById这个方法中处理cookie
规定 cookie的名称:ids value: 2-1-3
5-1-1.获取指定的cookie
CookieUtils.getCookieByName()
里面的实现:
通过request.getCookies()先获取cookie数组,然后遍历cookie,通过cookie的名称判断
if("ids".equals(cookie.getName)){return cookie;}
5-1-2.判断cookie是否为空
若不为空:获取value值
继续判断value值中有无该商品的id(将字符串切割转成list)
若有:
先移除,然后将商品id放入list的最前面
若没有:
继续判断list的长度是否>=3
若>=3:移除最后一个,将当前商品的id放入list的最前面
若<=:将当前商品的id放入list的最前面
最后将list变成字符串即可
若为空:
将当前商品的id放入ids中即可
Cookie c=new Cookie("ids",ids);
c.setMaxAge(int 秒);
c.setPath(request.getContextPath+"/");
response.addCookie(c);
5-1-3.在product_list.jsp需要将cookie里面的商品展示出来
1.需要在jsp中获取指定cookie
2.判断cookie是否为空
若不为空:获取value 例如:value=1-3-2
切割字符串获取每一个商品的id
通过id去数据库中查找,获取商品的所有信息
六.解耦合-ioc
在ProductService中,调用dao
ProductDao pDao=new ProductDaoImpl()
这里的dao是通过dbutils实现的curd,现在我们学习了 hibernate,
我们编写productDaoHibImpl()
然后在service中需要修改之前的代码
修改成
ProductDao pDao=new productDaoHibImpl()
为了解决耦合,我们可以使用工厂模式
可以通过
ProductDao pDao=beanfactory.getProductDao();
我希望作一个通用的方式,不需要修改任何java代码就可以随意的修改dao层的实现类(修改配置文件):
例如:配置文件名称为 bean.xml 内容如
<?xml version="1.0" encoding="UTF-8"?> <beans><bean id="CategoryService" class="com.itheima.service.impl.CategoryServiceImpl"></bean><bean id="ProductService" class="com.itheima.service.impl.ProductServiceImpl"></bean><bean id="UserService" class="com.itheima.service.impl.UserServiceImpl"></bean><bean id="ProductDao" class="com.itheima.dao.impl.ProductDaoImpl"/><bean id="UserDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="CategoryDao" class="com.itheima.dao.impl.CategoryDaoImpl"/> </beans>
工厂类如下:(工具类)
解析xml标签:通过xpath
思路: 通过参数给定的id去bean.xml文件中查找id为指定值的bean标签,获取bean标签的class属性
通过 Class.forName(class的属性值).newInstance();
以后修改实现类的时候,只需要将指定的bean标签中的class变化一下即可,java代码不需要改变,这样就可以实现解耦了
import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader;/*** 实体工厂类* @author Administrator**/ public class BeanFactory {/*** 通过给定一个id返回一个指定的实现类* @param id* @return*/public static Object getBean(String id){//通过id获取一个指定的实现类try {//1.获取document对象Document doc=new SAXReader().read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));//2.获取指定的bean对象 xpathElement ele=(Element) doc.selectSingleNode("//bean[@id='"+id+"']");//3.获取bean对象的class属性String value = ele.attributeValue("class");//4.反射 return Class.forName(value).newInstance();} catch (Exception e) {e.printStackTrace();}return null;}public static void main(String[] args) {System.out.println(getBean("ProductDao"));;} }
19-Javaweb-实战2(商品分类 分页 浏览记录 IOC)相关推荐
- 机器学习实战中的函数学习记录
title: 机器学习实战中的函数学习记录 date: 2020-05-01 09:20:50 tags: [python函数] categories: 机器学习实战 更多内容请关注我的博客 记录机器 ...
- JavaWeb实战教程(Servlet+JSP+JavaBean)-雷伟-专题视频课程
JavaWeb实战教程(Servlet+JSP+JavaBean)-1401人已学习 课程介绍 本课程主要介绍Jsp,Servlet基础知识,讲解Jsp+Servlet+JavaBea ...
- javaweb的struts2的分页查询操作
javaweb的struts2的分页查询操作 分页查询的实现: 1.利用action完成 action有成员变量: 除了实体对象的属性还有 // 分页显示 public int totalRecord ...
- javaweb利用struts2完成批量删除记录
javaweb利用struts2框架完成批量删除 实现方式思路**(mvc设计模式): 后台查询实现后:(未附代码,自写) 1.在前端使用ognl表达式对checkbox的name属性等于记录的唯一i ...
- QQ 正在尝试读取你的浏览记录?这是“火绒拦截腾讯产品,腾讯道歉”的历史重现吗?
QQ 正在尝试读取你的浏览记录 近日,一篇题目为<QQ 正在尝试读取你的浏览记录>引发了网友们广泛关注,内容是网友 @mengyx 在使用 QQ 时,为了防止一些流氓行为,特地去的 MS ...
- ICCV2017 论文浏览记录(转)
mark一下,感谢作者分享! 作者将ICCV2017上的论文进行了汇总,在此记录下来,平时多注意阅读积累. 之前很早就想试着做一下试着把顶会的论文浏览一遍看一下自己感兴趣的,顺便统计一下国内高校或者研 ...
- ICCV2017 论文浏览记录
之前很早就想试着做一下试着把顶会的论文浏览一遍看一下自己感兴趣的,顺便统计一下国内高校或者研究机构的研究方向,下面是作为一个图像处理初学者在浏览完论文后的 觉得有趣的文章: ICCV2017 论文浏览 ...
- JavaWeb实战项目-登录审批功能-付强-专题视频课程
JavaWeb实战项目-登录审批功能-134人已学习 课程介绍 在eclipse中进行web开发,熟练掌握HTML.Javaspript.CSS.JSP.Servlet.Oracle. ...
- 【01】网页中清除历史浏览记录能不能彻底删除浏览记录?
不能-- 即便你把记录全删了,也可用数据恢复工具给你找回来: 即便你用专业工具覆盖N遍,确保数据无法恢复,网站那头还记着哪个ip什么时候访问过哪些内容呢--然后跑ISP(联通或电信)一查,xx时间xx ...
最新文章
- Matlab中plot函数全功能解析
- java约瑟夫环 循环链表_约瑟夫环_循环链表JAVA解答
- SpringCloud采坑之Feign服务间调用默认返回xml
- 不会做特征工程的 AI 研究员不是好数据科学家!上篇 - 连续数据的处理方法 本文作者:s5248 编辑:杨晓凡 2018-01-19 11:32 导语:即便现代机器学习模型已经很先进了,也别
- 阿里数据产品经理工作(总结篇):数据PD,做牛做马
- java jtable刷新_使用Swing timer实现Jtable数据定时更新
- python cos函数_Python Tensorflow cos()用法及代码示例
- 兄弟连mysql数据库_兄弟连学python-------MySQL数据库基础知识
- php openssl.so加载,LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)...
- HTML图片热点及表单
- jsp与jspx文件
- iOS开发 - 关于微信分享后,提示“未验证应用”的解决办法,配置 Universal Link
- 【ARM开发】交叉编译Qt源码之(4)添加xcb支持
- 微信支付 H5端 和小程序端 统一下单接口 4个JAVA源码文件代码
- 详解旨在提升EVM底层性能的兼容公链Monad
- 【PTA~21年GPLT团体程序天梯赛-L1题】
- Android中使用OKHttp上传图片,从相机和相册中获取图片并剪切
- STM32F4+DP83848以太网通信指南系列知识储备
- AliOS Things 网络适配框架 - SAL
- 家乐福618保卫战二-零售O2O场景中的万级并发交易情况下的极限性能调优
热门文章
- 10种提高SketchUp运行速度的方式,必看!
- python3.6环境下安装gevent,附协程TCP服务器客户端代码
- 微模块数据中心这么火,你知道多少?
- llc谐振闭环电路基于simulink
- 狗叫翻译软件测试,用狗语翻译器,狗狗听得出是真的假的吗
- matlab h面分贝方向图,天线技术实验报告.doc
- Flink如何保证数据的一致性
- 走好脚下的路--写给迷茫的计算机专业在校生
- 在arm开发板上实现播放内存里所有的jpg和bmp格式图片
- 【Linux】Linux系统编程(入门与系统编程)(三)(深入理解操作系统、进程、环境变量、内存分布)