how2j.cn


5分29秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器

步骤 1 : 页面效果   
步骤 2 : MVC 设计思想   
步骤 3 : list()方法   
步骤 4 : 服务端跳转   
步骤 5 : listCategory.jsp   

首先访问

http://127.0.0.1:8080/tmall/admin_category_list

观看页面效果
页面效果
根据 MVC设计模式的思想,做J2EE web应用,从MVC的角度来看,就是把不同的数据显示在不同的页面上。

数据就是 模型 ( bean, dao )
页面就是 视图 ( jsp )
控制不同的模型显示在不同的视图上,这件事,就是由控制器来完成 ( servlet )

所以分类管理,从MVC的角度来看,就是把多条分类Category数据放在一个集合里, 让listCategory.jsp 这个视图去显示出来。
MVC 设计思想
完整的J2EE模仿天猫项目,使用J2SE、前端技术(包含所有前端jsp文件)、J2EE一整套技术栈, 从无到有涵盖全部147个知识点,475个开发步骤, 充实J2EE项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
根据filter+servlet的设计模式,访问地址

http://127.0.0.1:8080/tmall/admin_category_list

会导致CategoryServlet的list方法被调用。
根据MVC 设计思想,CategoryServlet充当的是C-控制器的角色
那么在list()方法里做的事情是,取出数据,并且交由jsp显示。

第二行: 通过categoryDAO取得数据集合 cs
第六行: 通过request.setAttribute 放在 “thecs" 这个key中,为后续服务端跳转到jsp之后使用。
第九行:return "admin/listCategory.jsp"; 服务端跳转到视图listCategory.jsp页面。

注: CategoryServlet的list()方法中可以直接使用categoryDAO,是因为其父类BaseBackServlet在属性中声明了

protected CategoryDAO categoryDAO = new CategoryDAO();

作为BaseBackServlet的子类,CategoryServlet可以直接使用该protected 修饰的属性

除此之外,list里还有page对象,这是关于分页功能的,将在分页中单独讲解。
public String list(HttpServletRequest request, HttpServletResponse response, Page page) { List<Category> cs = categoryDAO.list(page.getStart(),page.getCount()); int total = categoryDAO.getTotal(); page.setTotal(total); request.setAttribute("thecs", cs); request.setAttribute("page", page); return "admin/listCategory.jsp"; }
	public String list(HttpServletRequest request, HttpServletResponse response, Page page) {
		List<Category> cs = categoryDAO.list(page.getStart(),page.getCount());
		int total = categoryDAO.getTotal();
		page.setTotal(total);
		
		request.setAttribute("thecs", cs);
		request.setAttribute("page", page);
		
		return "admin/listCategory.jsp";
	}
完整的J2EE模仿天猫项目,使用J2SE、前端技术(包含所有前端jsp文件)、J2EE一整套技术栈, 从无到有涵盖全部147个知识点,475个开发步骤, 充实J2EE项目经验,为简历加上一个有吸引力的砝码.
增值内容,点击购买
list()方法返回字符串 "admin/listCategory.jsp" 就导致服务端跳转到了页面 "admin/listCategory.jsp"。
为什么返回这个字符串,就可以实现服务端跳转呢? 在servlet中进行服务端跳转不是要如下代码格式吗?

request.getRequestDispatcher("xxx.jsp").forward(request, response);

这个就要结合CategoryServlet的父类BaseBackServlet来理解了。
在BaseBackServlet的70行,在借助反射机制调用了list()方法之后,获取返回值redirect.

如果redirect是以@开头的字符串,那么就进行客户端跳转
如果redirect是以%开头的字符串,那么就直接输出字符串
如果都不是,则进行服务端跳转
String redirect = m.invoke(this,request, response,page).toString(); /*根据方法的返回值,进行相应的客户端跳转,服务端跳转,或者仅仅是输出字符串*/ if(redirect.startsWith("@")) response.sendRedirect(redirect.substring(1)); else if(redirect.startsWith("%")) response.getWriter().print(redirect.substring(1)); else request.getRequestDispatcher(redirect).forward(request, response);
String redirect = m.invoke(this,request, response,page).toString();
			
			/*根据方法的返回值,进行相应的客户端跳转,服务端跳转,或者仅仅是输出字符串*/
			
			if(redirect.startsWith("@"))
				response.sendRedirect(redirect.substring(1));
			else if(redirect.startsWith("%"))
				response.getWriter().print(redirect.substring(1));
			else
				request.getRequestDispatcher(redirect).forward(request, response);
最后就是视图listCategory.jsp了。
JSP包含关系中已经讲解过了listCategory.jsp中包含的jsp文件,这里就不做赘述。
本步骤就关注在listCategory.jsp主体内容是如何工作的。
作为视图,担当的角色是显示数据。所以关键就是从第44行开始,借助JSTL的c:forEach标签遍历从CategoryServlet的list() 的request.setAttribute("thecs", cs); 传递过来的集合。


<c:forEach items="${thecs}" var="c">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@include file="../include/admin/adminHeader.jsp"%> <%@include file="../include/admin/adminNavigator.jsp"%> <script> $(function(){ $("#addForm").submit(function(){ if(!checkEmpty("name","分类名称")) return false; if(!checkEmpty("categoryPic","分类图片")) return false; return true; }); }); </script> <title>分类管理</title> <div class="workingArea"> <h1 class="label label-info" >分类管理</h1> <br> <br> <div class="listDataTableDiv"> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr class="success"> <th>ID</th> <th>图片</th> <th>分类名称</th> <!-- <th>属性管理</th> --> <!-- <th>产品管理</th> --> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> <c:forEach items="${thecs}" var="c"> <tr> <td>${c.id}</td> <td><img height="40px" src="img/category/${c.id}.jpg"></td> <td>${c.name}</td> <%-- <td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td> --%> <%-- <td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td> --%> <td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td> <td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td> </tr> </c:forEach> </tbody> </table> </div> <div class="pageDiv"> <%@include file="../include/admin/adminPage.jsp" %> </div> <div class="panel panel-warning addDiv"> <div class="panel-heading">新增分类</div> <div class="panel-body"> <form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data"> <table class="addTable"> <tr> <td>分类名称</td> <td><input id="name" name="name" type="text" class="form-control"></td> </tr> <tr> <td>分类圖片</td> <td> <input id="categoryPic" accept="image/*" type="file" name="filepath" /> </td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <button type="submit" class="btn btn-success">提 交</button> </td> </tr> </table> </form> </div> </div> </div> <%@include file="../include/admin/adminFooter.jsp"%>


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2024-06-25 关于拦截器与过滤器执行顺序
iu不错

我分别在BackServletFilter.class中的doFilter()方法、BaseBackServlet.class中的service()方法和httpServlet.class中的service()方法添加断点, 在访问http://127.0.0.1:8080/tmall/admin_category_list调试时,断点先来到doFilter()方法, (因为BaseBackServlet.class是继承于httpServlet.class的,我的理解是放行后应该去执行httpServlet.class中的service()方法)。 可是 放行后直接跳到BaseBackServlet.class中的service()方法而不是去执行httpServlet.class中的service()方法, 这是什么原因呢?







回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2019-12-25 String redirect = m.invoke(this,request, response,page).toString(); 站长大大为什么要用toString()方法呢?
LZPsss

如题。。m.invoke(this,request, response,page);这句代码已经执行了CateforyServlet的list()方法,不是会返回一个String吗?为什么要在后面加一个toString()呢。。求解,感谢!!




3 个答案

LZPsss
答案时间:2019-12-26
String redirect = (String) m.invoke(this, request,response,page); 大佬们,那请问可以写成上面的样子吗?
String redirect = (String) m.invoke(this, request,response,page);

how2j
答案时间:2019-12-26
@Paul_Frank 顶

Paul_Frank
答案时间:2019-12-25
m.invoke()返回的是Object类型的



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2019-10-27 CSS代码是要自己写吗
2019-09-27 checkEmpty("name","分类名称")是什么意思?
2019-08-03 关于File类


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 12 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 实践项目-天猫整站J2EE-查询 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图