JavaWeb-NewsServlet-大总结
来源:互联网 发布:qq空间个性域名注册 编辑:程序博客网 时间:2024/06/18 13:43
话说:
亲们,晚上好!正是前面一系列的优化,才有了今天这篇总结。如果读者看到这篇,觉得无厘头,请一定要回头从开始的JDBC系列开始看起,哈哈。
目录
一、BaseServlet的由来
二、多个Servlet合并归一
三、 BaseDao、NewsDao及页面
四、整体总结
整体布局:
一、BaseServlet的由来
为了避免在页面用JSP来处理请求和响应,我们用专业的处理请求和响应的工具——Servlet来替换了doAdd.jsp、doUpdate.jsp等页面。前期由于有多个功能-CURD,每个功能对应一个Servlet,页面虽然减少了,但是Servlet却多了起来。所以,我们就进一步把多个Servlet优化为了一个Servlet,在这个Servlet里面调用方法,然后处理请求,进行响应。这里有两种方式来实现在一个Servlet里面调用不同的方法:一是:采用if() else{}判断页面的请求参数op(operation,我们自己定义的);这个方法的弊端是要判断,而且在判断过后,手动调用,本质也没有优化多少;二是:用类本身创建Method对象,调用invoke()方法来实现方法的自动调用。你传过来的op值是什么,默认就调用和op同名的方法。这就弥补了第一种方法的弊端。
BaseServlet如下:
package com.hmc.jdbc.news.servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * User:Meice * 2017/10/5 */public class BaseServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置编码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); //根据传递参数决定方法跳转 op代表你访问页面传递的参数operation之含义 String op = req.getParameter("op"); if(op !=null && !"".equals(op)) { try { //获取Method对象;这里和我们前面写过的this.getClass().getDeclaredField类似 Method method = this.getClass().getDeclaredMethod(op,HttpServletRequest.class,HttpServletResponse.class); /** * 调用invoke()方法;属于java.lang.reflect下面的类 * 自动调用指定的方法 参数1:方法所在的类 参数2:调用方法的参数 */ //如果不取消访问权限检查,会报IllegalAccessException异常 method.setAccessible(true); method.invoke(this,req,resp); } catch (NoSuchMethodException e) { //这里,我们来掌控,不要让它抛出异常即可。因为不需要携带什么参数,有请重定向上场!但是不利于搞定Bug e.printStackTrace(); //跳转注意/的区别。/直接从绝对路径开始找,没有了相对路径即当前项目名称了 // resp.sendRedirect("error.jsp"); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } }else{ System.out.println("参数缺失"); } }}
二、多个Servlet合并归一
之所以可以方便的合并为一个Servlet,就是BaseServlet的功劳。我们只用专注的在NewsServlet里面调用各种方法,处理请求和给与响应即可。
NewsServlet中调用了大量BaseDao和NewsDao两个基类中的方法,这两个基类做了漫长的优化之路。这里一并给出,请对比参阅。
NewsServlet
package com.hmc.jdbc.news.servlet;import com.hmc.jdbc.news.dao.BaseDao;import com.hmc.jdbc.news.dao.NewsDao;import com.hmc.jdbc.news.model.News;import com.hmc.jdbc.news.util.StringConvertUtil;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 java.io.IOException;import java.util.List;/** * User:Meice * 2017/10/5 */@WebServlet(urlPatterns = "/news.do")public class NewsServlet extends BaseServlet { NewsDao nd = new NewsDao(); BaseDao bd = new BaseDao(); //查(R) // 未避免代码混乱,把显示新闻列表封装成方法;这里采用最高级的显示新闻方法listShow3() private void list (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sql = "select * from t_news"; List<News> list =(List<News>) bd.listShow3(sql,News.class,null); //3 存储到req中 req.setAttribute("list", list); req.getRequestDispatcher("newsShow.jsp").forward(req, resp); } //增(C) private void add(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { //接受参数 String title = req.getParameter("title"); String author = req.getParameter("author"); News news = new News(title,author); int result = nd.newsAdd2(news);//(写这些方法从后往前写) if(result > 0) { req.getRequestDispatcher("news.do?op=list").forward(req,resp); }else { req.getRequestDispatcher("newsAdd.jsp").forward(req,resp); } } //改(U) //显示要修改的新闻 public void changeShow(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { //接受参数 String strId = req.getParameter("id"); int id = StringConvertUtil.getVal(strId); News news = nd.newsPut3(id); req.setAttribute("news",news); req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp); } //执行修改操作 public void change(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { //接受参数 String strId = req.getParameter("id"); int id = StringConvertUtil.getVal(strId); String title = req.getParameter("title"); String author = req.getParameter("author"); News news = new News(id,title,author); //调用方法 int result = nd.newsUpdate2(news); if(result >0) { req.getRequestDispatcher("news.do?op=list").forward(req,resp); }else { req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp); } } //删(D) private void del(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException { //接受参数 String strId = req.getParameter("id"); int id = StringConvertUtil.getVal(strId); int result = nd.newsDel2(id); req.getRequestDispatcher("news.do?op=list").forward(req,resp); }}
三、 BaseDao、NewsDao及页面
BaseDao
package com.hmc.jdbc.news.dao;import com.hmc.jdbc.news.model.Goods;import com.hmc.jdbc.news.model.News;import com.hmc.jdbc.news.model.User;import com.hmc.jdbc.news.util.ConfigUtil;import java.lang.reflect.Field;import java.sql.*;import java.util.ArrayList;import java.util.List;//哎呀,默认导全部的包,如果包到错了怎么办?public class BaseDao { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; //1、加载驱动,把加载类定义为静态语句块 static { try { Class.forName(ConfigUtil.get("driver")); } catch (ClassNotFoundException e) { e.printStackTrace(); } //说实话感觉卡顿的问题也没怎么解决。可能搜狗输入法还没有和捷克公司做好沟通吧。 } //2、连接MySQL数据库 定义方法getConn() public Connection getConn() { String url = ConfigUtil.get("url"); String user = ConfigUtil.get("user"); String password = ConfigUtil.get("password"); try { conn = DriverManager.getConnection(url,user,password); } catch (SQLException e) { e.printStackTrace(); } System.out.print("恭喜你,连接上了...."); return conn; } //3、关闭资源 public void closeJDBC(ResultSet rs, PreparedStatement ps,Connection conn) { try { if (rs != null) rs.close(); if (ps != null) ps.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } public static void main(String[] args) { //编写查 把数据库的News输出到控制台 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; BaseDao bd = new BaseDao(); //这里如果赋值,就会报NullPoint错误。 conn = bd.getConn(); try { //预编译SQL语句 String sql = "select * from t_news"; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); //遍历结果集 while(rs.next()){ //这里我们可以分明感受到Idea和Eclipse的差别 int id = rs.getInt(1); String title = rs.getString("title"); String author = rs.getString("author"); System.out.println(id+"---"+title+"---"+author); } } catch (SQLException e) { e.printStackTrace(); } new BaseDao().test(); } /** * 我们会发现,我们发现,在NewsDao里面,尤其是CUD有大量重复代码,他们结构都差不多,不同的只是Sql语句和SQL带的参数。所以我们可以做如下封装。 *另外,NewsShow中的查询和改(U)代码也几乎完全相同,无非一个是 * select * from t_news ;一个是select * from t_news where id = ? 是否也可以类似CUD那样封装起来? * */ public int CUD(String sql,Object[] params){ int result = 0; getConn(); try { ps = conn.prepareStatement(sql); //问题关键是参数怎么赋值?在参数个数不确定?类型不确定的情况下? for (int i=0;i<params.length;i++) { ps.setObject((i+1),params[i]); } result = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } closeJDBC(null,ps,conn); return result; } //下面们把查在优化一下 /** * 这里我们不把SQL写死,我们会在两个地方用到,1是newsShow.jsp用到, * 另外一个是修改新闻的时候要用到,代码区别仅仅只是SQL语句不同。 */ public List<News> listShow(String sql, Object[] params) { List<News> list = new ArrayList<>(); getConn(); try { ps = conn.prepareStatement(sql); /** * 以下方法解决了参数个数和参数类型不同的问题 * 高度抽象,不论你给多少参数,什么类型,都可以处理。 */ //这里的params可能有,也可以没有比如select * from t_news和select * from t_news where id = ? //所以最好判断一下 if(params != null && params.length>0) { for(int i = 0;i<params.length;i++) { ps.setObject((i+1),params[i]); } } //否则(null),就不用给参数赋值了,直接执行,这样逻辑才够严谨。 rs = ps.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String title = rs.getString(2); String author = rs.getString("author"); News news = new News(id,title,author); list.add(news); } } catch (SQLException e) { e.printStackTrace(); } return list; } //再次优化查的方式,把List<E>对象也变得灵活抽象,不写死 public List<?> listShow3(String sql ,Class<?> cls,Object... params) { //创建集合存放 List<Object> list = new ArrayList<>(); getConn(); try { //预编译 ps = conn.prepareStatement(sql); //如果带参,遍历赋值 if(params != null && params.length>0){ for(int i =0;i<params.length;i++) { ps.setObject((i+1),params[i]); } } //执行SQL rs = ps.executeQuery(); //获取元数据 ResultSetMetaData rsmd = rs.getMetaData(); //遍历 while (rs.next()) { /** * 要解决的问题就在这里 * 我们不知道调用该方法的人会传入什么类?那个类中有什么属性? * 也同样不知道该用什么类型来接收,也同样没法把属性作为一个对象传递给 * list<E>集合? */ //实例化对象 Object obj = cls.newInstance(); //获取列数 int count = rsmd.getColumnCount(); //rs.getObject(这里面的列数通过remd获取); for(int k=1;k<=count;k++) { //获取列名 String colName = rsmd.getColumnName(k); //根据列名获取对象字段 Field f = cls.getDeclaredField(colName); //给字段赋值;获取列值 Object colVal = rs.getObject(colName); //给对象赋值 f.setAccessible(true);//取消访问检查 f.set(obj,colVal); } list.add(obj); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } return list; } public void test() { String sql = "select * from t_goods"; List<Goods> list = (List<Goods>) listShow3(sql, Goods.class,null); System.out.println(list); }}
BaseDao和之前最大的区别就是把查做了进一步优化。现在优化的结果就是listShow3()这个方法。不论你实体类怎么变化,给我三个参数:实体类、SQL语句、查询的参数,就可以完美执行查的操作了,并把查询结果存放到一个List<>,(中间是问号)类型中。便于页面传值。其他无大变化。
这里面最关键的用到了Field类。这个类可以把数据库中的字段反射成JavaBean的属性。因为调用listShow3()方法的时候,不知道你会给什么类,只知道你要在哪张表查询,所以在遍历结果集取值并赋值的过程中,Field类起了关键作用。
实体类News
package com.hmc.jdbc.news.model;public class News { private int id; private String title; private String author; public News() { } public News(int id, String title, String author) { this.id = id; this.title = title; this.author = author; } //没有2个参数的构造方法,我自己就造一个出来;因为增加新闻不需要考虑ID,对于客户来说。 public News(String title, String author) { this.title = title; this.author = author; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "News{" + "id=" + id + ", title='" + title + '\'' + ", author='" + author + '\'' + '}'; }}
NewsDao
package com.hmc.jdbc.news.dao;import com.hmc.jdbc.news.model.News;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;/** * User:Meice * 2017/10/1 */public class NewsDao extends BaseDao{ //这个类里面我们要写CURD啦。 //1 查 R /** * 我们要把数据从刚才的控制台输出变为输出到页面,所以需要一个类似容器的东西存放我们的数据 * 这里我们用List集合来存放新闻信息,作为运输工具。把我们的代码运输到JSP页面。 */ public List<News> list() { List<News> list = new ArrayList<>(); getConn(); String sql = "select * from t_news"; try { ps = conn.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()) { int id = rs.getInt(1); String title = rs.getString("title"); String author = rs.getString("author"); //每次遍历一次,我们就把一行新闻作为一个对象,这就是JavaBean News news = new News(id,title,author); list.add(news); } } catch (SQLException e) { e.printStackTrace(); } //输出做验证,看以上代码是否正确 // System.out.println(list); closeJDBC(rs,ps,conn); return list; } public static void main(String[] args) { NewsDao nd = new NewsDao(); //验证list()方法 // nd.list(); } //2 增 C //法1:封装发布新闻的方法 public void newsAdd(News news) { getConn(); String sql = "insert into t_news (title,author) values (?,?)"; try { //预编译,步骤类似查 R ps = conn.prepareStatement(sql); //这里我们使用?来传递,专业名称忘了 ps.setString(1,news.getTitle()); ps.setString(2,news.getAuthor()); //这里执行和查就不一样了,用的是Update方法 ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } closeJDBC(null,ps,conn); } //法2:封装发布新闻的方法(前后对比明显吧!) public int newsAdd2(News news){ String sql = "insert into t_news (title,author) values (?,?)"; Object[] params = {news.getTitle(),news.getAuthor()}; return CUD(sql,params); } //3 删 D 法一 public void newsDel(int id) { getConn(); String sql = "delete from t_news where id = ? "; System.out.println("进来了"); try { ps = conn.prepareStatement(sql); ps.setInt(1,id); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } closeJDBC(null,ps,conn); } //删除法二 public int newsDel2(int id) { String sql = "delete from t_news where id = ?"; Object[] params = {id}; return CUD(sql,params); } //4 改 U //法1:第一步,点击修改链接,我们要能把对应的内容放到对应的位置。 public News newsPut(int id) { getConn(); News news = null; String sql = "select * from t_news where id = ?"; try { ps = conn.prepareStatement(sql); ps.setInt(1,id); rs = ps.executeQuery(); while (rs.next()) { id = rs.getInt(1); String title = rs.getString(2); String author = rs.getString(3); news = new News(id,title,author); } } catch (SQLException e) { e.printStackTrace(); } closeJDBC(rs,ps,conn); return news; } //法2:封装根据对应ID把新闻放到页面的方法(两方法对比结果鲜明!) public List<News> newsPut2(int id) { String sql = "select * from t_news where id = ?"; Object[] params = {id}; return listShow(sql,params); } //法3:根据最高级版本的查的的方法listShow3()来根据id获取新闻,直接返回新闻信息,便于获取 public News newsPut3(int id) { String sql = "select * from t_news where id = ?"; Object[] params = {id}; List<News> list =(List<News>) listShow3(sql,News.class,params); //判断 if(list != null && list.size()>0) { return list.get(0); }else{ return null; } } //执行修改操作 法1: public void newsUpdate(News news) { getConn(); String sql = "update t_news set title = ? , author = ? where id = ?"; try { ps = conn.prepareStatement(sql); ps.setString(1,news.getTitle()); ps.setString(2,news.getAuthor()); ps.setInt(3,news.getId()); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } closeJDBC(null,ps,conn); } //执行修改操作 法2:(没有对比就没有伤害) public int newsUpdate2(News news) { String sql = "update t_news set title = ?, author = ? where id = ?"; Object[] params = {news.getTitle(),news.getAuthor(),news.getId()}; return CUD(sql,params); }}
这个几乎没有变化,读者如果用心看,可以看到优化升级的痕迹。
页面布局
也是和之前的NewsServlet类似。不过这次3个页面搞定!
新闻列表:newsShow.jsp
<%@ page import="java.util.List" %><%@ page import="java.util.Enumeration" %><%@ page import="com.hmc.jdbc.news.model.News" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jstl/core" prefix="a" %><%-- Created by IntelliJ IDEA. User: Meice Date: 2017/10/1 Time: 13:30 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><%--如果不用jstl,还是采用JSP嵌套获取--%><%--<% //本来在页面,我们获取list集合非常简单,${}这样就获取了,但是实际过程中,我们在JSP代码中没发做到用这个来获取 List<News> list =(List<News>) request.getAttribute("list");%>--%><html><head> <title>Meice的新闻列表</title></head><body> <h2 align="center">Meice的新闻列表</h2> <table border="1" align="center" width="80%"> <thead> <tr> <th>编号</th> <th>标题</th> <th>作者</th> <th>操作</th> </tr> </thead> <tbody> <%--${news}--%> <%--这里传过来就是那幅图的场景;现在的问题是我不知道怎么接收这个传递过来的值,直接用EL取出来的是 个List<News>的集合。这边又没法遍历。?? 如果不用JSTL,我们用普通的for each,问题是怎么取出这个值。 --%> <c:forEach var="news" items="${list}"> <tr> <td align="center">${news.id}</td> <td align="center">${news.title}</td> <td align="center">${news.author}</td> <td align="center"> <a href="news.do?op=changeShow&id=${news.id}">修改</a> <a href="news.do?op=del&id=${news.id}" onclick="return confirm('真的忍心删我?')">删除</a> </td> </tr> </c:forEach> </tbody> <tfoot></tfoot> </table> <a href="newsAdd.jsp">发布新闻</a></body></html>
发布新闻页面newsAdd.jsp
<%-- Created by IntelliJ IDEA. User: Meice Date: 2017/10/1 Time: 15:02 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>发布新闻</title></head><body> <form action="news.do" method="post"> <%--传递参数的时候,可以直接传参,也可以用隐藏域--%> <input type="hidden" name="op" value="add"/> <table> <tr> <td>标题</td> <td><input type="text" name="title"></td> </tr> <tr> <td>作者</td> <td><input type="text" name="author"></td> </tr> <tr> <td colspan="2"><input type="submit" value="发布"></td> </tr> </table> </form></body></html>
修改新闻页面newsUpdate.jsp
<%@ page import="java.util.List" %><%@ page import="com.hmc.jdbc.news.model.News" %><%@ page import="java.util.ArrayList" %><%-- User: Meice Date: 2017/10/1 Time: 18:06--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html><head> <title>Title</title></head><body> <form action="news.do" method="post"> <input type="hidden" name="op" value="change"/> <%--既然form表单的提交方式都为post了,那么在带参就不好,所以用隐藏域来传参--%> <table> <%--多个可以遍历,一个元素也可以遍历的。否则又要回归到JSP方法取值了--%> <tr> <td>编号</td> <td><input type="text" name="id" value="${news.id}" disabled="disabled" ></td> </tr> <tr> <td>标题</td> <td><input type="text" name="title" value="${news.title}"></td> </tr> <tr> <td>作者</td> <td><input type="text" name="author" value="${news.author}"></td> </tr> <tr> <td colspan="2"><input type="submit" value="确认修改"></td> </tr> </table> </form></body></html>
也许你还会问,web.xml配置呢?哈哈,我们全部用了Servlet3.0新特性——注解搞定啦。
这里的web.xml也贴出来,作为纪念,里面的配置已经没有任何实质作用啦。
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!--news Add Servlet--> <servlet> <servlet-name>newsAdd</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsAddServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>newsAdd</servlet-name> <url-pattern>/newsAdd.do</url-pattern> </servlet-mapping> <!--news Show Servlet--> <servlet> <servlet-name>newsShow</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsShowServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>newsShow</servlet-name> <url-pattern>/newsShow.do</url-pattern> </servlet-mapping> <!-- news Update Servlet--> <servlet> <servlet-name>newsUpdate</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsUpdateServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>newsUpdate</servlet-name> <url-pattern>/newsUpdate.do</url-pattern> </servlet-mapping> <!--news Update Do Servlet--> <servlet> <servlet-name>newsUpdateDo</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsUpdateDoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>newsUpdateDo</servlet-name> <url-pattern>/newsUpdateDo.do</url-pattern> </servlet-mapping> <!--news Del Servlet--> <servlet> <servlet-name>newsDel</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsDelServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>newsDel</servlet-name> <url-pattern>/newsDel.do</url-pattern> </servlet-mapping> <!--news Servlet 这个Servlet可以处理所有操作;只要你给我一个参数--> <!--用Servlet3.0新特性——注解的时候就可以不用配置啦!--> <!-- <servlet> <servlet-name>news</servlet-name> <servlet-class>com.hmc.jdbc.news.servlet.NewsServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>news</servlet-name> <url-pattern>/news.do</url-pattern> </servlet-mapping>--> <!--错误页面配置--> <!--<error-page>--> <!--<!–表示页面错误类型404 400 500之类的–>--> <!--<error-code>404</error-code>--> <!--<!–这里配置错误页面位置–>--> <!--<location>/error.jsp</location>--> <!--<!–这个配置是配置错误类型类似:NullPointException–>--> <!--<!–<exception-type></exception-type>–>--> <!--</error-page>--> <!--既然是Servlet新特性,我们把Filter也加入进来,这里过滤字符编码;加入注解,也就不用配置了--> <!-- <filter> <filter-name>encoding</filter-name> <filter-class>com.hmc.jdbc.news.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>--> <!--加入我们的监听器TestHttpSessionListener;这里同样可以加入注解,取消配置--> <!-- <listener> <listener-class>com.hmc.jdbc.news.listener.TestHttpSessionListener</listener-class> </listener>--></web-app>
优化到这里,就会明白一个道理,温故知新,知历史方能更好的知未来。不经历优化的漫长体验,就无法体会优化后的爽歪歪。
四、整体总结
四点总结
1、根据ID获取News对象,封装成方法。这是个很好的优化过程,之前我们每次修改和删除传递ID的时候,都是接收后,然后转换为整型,搞得很无语。现在好了,一个方法,随时调用。当你重复代码多起来的时候,就思考下,怎么来简化。
package com.hmc.jdbc.news.util;/** * User:Meice * 2017/10/8 */public class StringConvertUtil { //还记得每次修改和删除的时候,都要接受字符串id嘛,转换的很辛苦,每次都重复这段代码,今天从根源解决一下 /** * 1 接受参数 *int id = 0; *String strId = req.getParameter("id"); *if (strId != null && !"".equals(strId)) { *id = Integer.valueOf(strId); *} */ //未方便调用,直接来个静态的 public static int getVal(String str){ int id =0; if(str != null && !"".equals(str)) { id = Integer.parseInt(str); }else{ id =0; } return id; }}
2、 public List<问号> listShow3(String sql ,Class<问号> cls,Object… params) {}
这里List<问号>写?而不写Object大有作用,这里的?代表Object以及任何实体类,
这样在调用该方法的时候,返回值的类型可以强转成任意需要的类型:
List<News> list =(List<News>)
listShow3(sql,News.class,params);
但是,如果方法开始这么定义public List listShow3(String sql ,Class<问号> cls,Object… params){}
那么接收的时候,就无法转换类型。实体类没发强转成List类。
示例:
//以下方法的弊端是:你传过去的是个List里面存放的是 Object的集合,不好取值
/* String sql = "select * from t_news where id = ?"; Object[] params = {id}; //调用这个在查功能上万能的方法,哈哈! List<Object> list = bd.listShow3(sql,News.class,params); //传参 req.setAttribute("list",list); //页面跳转 try { req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } */
你返回的是一个List里面存放的是Object对象,那么我们的JavaBean呢?根本没用上呢
3、传递多个参数,用&连接
<a href="news.do?op=changeShow&id=${news.id}">修改</a>
别写成这样:
<a href="news.do?op=changeShow&?id=${news.id}">修改</a>
4、修改新闻的时候,让新闻编号id显示还是不显示?如何显示,This is a question!
<tr> <td>编号</td> <td><input type="text" name="id" value="${news.id}" readonly="readonly"></td> </tr>
1)编号是后台把控的,如果不想用户看到,可以作为隐藏域
<input type="hidden" name="id" value="${news.id}"/>
这样在form表单提交的时候,id照样可以传过去,便于后台执行修改操作。那为什么不直接在
<form action="news.do" method="post">
里的news.do?id=${news.id}这样带参?又是post提交,又带参,就不好了。
2)除了设置为readonly=”readonly”之外,我们表面上还可以设置为diabled=”disabled”;但是虽然也达到了了用户不能修改id的目的且显示灰色,表示不能修改。但是,一旦改为这个,在点击提交的时候,id就没发传到后台。我们的修改和删除全都依靠id来操作…….
我们在NewsServlet里面接受参数那几行代码设置断点,然后DeBug观察参数变化,如图:
实践是检验真理的唯一标准,果然,后台没有接收到参数id.
所以,慎用disabled属性。
大数据里面,HBase表格中,一张表只有disabled,才能删除。属性之间是相通的。
好了,各位,晚安!下次再会!
- JavaWeb-NewsServlet-大总结
- JavaWeb中的九大内置对象总结
- javaweb三大框架知识点总结
- javaweb三大框架知识点总结
- javaweb三大框架(ssh)知识点总结
- JavaWeb总结
- javaweb总结
- javaweb总结
- JavaWeb总结
- Javaweb总结
- javaweb三大框架
- JavaWeb三大组件
- JavaWeb三大组件
- javaweb三大组件
- javaweb学习总结(三十四)——使用JDBC处理MySQL大数据
- JavaWeb学习总结(三十五)——使用JDBC处理Oracle大数据
- javaweb学习总结(三十四)——使用JDBC处理MySQL大数据
- JavaWeb学习总结(三十五)——使用JDBC处理Oracle大数据
- 开放系统互联
- 实验二 线性表综合实验之《单链表》
- java第三天/10.1
- struts2运行流程
- 理论篇~第六章 元数据
- JavaWeb-NewsServlet-大总结
- 每天一个linux命令(4):mkdir命令
- 设计模式从零开始——代理模式
- 标签
- 欢迎使用CSDN-markdown编辑器
- 死锁产生的原因和解决方法
- Nginx配置文件nginx.conf中文详解(史上最全!!!!)
- Java面试题全集(上)
- genymotion出现INSTALL_FAILED_CPU_ABI_INCOMPATIBLE