毕业实习项目-8

详情模块-公告详情

需要的资源

链接: https://pan.baidu.com/s/1BiSSWcxTpwF-YLH9GTGNyw .
提取码:m71z

思路

前台:

  1. 由于新闻详情、公告详情和商品详情的页面布局一样,只是显示的内容不同,为了节省工作量,可以将notice.jsp里的主要代码进行复用。所以第一步将拷贝至WebContent文件夹下的notice.jsp文件重命名为details.jsp(资源已给)
  2. details.jsp文件中动态包含notice.jsp
  3. 通过EL表达式从域对象中获取公告信息
  4. index.jsp中设置公告链接的路径

后台:

  1. 建一个NoticeServlet

  2. 接收参数id

  3. 非空判断
    空则无操作
    不空,调用service通过id查询公告详情notice

  4. 公告详情不需要一直保留在会话中,考虑服务器性能,所以将pageNamechangePagenotice存在作用域request中

  5. 请求转发跳转details.jsp

实操

  1. notice.jsp文件拷贝至WebContent文件夹下,文件重命名为details.jsp
  2. 重写details.jsp的代码

details.jsp文件更新代码

...
				<!-- 用参数pageName 来标示当前小模块标题 -->
				<title>易买网 - ${
    
    pageName }</title>
	</head>
	<body>
		<!-- 头部 -->
		<div id="header" class="wrap">
			<jsp:include page="common/top.jsp" /> 
		</div>
		<div id="position" class="wrap">
			<!-- 文字的导航 -->
			<!-- 用参数pageName 来标示当前小模块标题 -->
			您现在的位置:<a href="index">首页</a>&nbsp;&gt;&nbsp;${
    
    pageName }详情
		</div>
		<div id="main" class="wrap">
			<div class="lefter">
				<jsp:include page="common/left.jsp" />
			</div>
			
			<!-- 动态包含页面 (公告详情,新闻详情,商品详情)-->
			<!-- 用参数changePage来标示去哪个小模块的详情内容-->
    		<jsp:include page="${changePage }"></jsp:include>
			
			<div class="clear"></div>
		</div>
...
  1. WebContent文件夹下新建一个notice文件夹,并在文件夹里新建一个notice.jsp文件来专门完成公告详情代码。

notice.jsp文件代码

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
    <div class="main">
				<div id="notice" class="right-main">
					<h1>${
    
    notice.title }</h1>
					<div class="content" style="word-wrap: break-word;word-break: break-all;overflow: hidden;">
						${
    
    notice.content }
					</div>
				</div>
			</div>
  1. index.jsp文件中设置不同公告链接的路径

index.jsp文件相关更新代码

...
				<div class="side">
					<div class="news-list">
						<h4>最新公告</h4>
						<ul>
						
						<!-- 循环遍历存放最新公告信息的<li>标签,过程中动态获取最新公告信息,最多显示7-->
						<c:forEach items="${noticeList }" var="notice" end="6">
						
							<li>
							<!-- 从后台用id查公告内容,所以要向负责详情的Servlet传一个id值 -->
								<a href="notice?id=${notice.id }">${
    
    notice.title }</a>
							</li>
						
						</c:forEach>
						
						</ul>
					</div>
...
  1. 新建一个NoticeServlet
    右击com.xxx.servlet包⇥New⇥servlet⇥ClassName填写NoticeServlet⇥next⇥URL mappings栏下修改路径名为notice⇥next⇥取消勾选Constructors from supclassdoPostdoGet,勾选service⇥Finish

  2. NoticeServlet.java文件里完成功能代码

NoticeServlet.java文件代码

@WebServlet("/notice")
public class NoticeServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	
	
	//之前写过NoticeService和NoticeServiceImpl文件所以不报红,但是需要去NoticeServiceImpl文件里添加一下下面的findNoticeById方法
	private NoticeService noticeService = new NoticeServiceImpl(); 
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		
		//接收参数id
		String id = request.getParameter("id");
		
		//非空判断
		if(StringUtil.isEmpty(id)){
    
    
			
			//空则无操作
			return;
		}

		//不空,调用service通过id查询公告详情notice
		Notice notice = noticeService.findNoticeById(Integer.parseInt(id)); //findNoticeById报红添加一下方法,跳转的文件中将parseInt参数改为id
		
		//公告详情不需要一直保留在会话中,考虑服务器性能,所以将pageName、changePage和notice存在作用域request中
		
		//用户访问公告详情时标题显示公告
		request.setAttribute("pageName", "公告");
		request.setAttribute("changePage", "notice/notice.jsp");
		request.setAttribute("notice", notice);
		
		
		//请求转发跳转details.jsp
		request.getRequestDispatcher("details.jsp").forward(request, response);
		
		//写完后有报红,ctrl+shift+o先自动导一下包
	}

}

  1. NoticeServiceImpl.java文件里写一下方法代码:

NoticeServiceImpl.java文件findNoticeById方法:

...
	//写在查询公告集合方法后面
	//通过Id查询公告
	@Override
	public Notice findNoticeById(int id) {
    
    
		// TODO Auto-generated method stub
		Notice notice = null;
		Connection conn = null;
		
		//异常
		try{
    
    
			
		//数据库操作
		//建立连接
		conn = DBUtil.getConnection();
		
		//编写sql语句
		String sql = "select * from t_notice where id = ?";
		
		//new一个QueryRunner
		QueryRunner qr = new QueryRunner();
		
		//创建参数数组
		Object[] params = {
    
    id};
		
		//执行查询
		notice = qr.query(conn, sql ,new BeanHandler<>(Notice.class),params);//BeanHandler报红导一下包
		
		} catch (Exception e){
    
    
			e.printStackTrace();
		}finally{
    
    
			
			//关闭连接
			DBUtil.close(null, null, conn);
		}
		return notice;
	}
...

这样,公告详情模块就写完了。
公告一
公告二

详情模块-商品详情

思路

前台:

  1. details.jsp文件中动态包含product.jsp
  2. 通过EL表达式从域对象中获取商品信息
  3. index.jsp中设置商品链接的路径

后台:

  1. 建一个ProductServlet

  2. 判断用户行为

  3. 接收参数

  4. 非空判断
    空则无操作
    不空,调用service通过id查询商品详情product

  5. 公告详情不需要一直保留在会话中,考虑服务器性能,所以将pageNamechangePageproduct存在作用域request中

  6. 请求转发跳转details.jsp

实操

  1. WebContent文件夹下新建一个product文件夹,并在文件夹里新建一个product.jsp文件来专门完成商品详情代码。

product.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
			<div id="product"  class="main">
				<h1>${
    
    product.name }</h1>
				<div class="infos">
					<div class="thumb">
						<img class="img" src="${product.proPic }" />
					</div>
					<div class="buy">
						<br/>
						<p>
							商城价:<span class="price">${
    
    product.price }</span>
						</p>
						<p>库 存:${
    
    product.stock }</p>
						<br/>
						<div class="button">
							<input type="button" name="button" value=""/><br/>
							<a href="">放入购物车</a>
						</div>
					</div>
					<div class="clear"></div>
				</div>
				<div class="introduce">
					<h2>
						<strong>商品详情</strong>
					</h2>
					<div class="text">
						${
    
    product.description }
					</div>
				</div>
			</div>
  1. index.jsp中设置商品链接的路径

index.jsp文件相关更新代码:

...
	<h2>今日特价</h2>
					<ul class="product clearfix">
					
					<!-- 循环遍历存放今日特价商品信息的<li>标签 -->
					<c:forEach items="${specialProductList }" var="specialProduct" end="7"> 
					
						<li>
							<dl>
								<dt>
								
								<!-- 从后台用id查商品详情,所以要向负责商品详情的Servlet传一个id值 -->
									<a href="product?id=${specialProduct.id }" target="_blank"><img src="${specialProduct.proPic }" /></a>
								</dt>
								<dd class="title">
									<a href="product?id=${specialProduct.id }" target="_blank">${
    
    specialProduct.name }</a>
								</dd>
								<dd class="price">¥${
    
    specialProduct.price}</dd>
							</dl>
						</li>
						
					</c:forEach>
						
					</ul>
				</div>
				
...

					<h2>热卖推荐</h2>
					<ul class="product clearfix">
						<li>
							<dl>
								<dt>
								
								<!-- 从后台用id查商品详情,所以要向负责商品详情的Servlet传一个id值 -->
									<!-- 热卖模块留在最后写,所以这里的商品是定死的 ,且热卖模块暂时不可用-->
									<a href="product?id=${hotProduct.id }" target="_blank"><img src="images/product/5.jpg" /></a>
								</dt>
								<dd class="title">
									<a href="product?id=${hotProduct.id }" target="_blank">优衣库2019春装新款中腰蓝色刺绣修身</a>
								</dd>
								<dd class="price">78</dd>
							</dl>
						</li>
					</ul>
...
  1. 新建一个ProductServlet
    右击com.xxx.servlet包⇥New⇥servlet⇥ClassName填写ProductServlet⇥next⇥URL mappings栏下修改路径名为product⇥next⇥取消勾选Constructors from supclassdoPostdoGet,勾选service⇥Finish

  2. ProductServlet.java文件里完成功能代码

ProductServlet.java文件代码

@WebServlet("/product")
public class ProductServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	
	private ProductService productService = new ProductServiceImpl();
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		
		//判断用户行为
		String action = request.getParameter("action");
		if("".equals(action)){
    
    
			
		}else{
    
    
			
			//商品详情
			details(request,response); //details报红创建一下方法
		}

	}

	//商品详情
	private void details(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		
		//接收参数
		String id = request.getParameter("id");
		
		//非空判断
		if(StringUtil.isEmpty(id)){
    
    
			
			//空则无操作
			return;
		}
		
		//不空,调用service通过id查询商品详情product 
		Product product = productService.findProductById(Integer.parseInt(id)); //findProductById报红生成一下方法,跳转的文件中将parseInt参数改为id
		
		//详情不需要一直保留在会话中,考虑服务器性能,所以将pageName、changePage和product存在作用域request中
		
		//用户访问商品详情时标题商品公告
		request.setAttribute("pageName", "商品");
		request.setAttribute("changePage", "product/product.jsp");
		request.setAttribute("product", product);
		
		//请求转发跳转details.jsp
		request.getRequestDispatcher("details.jsp").forward(request, response);
	}

}
  1. ProductServiceImpl.java文件里写一下方法代码:

ProductServiceImpl.java文件findProductById方法:

...
	//写在查询今日特价商品集合方法后面
	//通过id查询商品详情
	@Override
	public Product findProductById(int id) {
    
    
		// TODO Auto-generated method stub
		
		Product product = null;
		Connection conn = null;
		
		//异常
		try{
    
    
			
		//数据库操作
		//建立连接
		conn = DBUtil.getConnection();
		
		//编写sql语句
		String sql = "select * from t_product where id = ?";
		
		//new一个QueryRunner
		QueryRunner qr = new QueryRunner();
		
		//创建参数数组
		Object[] params = {
    
    id};
		
		//执行查询
		product = qr.query(conn, sql ,new BeanHandler<>(Product.class),params);//BeanHandler报红导一下包
		
		} catch (Exception e){
    
    
			e.printStackTrace();
		}finally{
    
    
			
			//关闭连接
			DBUtil.close(null, null, conn);
		}
		return product;
	}
...

做完后保存文件,重启服务器,再刷新网页,当我们点击今日特价里的商品图片或者文字时,就可以访问商品的详细信息啦。
商品详情一
商品详情二

详情模块-商品详情-最近浏览

思路

此功能后台写在商品详情小模块里的调用service通过id查询商品详情product这一步骤后面。

前台:

  1. WebContent文件夹的子文件夹common下找到left.jsp文件
  2. 循环遍历获取最新浏览商品

后台:

  1. 依旧是在ProductServlet.java文件里完成功能

  2. 从Session中获取最近浏览商品集合

  3. 非空判断
    空,创建集合

  4. 不为空,
    循环遍历最近浏览商品集合,先判断是不是浏览同一件商品

  5. 如果是同一件商品,把浏览的这一件商品放在集合最前。

  6. 如果不是再判断是否有4个商品(最近浏览最多显示四个)
    如果有4个商品,移除最后一个,把浏览的这个商品放在最前
    如果没有4个商品,就把浏览的这个商品放在最前

  7. 存Session,覆盖集合

实操

  1. left.jsp文件中修改最近浏览的相关代码

left.jsp文件相关代码:

...
			<h2>最近浏览</h2>
			<dl class="clearfix">
			
			<!-- 循环遍历<dt><dd>标签 -->
			<c:forEach items="${recentProductList }" var="recentProduct">
			
			 	<dt>
			 		<a href="product?id=${recentProduct.id }" target="_blank"><img src="${recentProduct.proPic }" class="imgs" style="height: 50px;width: 50px;"></a>
			 	</dt>
			 	<dd>
			 		<a href="product?id=${recentProduct.id }" target="_blank">${
    
    recentProduct.name }</a>
			 	</dd>
			
			</c:forEach>
			
			</dl>
...
  1. ProductServlet.java文件更新代码:
...
		//不空,调用service通过id查询商品详情product 
		Product product = productService.findProductById(Integer.parseInt(id)); //findProductById报红生成一下方法,跳转的文件中将parseInt参数改为id
		
		/**
		 * 最近浏览功能
		 */
		
		//从Session中获取最近浏览商品集合
		List<Product> recentProductList = ((List<Product>) request.getSession().getAttribute("recentProductList"));
		
		//非空判断
		if(recentProductList == null){
    
    
			
			//空,创建集合
			recentProductList = new LinkedList<>();
		}
		
		//写一个标记
		boolean flag = true;
		
		//不为空,
		//循环遍历最近浏览商品集合
		//先判断是不是浏览同一件商品
		for(Product recentProduct : recentProductList){
    
    
			
			if(Integer.parseInt(id) == recentProduct.getId()){
    
    
				
				//是同一件商品,改一下标记
				flag = false;
				
				//先删除原来的浏览记录
				recentProductList.remove(recentProduct);
				
				//再把浏览的这一件商品放在集合最前。
				recentProductList.add(0, recentProduct);
				break;
			}
			
		}
		
		if(flag){
    
    
			
			//不是
			//再判断是否有4个商品(最近浏览最多显示四个)
			if(recentProductList.size() == 4){
    
    
				
				//有4个商品,移除最后一个,把浏览的这个商品放在最前
				recentProductList.remove(3);
				recentProductList.add(0, product);
			}else{
    
    
				
				//如果没有4个商品,就把浏览的这个商品放在最前
				recentProductList.add(0, product);
			}
			
		}
		//存Session,覆盖集合
		request.getSession().setAttribute("recentProductList", recentProductList);
		
		//详情不需要一直保留在会话中,考虑服务器性能,所以将pageName、changePage和product存在作用域request中
...

完成以上代码,最近浏览功能也就做完了。点击没一件商品时,右下角的最近浏览第一个都会显示最新浏览的商品,第二个显示上一个浏览的商品,最多显示4个。在里面点击也可以跳转商品详情,贴上成功图(PS:我的今日特价商品因为数据库表的数据时间到了,商品变得很少,所以我干脆给他们的特价时间改到了明年,这样就一直有商品了):

最近浏览
下一篇继续写详情模块的查看留言和发表留言。

猜你喜欢

转载自blog.csdn.net/weixin_42347543/article/details/113341233