项目1-企业门户网-2-首页显示新闻

xiaoxiao2021-02-28  8

话说:

各位读者盆友,新年好!

还是那句话:学会的感觉是快乐的,如果能够创造,会更加快乐!我们在17年12月中旬发表过1篇博客是关于企业门户网首页的博客,然后就搁置下来啦。这个小项目是基于JSP+Servlet的,技术还是Servlet的增删改查,和笔者后续发表的小确幸论坛技术类似。做这个的目的很简单:再次重温JDBC和Servlet.。我一直对JDBC和Servlet有一种特殊的感情,即便到了各种框架,我依旧很怀念初逢JDBC和Servlet的那段日子,SpringMVC的底层还不是Servlet,所以说虽然现在用得少了,但是还是那么熠熠生辉,那么经典。

目录


1.效果图 2.数据库连接 3.显示新闻列表(String方式) 4..显示新闻列表(Servlet方式) 5.总结


技术:JSP+Servlet+MySQL 开发工具:Eclipse

难度系数:★☆☆☆☆ 建议用时:1H

1.效果图

这不就是简单从数据库查显示一下么?有啥特别的?是的。过年嘛,敲敲代码玩下。 但是还有点新东西的,后面介绍到对应模块了在细讲。

整体代码结构: 后端:

前端:

2.数据库连接

一般我们把连接数据库封装成工具类,直接调用。这里的连接方式和我之前的方式有点不一样:把数据库类型:DBType抽离出来,根据这个选择不同的连接方式。这个思路很好,不论是连接MySQL、SqlServer、 Oracle,直接改变这个值然后增加一个连接其他数据库方法即可。

DBConnection

package com.hmc.util; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; /** Author:Meice Date:2018年2月18日上午9:19:03 */ public class DBConnection { /** * 目标:获取数据库连接 * 1.读取静态资源 * 2.把数据库连接写活 。(不论连接什么数据库,我们只需要修改配置文件的DBType即可) * 3.把日常用到的方法封装成工具类:MyFunction,便于调用 */ private static Connection conn; private static int DBType; /** * 定义根据数据类型返回对应连接的方法getConn() * 这里妙在:数据库类型很灵活啦! */ public static Connection getConn() { DBType = MyFunction.getStrToInt(getPara("DBType")); switch(DBType) { case 1: return getConnToMySql(); default: return null; } } /** * 获取静态资源方法 getPara() */ public static String getPara(String paraName) { Properties pro = new Properties(); InputStream is; try { is = new FileInputStream("D:\\WorkSpace\\eclipse2\\qymh\\src\\DBConfig.property");//默认从Web项目下开始找 pro.load(is); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return pro.getProperty(paraName); } /** * 定义连接MySQL数据库方法getConnToMySql() */ public static Connection getConnToMySql() { try { Class.forName(getPara("MySQLDriver")); conn =DriverManager.getConnection(getPara("MySQLURL")); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 测试 */ public static void main(String[] args) { System.out.println(getPara("DBType"));//1 成功! System.out.println(getConn());//com.mysql.cj.jdbc.ConnectionImpl@3c5a99da } }

要是代码里面可以标记颜色就好了,我的笔记里面对重点部分是有强调的。

注意静态资源DBConfig.property的位置。默认是放在工程目录下,如果放在src下面,直接写到:工程/src/DBConfig.property即可。 这里之所以要用绝对路径,是因为交给Servlet之后,就找不到啦。

MyFunction

是打算把过去所有的工具方法放在一个方法里面,方便调用。 package com.hmc.util; /** Author:Meice Date:2018年2月18日上午9:23:24 */ public class MyFunction { /** * 方法1:把字符串转int * 静态方法方便直接调用 */ public static int getStrToInt(String str) { if(str != null && str != "") { return Integer.parseInt(str); }else { return 0; } } }

3.显示新闻列表(String方式)

这里的方法比较奇怪,书上直接通过StringBuffer来返回给页面的。这种拼接HTML的方式很特别,也比较原始。在JSP未诞生时候,就是用这种方式写的吧。在JSP页面里面套代码,在方法里面写HTML标签,也是一种方式,不过,读者尝试过就知道了,不好。 后台是这么写的:

MyNews

package com.hmc.servlet; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.hmc.util.DBConnection; import com.hmc.util.MyFunction; /** Author:Meice Date:2018年2月18日下午4:05:58 */ public class MyNews { /** * 新闻列表查询 * 法2:不用Servlet 直接传字符串过去 */ public String getNewsList() { Connection conn = DBConnection.getConn(); //定义本方法返回的字符串数据 StringBuffer sb = new StringBuffer(); String sql = "select * from news order by NewsID desc"; try { PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); if(rs == null) {//当查询结果为空 System.out.println(rs); sb.append("<tr><td colspan=\"5\" style=\"color:red\">奥奥,暂无记录~</td></tr>"); }else { while(rs.next()) { //接收每个字段 int newsId = rs.getInt("NewsID");//这里一定要接收Id,因为详情要用到 以后后台修改也是类似的逻辑 String newsTitle = rs.getString("NewsTitle"); String newsTime = rs.getString("NewsTime"); String adminName = rs.getString("AdminName"); //把这些值作为字符串追加到sb方便页面显示 sb.append("<tr>");//页面到时候是表格 这里代表一行 sb.append("<td>"+newsTitle+"</td>"); sb.append("<td>"+newsTime+"</td>"); sb.append("<td>"+adminName+"</td>"); sb.append("<td><a href=\"newsDetail2.jsp?newsId="+newsId+"\">详情</a></td></tr>"); } } rs.close(); ps.close(); conn.close(); return sb.toString(); } catch (SQLException e) { return "No"; } } public String getNewsDetail(String newsIdStr) { Connection conn = DBConnection.getConn(); StringBuffer sb = new StringBuffer(); String sql = "select * from news where NewsID = ?"; try { PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = null; int newsId = MyFunction.getStrToInt(newsIdStr); if(newsId == 0) { return "No"; }else { ps.setInt(1, newsId); rs = ps.executeQuery(); if(rs == null) { return "No"; }else { while(rs.next()) { String newsTitle = rs.getString("NewsTitle"); String newsContent = rs.getString("NewsContent"); sb.append("<h2>"+newsTitle+"</h2>"); sb.append("<p>"+newsContent+"</p>"); } } } rs.close(); ps.close(); conn.close(); return sb.toString(); } catch (SQLException e) { // TODO Auto-generated catch block return "No"; } } }

根本没有用到Servlet的请求方式,这里直接在页面调用了方法,然后输出StringBuffer

我们看页面是如何调用方法的: newsList2

<%@page import="com.hmc.servlet.MyNews"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!--Author:Meice 2018年2月18日下午4:01:10 --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>新闻列表</title> <link rel="stylesheet" type="text/css" href="css/mymain.css"> </head> <body> <jsp:include page="head.jsp"></jsp:include> <div> <!-- 显示新闻信息详情 --> <table align="center" width="60%" border="1"> <thead> <tr> <th>新闻标题</th> <th>发布人</th> <th>发布时间</th> <th>详情</th> </tr> </thead> <tbody> <!-- 从后台拿数据 --> <% MyNews mn = new MyNews(); String sbOk = mn.getNewsList(); if(sbOk.equals("No")) { out.println("数据库连接有误~"); }else{ out.println(sbOk); } %> </tbody> </table> </div> <jsp:include page="foot.jsp"></jsp:include> </body> </html>

这是书本上显示新闻列表的方式?元芳,你怎么看?

4..显示新闻列表(Servlet方式)

上面方式不好,我当然用自己的方式喽,以下是自己的方式:用到Servlet 也是用MVC架构写的,配置Servlet的时候,注解、XML交叉使用,看心情。 NewsDao NewsDaoImpl NewsListServlet NewsDetailServlet

NewsDao

package com.hmc.dao; /** Author:Meice Date:2018年2月18日上午11:21:32 */ import java.util.List; import com.hmc.pojo.News; public interface NewsDao { //显示新闻列表及查询单个新闻 List<News> getNewsList(); News getNewByNewsId(Integer newsId); //接口 int Cud(String sql,Object[] params); }

这里的SQL没有写具体,好处是写一个接口就好。不过,所有的sql语句都跑到了Servlet中去啦。 元芳,你怎么看?按理说,我们的SQL属于Dao层,所有的SQL都应该放到Dao里面,Servlet不管其他,只管调用底层方法即可,这样方便了方法,有点小矛盾。不过,不伤大雅,好用就行。

NewsDaoImpl

package com.hmc.daoImpl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.hmc.dao.NewsDao; import com.hmc.pojo.News; import com.hmc.util.DBConnection; /** Author:Meice Date:2018年2月18日上午11:23:57 */ public class NewsDaoImpl implements NewsDao{ @Override public List<News> getNewsList() { //定义List集合存放从MySQL中取出的数据 List<News> newsList = new ArrayList<>(); //从数据库查数据 Connection conn = DBConnection.getConn(); String sql = "select * from news order by NewsID desc"; try { PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); if(rs != null) { while(rs.next()) { int newsId = rs.getInt("NewsID"); String newsTitle = rs.getString("NewsTitle"); String newsContent = rs.getString("NewsContent"); String newsTime = rs.getString("NewsTime"); String adminName = rs.getString("AdminName"); News news = new News(newsId, newsTitle, newsContent, newsTime, adminName); newsList.add(news); } } } catch (SQLException e) { e.printStackTrace(); }finally { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return newsList; } /** * 根据新闻Id 返回单个新闻对象 */ @Override public News getNewByNewsId(Integer newsId) { News news = null; Connection conn = DBConnection.getConn(); String sql = "select * from news where NewsID = ?"; try { PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, newsId); //执行查询 ResultSet rs = ps.executeQuery(); if(rs != null) { if(rs.next()) { String newsTitle = rs.getString("NewsTitle"); String newsContent = rs.getString("NewsContent"); String newsTime = rs.getString("NewsTime"); String adminName = rs.getString("AdminName"); news = new News(newsId, newsTitle, newsContent, newsTime, adminName); } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return news; } /** * 增 删 该 */ @Override public int Cud(String sql, Object[] params) { Connection conn = DBConnection.getConn(); try { PreparedStatement ps = conn.prepareStatement(sql); /** * 执行操作 因为增删改直接操作数据库 和查相比 就简单多 不需要考虑字段什么的 重要的是为每个参数赋值 * insert into news (NewsTitle,NewsContent,AdminName) values(?,?,?); * update news set NewsTitle = ?,NewsContent = ? where NewsID =? * delete from news where NewsID = ? * 如何处理多个参数? */ //遍历为参数赋值后才执行操作 if(params != null) { for(int i=0;i<params.length;i++) { ps.setObject((i+1), params[i]); } } //执行操作 int result =ps.executeUpdate(); System.out.println("执行增删改后的结果是:"+result); if(result >0) { return 1; }else { return 0; } } catch (SQLException e) { e.printStackTrace(); return 0; } } }

重温JDBC,无比亲切啊。框架是很好用,不过鬼知道底层怎么实现的。出现了问题,不是bean就是compoent之类的。

NewsListServlet

这个显示新闻列表 package com.hmc.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hmc.dao.NewsDao; import com.hmc.daoImpl.NewsDaoImpl; import com.hmc.pojo.News; /** Author:Meice Date:2018年2月18日上午10:44:27 */ @WebServlet("/front/newsList") public class NewsListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接收参数 System.out.println("查询新闻列表进来了"); //2.调用方法 NewsDao nd = new NewsDaoImpl(); List<News> newsList = nd.getNewsList(); System.out.println("查询到的新闻列表是:"+newsList); //3.跳转页面 req.setAttribute("newsList", newsList); req.getRequestDispatcher("newsList.jsp").forward(req, resp); } }

以上需要注意一下@WebServlet(),因为我的项目在WebContent下面是2个目录:front admin所以访问的时候,一开始是默认在front下面的,配置的时候原来都是直接/ 这样开始的,现在要手动写一个目录,否则找不到。

编码就不用过滤器了,反正就那么点代码,也不麻烦,找找当年处理乱码的感觉。

NewsDetailServlet

这个显示新闻详情 package com.hmc.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hmc.dao.NewsDao; import com.hmc.daoImpl.NewsDaoImpl; import com.hmc.pojo.News; import com.hmc.util.MyFunction; /** Author:Meice Date:2018年2月18日下午12:41:22 */ @WebServlet("/front/newsDetail") public class NewsDetailServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1 接收新闻Id String newsIdStr = req.getParameter("newsId"); int newsId = MyFunction.getStrToInt(newsIdStr); //2.调用查单个新闻的方法 NewsDao nd = new NewsDaoImpl(); News news = nd.getNewByNewsId(newsId); System.out.println("根据newsId查出的单个对象为:"+news); //3.页面跳转 req.setAttribute("news", news); req.getRequestDispatcher("newsDetail.jsp").forward(req, resp); } }

5.总结

哈哈,做这个有什么意义呢?好玩。


1)页面我们全部放到WebContent里面,没有放到Web-inf下面,因为技术是JSP+Servlet,放到那下面就没法访问啦。加上整体又是admin front两个文件夹,所以Servet的请求路径要注意下,不能简单的/了事;

2) out.println()是在<%%>里面给页面输出的方式;在Servlet里面是这么输出页面元素的:response.getWriter().write();这里面是可以写JS的,主要用来提示用比如:登录失败给提示,修改成功给提示等等; out.println()也是可以写网页元素的,但是网页元素很多,怎么办?用到了StringBuffer,这个可长可短,最后.toString()一下就可以啦。到页面就直接显示网页元素。是一种比较古老的处理方式,了解即可。


好了!再会!下一篇实现后台新闻增删改查,这个小项目就搞定啦。

转载请注明原文地址: https://www.6miu.com/read-2650061.html

最新回复(0)