day02

Servlet JSP

Java Web应用的目录结构

Java Servlet 规范规定了严谨的目录结构必须

webapp
  |--WEB-INF        用户不能直接访问的文件夹
  |   |-- web.xml   部署描述文件
  |   |-- classes   编译以后的Java 类文件, 包括Servlet等
  |   |-- lib       第三方的库, 比如jdbc驱动等
  |--post.html      直接发布的文件: html, js, css 等

Eclipse会自动将项目发布到 Tomcat 中:

1.png

Servlet JDBC 编程

导入JDBC驱动

Maven项目中导入的Jar会自动发布到 WEB-INF/lib 文件夹中.

步骤:

  1. 导入 mysql 驱动

     <dependency>
         <groupId>mysql-connector-java</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.37</version>
     </dependency>
    
  2. 部署

  3. 检查 Tomcat 里面的Web应用中WEB-INF/lib里面是否有mysql connector jdbc jar.

导入测试框架 JUnit

JUnit是企业中必备的Java测试工具, 其使用步骤为:

  1. 导入JUnit组件

     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
         <scope>test</scope>
     </dependency>
    

    这里<scope></scope> 表示JUnit组件不发布到Web 应用的WEB-INF/lib文件夹下,只是在Eclipse项目中有效
    scope 范围

  2. 创建测试案例:

     public class TestCase {
         @Test
         public void testHello() {
             System.out.println("Hello World!");
         }
         @Test
         public void testKitty() {
             System.out.println("Hello Kitty!");
         }
     }
    
  3. 测试: 在Eclipse中可以对每个测试方法单独执行, 测试结果显示在JUnit视图标签中.

编写DBUtils封装数据库连接

  1. 编写DBUtil

     public class DBUtil {
         private static String driver;
         private static String url;
         private static String username;
         private static String password;
         //读取配置文件,获取4个连接参数 conf.properties
         static{
             
             try {
                 //读取resource中的配置文件
                 String file="conf.properties";
                 InputStream in = DBUtil.class
                         .getClassLoader()
                         .getResourceAsStream(file);
                 Properties config=new Properties();
                 config.load(in);
                 driver=config.getProperty("driver");
                 url=config.getProperty("url");
                 username=config.getProperty("username");
                 password=config.getProperty("password");
                 //打桩!!!
             } catch (IOException e) {
                 e.printStackTrace();
                 throw new RuntimeException(e);
             }
             
         }
         
         public static Connection getConnection()
             throws SQLException {
             try {
                 Class.forName(driver);
                 Connection conn = 
                         DriverManager.getConnection(
                         url, username, password);
                 return conn;
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
                 throw new SQLException(e);
             }
         }
         public static void commit(Connection conn){
             if(conn!=null){
                 try {
                     conn.commit();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
         public static void rollback(Connection conn){
             if(conn!=null){
                 try {
                     conn.rollback();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
         public static void close(Connection conn){
             if(conn!=null){
                 try {
                     conn.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
     }
    
  2. 利用JUnit测试:

     @Test
     public void testCConnection() throws SQLException {
         //测试数据库的连接
         Connection conn = DBUtil.getConnection();
         System.out.println(conn);
         DBUtil.close(conn);
     }
    

Servlet直接调用JDBC可以直接编写程序,程序会复杂繁琐:

2.png

步骤为:

  1. 编写Servlet

     /**
      * 实现显示用户列表的功能
      */
     public class ListUserServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             //连接到数据库
             //查询结果
             //将查询结果拼接为HTML
             //返回HTML内容
    
             //状态默认值是200
             response.setContentType("text/html;charset=utf-8");
             //设置Body中的文本编码为 utf-8
             response.setCharacterEncoding("utf-8");
             PrintWriter out = response.getWriter();
    
             //输出头部
             out.println("<!DOCTYPE html>");
             out.println("<html>");
             out.println("   <head>");
             out.println("       <meta charset=\"utf-8\"");
             out.println("   </head>");
             out.println("   <body>");
             out.println("       <h1>用户列表</h1>");
    
             Connection conn = null;
    
             try {
                 conn = DBUtil.getConnection();
                 //执行SQL
                 String sql = "select * from user";
                 Statement st = conn.createStatement();
                 ResultSet rs = st.executeQuery(sql);
                 //输出头部...
                 out.println("<table border='1'>");
                 out.println("   <tr>");
                 out.println("       <td>编号</td>");
                 out.println("       <td>用户名</td>");
                 out.println("   <tr>");
    
                 while(rs.next()) {
                     //读取查询结果
                     //输出 每一行数据
                     out.println("   <tr>");
    
                     out.print("         <td>");
                     out.print(rs.getInt("id"));
                     out.println("   </td>");
    
                     out.print("         <td>");
                     out.print(rs.getString("username"));
                     out.println("       </td>");
    
                     out.println("   </tr>");
                 }
                 //输出尾部
                 out.println("   </table>");
             } catch (SQLException e) {
                 e.printStackTrace();
                 //抛出异常返回 500 错误页面
                 throw new ServletException(e);
             } finally {
                 DBUtil.close(conn);
             }
    
             out.println("   </body>");
             out.println("</html>");
         }
     }
    

    拼接table的思路如下:

4.png
  1. 配置web.xml

        <servlet>
         <description></description>
         <display-name>ListUserServlet</display-name>
         <servlet-name>ListUserServlet</servlet-name>
         <servlet-class>day03.ListUserServlet</servlet-class>
       </servlet>
       
       <servlet-mapping>
         <servlet-name>ListUserServlet</servlet-name>
         <url-pattern>/user/list</url-pattern>
       </servlet-mapping>
    
  2. 测试:

     http://localhost:8080/servlet1/user/list
    

利用MVC模式实现用户列表功能

上述案例可以看到, 数据访问代码和HTML代码混合在一起, 混乱不堪, 并且当HTML页面内容复杂时候, 就更加难于驾驭代码.

在WEB编程中采用MVC模式, 将数据访问\显示视图和控制流程加以分离, 这样可以应付复杂HTML页面处理.

5.png

实现步骤

  1. 编写实体类User:
    public class User implements Serializable {

        private Integer id;
        private String username;
        private String password;
        private String email;
        private String mobile;
        private Date createTime;

        public User() {
        }

        public User(Integer id, String username, String password, String email, String mobile, Date createTime) {
            super();
            this.id = id;
            this.username = username;
            this.password = password;
            this.email = email;
            this.mobile = mobile;
            this.createTime = createTime;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public Date getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((id == null) ? 0 : id.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            User other = (User) obj;
            if (id == null) {
                if (other.id != null)
                    return false;
            } else if (!id.equals(other.id))
                return false;
            return true;
        }

        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", mobile="
                    + mobile + ", createTime=" + createTime + "]";
        }


    }
  1. 编写Dao封装数据访问逻辑

    Dao 接口:

     public interface UserDao {
    
         /**
          * 查询全部用户信息
          * @return 包含全部用户信息的集合
          */
         List<User> findAllUser();
     }
    

    Dao实现类:

     public class UserDaoImpl implements UserDao{
    
         public List<User> findAllUser() {
             Connection conn = null;
             try {
                 conn = DBUtil.getConnection();
                 String sql = "select * from user";
                 Statement st = conn.createStatement();
                 ResultSet rs = st.executeQuery(sql);
                 List<User> list = new ArrayList<User>();
                 while(rs.next()) {
                     User user = new User();
                     user.setId(rs.getInt("id"));
                     user.setUsername(rs.getString("username"));
                     user.setPassword(rs.getString("password"));
                     user.setEmali(rs.getString("email"));
                     user.setMobile(rs.getString("mobile"));
                     user.setCreateTime(rs.getTimestamp("create_time"));
                     list.add(user);
                 }
                 return list;
             } catch (SQLException e) {
                 e.printStackTrace();
                 throw new RuntimeException(e);
             } finally {
                 DBUtil.close(conn);
             }
         }
    
     }
    
  2. 测试Dao

     @Test
     public void testFindAllUser(){
         //测试 查询全部用户信息的方法
         UserDao dao = new UserDaoImpl();
         List<User> list=dao.findAllUser();
         for (User user : list) {
             System.out.println(user); 
         }
     }
    
  3. 编写 ListAllServlet 作为控制器

     public class ListAllServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
    
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             //利用Dao查询数据
             //将请求转发到 另外一个 Servlet显示数据
             UserDao dao = new UserDaoImpl();
             List<User> list = dao.findAllUser();
    
             //将需要传递的数据 放置到request对象中
             req.setAttribute("users", list);
             //list = req.getAttribute("user");
    
             String path = "user/view";
             //String path="/WEB-INF/view/users.jsp";
             //request API 提供了 Servlet之间协作处理
             //的功能, forward: 协作(请求)转发
             RequestDispatcher rd = req.getRequestDispatcher(path);
         }
     }
    

    注意这个 控制器 必须依赖 显示组件 才能工作

  4. 配置 web.xml

     <servlet>
         <description></description>
         <display-name>ListAllServlet</display-name>
         <servlet-name>ListAllServlet</servlet-name>
         <servlet-class>controller.ListAllServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>ListAllServlet</servlet-name>
         <url-pattern>/user/listall</url-pattern>
     </servlet-mapping>
    
  5. 编写视图 ViewServlet

     public class ViewServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
    
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             //显示组件,只负责显示用户信息
             //获得用户信息
             List<User> users = (List<User>) req.getAttribute("users");
             System.out.println("users"+users);
    
             resp.setContentType("text/html;charset=utf-8");
             resp.setCharacterEncoding("utf-8");
             PrintWriter out = resp.getWriter();
    
             out.println("<!DOCTYPE html>");
             out.println("<html>");
             out.println("<head>");
             out.println("<meta charset='utf-8'>");
             out.println("</head>");
             out.println("<body>");
             out.println("<h1>全部用户</h1>");
             out.println("<table>");
             out.println("  <tr>");
             out.println("  <td>编号</td>");
             out.println("  <td>用户名</td>");
             out.println("  </tr>");
             for (User u : users) {
                 out.println("   <tr>");
    
                 out.print(" <td>");
                 out.print(u.getId());
                 out.println("   </td>");
    
                 out.print(" <td>");
                 out.print(u.getUsername());
                 out.println("   </td>");
    
                 out.println("   </tr>");
             }
             out.println("</table>");
             out.println("</body>");
             out.println("</html>");
         }
     }
    
  6. 配置 web.xml

     <servlet>
         <description></description>
         <display-name>ViewServlet</display-name>
         <servlet-name>ViewServlet</servlet-name>
         <servlet-class>view.ViewServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>ViewServlet</servlet-name>
         <url-pattern>/user/view</url-pattern>
     </servlet-mapping>
    
  7. 测试

    http://8080/servlet1/user/listall

JSP

JSP Java 推荐的视图组件,用于解决Servlet作为视图使用非常繁琐的问题,JSP按照HTML语法编写,在运行期间解释为Servlet工作:

编写JSP实现视图组件功能:

  1. 编写JSP实现视图组件功能:

     <%@ page 
         import="java.util.List,entity.User"
         contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
     <!DOCTYPE html>
     <html>
     <head>
         <meta charset="utf-8">
         <title>用户列表</title>
     </head>
     <body>
         <h1>用户JSP</h1>
         <table>
             <tr>
                 <td>编号</td>
                 <td>用户名</td>
             </tr>
     <%
     //Java程序脚本
         List<User> users = (List<User>)request.getAttribute("users");
         for(User u: users){
     %>
             <tr>
                 <td><%=u.getId() %></td>
                 <td><%=u.getUsername() %></td>
             </tr>
     <%
         }
     %>
         </table>
     </body>
     </html>
    

    这里将JSP保存在 WEB-INF文件夹的目的是为了避免视图组件被用户之间访问出现异常信息。

  2. 重构控制器 LustServlet,更新视图组件:

     ...
     //转发到视图显示users数据
     String path="/WEB-INF/view/users.jsp";
     //request API 提供了 Servlet之间协作处理
     //的功能,forward: 协作(请求)转发
     RequestDispatcher rd = req.getRequestDispatcher(path);
     rd.forward(req,resp);
     ...
    
  3. 测试:

     http://localhost:8080/servlet/user/listall
    

后续课程讲解详细的 JSP语法

  • JSP 指令 <%@ %>
  • JSP 脚本 <% ... %>
  • JSP 表达式 <%=表达式%>

作业

  1. 实现课堂案例
  2. 利用 Servlet/JSP 配合实现 商品列表
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,605评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,807评论 0 11
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,582评论 1 114
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 你心中排名前三的渣男是谁?相信每个人答案都不一样. 我的答案是胡兰成,金庸,郭沫若。 胡兰成当之无愧排第一,花女人...
    顽爸的腔调阅读 605评论 2 4