web入门【JSP & MVC】

JSP & MVC

案例目标

  • 企业通讯录

在这里插入图片描述

分析

在这里插入图片描述

实现

  • ContactProfile.java

    package com.itheima.domain;
    
    /**
     * 通讯录用户信息
     *
     * @author itcast
     */
    public class ContactProfile {
        /// 编号
        private int no;
    
        /// 姓名
        private String name;
    
        /// 性别
        private String gender;
    
        /// 出生日期
        private long birthday;
    
        /// 出生地
        private String birthplace;
    
        /// 手机号码
        private String mobile;
    
        /// 邮箱
        private String email;
    
        public ContactProfile() {
        }
    
        public ContactProfile(int no, String name, String gender, long birthday, String birthplace, String mobile, String email) {
            this.no = no;
            this.name = name;
            this.gender = gender;
            this.birthday = birthday;
            this.birthplace = birthplace;
            this.mobile = mobile;
            this.email = email;
        }
    
        public int getNo() {
            return no;
        }
    
        public void setNo(int no) {
            this.no = no;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public long getBirthday() {
            return birthday;
        }
    
        public void setBirthday(long birthday) {
            this.birthday = birthday;
        }
    
        public String getBirthplace() {
            return birthplace;
        }
    
        public void setBirthplace(String birthplace) {
            this.birthplace = birthplace;
        }
    
        public String getMobile() {
            return mobile;
        }
    
        public void setMobile(String mobile) {
            this.mobile = mobile;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
  • ContactsFactory.java

    package com.itheima.domain;
    
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * 通讯录工厂,用于批量生产通讯录用户信息,实际项目中将会采用JDBC技术从数据库读取
     *
     * @author itcast
     */
    public class ContactsFactory {
        public static List<ContactProfile> produce() {
            List<ContactProfile> result = new LinkedList<>();
    
            result.add(new ContactProfile(1, "张三", "male", 11, "广州", "134-0000-0000", "zhangsan@itcast.cn"));
            result.add(new ContactProfile(2, "李四", "male", 12, "上海", "134-0000-0001", "lisi@itcast.cn"));
            result.add(new ContactProfile(3, "王五", "female", 13, "广州", "134-0000-0002", "wangwu@itcast.cn"));
            result.add(new ContactProfile(4, "赵六", "male", 14, "北京", "134-0000-0003", "zhaoliu@itcast.cn"));
            result.add(new ContactProfile(5, "田七", "female", 15, "广州", "134-0000-0004", "tianqi@itcast.cn"));
    
            return result;
        }
    }
    
  • ContactServlet.java

    package com.itheima.web;
    
    import com.itheima.domain.ContactProfile;
    import com.itheima.domain.ContactsFactory;
    
    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.io.PrintWriter;
    import java.util.List;
    
    @WebServlet("/contact")
    public class ContactServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html; charset=utf-8");
            PrintWriter out = response.getWriter();
    
            List<ContactProfile> users = ContactsFactory.produce();
    
            out.println("<!DOCTYPE html>");
            out.println("<html lang='en'>");
            out.println("<head>");
            out.println("<link rel='stylesheet' href='css/bootstrap-grid.min.css'/>");
            out.println("<link rel='stylesheet' href='css/bootstrap-reboot.min.css'/>");
            out.println("<link rel='stylesheet' href='css/bootstrap.min.css'/>");
            out.println("<script src='js/jquery-3.3.1.min.js'></script>");
            out.println("<script src='js/vue.min.js'></script>");
            out.println("<script src='js/bootstrap.bundle.min.js'></script>");
            out.println("<script src='js/bootstrap.min.js'></script>");
            out.println("<meta charset='UTF-8'>");
            out.println("<title>Title</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<table class='table table-striped'>");
            out.println("<tr>");
            out.println("<th>编号</th>");
            out.println("<th>姓名</th>");
            out.println("<th>性别</th>");
            out.println("<th>年龄</th>");
            out.println("<th>籍贯</th>");
            out.println("<th>手机</th>");
            out.println("<th>邮箱</th>");
            out.println("</tr>");
            for (ContactProfile profile : users) {
                out.println("<tr>");
                out.println("<td>" + profile.getNo() + "</td>");
                out.println("<td>" + profile.getName() + "</td>");
                out.println("<td>" + (profile.getGender().equals("male") ? "男" : "女") + "</td>");
                out.println("<td>" + profile.getBirthday() + "</td>");
                out.println("<td>" + profile.getBirthplace() +"</td>");
                out.println("<td>" + profile.getMobile() + "</td>");
                out.println("<td>" + profile.getEmail() + "</td>");
                out.println("</tr>");
            }
            out.println("</table>");
            out.println("</body>");
            out.println("</html>");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    

总结

Servlet制作动态资源的缺点
  • 在Java代码当中嵌入HTML代码,IDEA无法检查字符串内部的HTML语法错误
  • 需要使用字符流输出
  • Java相应的关键字需要转义后才能使用
结论
  • Servlet是在Java代码当中嵌入HTML代码
  • JSP是在HTML代码当中嵌入Java代码

第一部分 JSP入门

1 JSP概述

JavaServer Pages (JSP) technology lets you put snippets of servlet code directly into a text-based document. A JSP page is a text-based document that contains two types of text:

  • Static data, which can be expressed in any text-based format, such as HTML or XML
  • JSP elements, which determine how the page constructs dynamic content

2 JSP运行原理

  • Idea部署Tomcat的Web项目目录
Mac:     /Users/${user}/Library/Caches/IntelliJIdea${version}/tomcat/work
Linux:   /home/${user}/.IntelliJIdea${version}/system/tomcat/work
Windows: C:\Users\${user}\.IntelliJIdea${version}\system\tomcat\work

JSP本质就是Servlet

  • Servlet

在这里插入图片描述

  • JSP

在这里插入图片描述

3 JSP脚本和注释

JSP脚本
  • <% Scriptlet %>【掌握】

    内部的Java代码翻译到service方法的内部
    
  • <%= 表达式 %>【掌握】

    会被翻译成service方法内部out.print(表达式)
    
  • <%! 声明 %>【了解】

    会被翻译成Servlet的成员的内容
    
JSP注释
不同的注释,可见范围不同
  • HTML注释

    <!-- 注释内容 -->
    

    可见范围

    • JSP源码

    • 翻译后的Servlet

    • 页面显示HTML源码

  • Java注释

    //单行注释
    
    /*
    多行注释
     */
    
    /**
      * Java 文档注释
      */
    

    可见范围

    • JSP源码

    • 翻译后的Servlet

  • JSP注释【掌握】

    <%-- 注释内容 --%>
    

    可见范围

    • JSP源码可见
小结
  • Scriptlet

    <% Java代码 %>
    
  • 表达式

    <%= 表达式 %>
    
  • 声明【了解】

    <%! %>
    

4 JSP指令(3个)

JSP的指令是指导JSP翻译和运行的命令,JSP包括三大指令:

page指令【了解】
<%@ page 属性名1 = "属性值1" 属性名2 = "属性值2" %>
属性名描述
languageJSP脚本中可以嵌入的语言种类
pageEncoding当前JSP文件的本身编码,内部可以包含contentType
contentTyperesponse.setContentType(text/html;charset=UTF-8)
session是否JSP在翻译时自动创建session
extends修改JSP翻译后的Servlet的继承体系
import导入java的包
errorPage当前页面出错后跳转到哪个页面
isErrorPage当前页面是一个处理错误的页面,在翻译后的Servlet中会出现一个exception对象
  • 关于错误页面的全局配置(web.xml)

    <error-page>
      <error-code>404</error-code>
      <location>/404.jsp</location>
    </error-page>
    
    <error-page>
      <error-code>500</error-code>
      <location>/500.jsp</location>
    </error-page>
    
include指令【了解】
  • 页面包含(静态包含)指令,可以将一个JSP页面包含到另一个JSP页面中
<%@ include file="被包含的文件地址"%>
taglib指令【了解】
  • 在jsp页面中引入标签库(JSTL标签库、Struts2标签库)
<%@ taglib uri="标签库地址" prefix="前缀"%>

5 pageContext对象

JSP页面的上下文对象
  • pageContext是一个域对象

    • void setAttribute(String name, Object value)

    • Object getAttribute(String name)

    • void removeAttrbute(String name)

    • void setAttribute(String name, Object value, int scope)【了解】

    • Object getAttribute(String name, int scope)【了解】

    • void removeAttrbute(String name, int scope)【了解】

      以上3个方法中,scope的枚举值

      • PageContext.APPLICATION_SCOPE
      • PageContext.SESSION_SCOPE
      • PageContext.REQUEST_SCOPE
      • PageContext.PAGE_SCOPE
    • Object findAttribute(String name)【重点】

      依次从pageContext域,request域,session域,application(ServletContext)域中获取属性,在某个域中获取后将不在向后寻找
      

6 四大作用域总结

  • pageContext

    只在翻译过的service方法里面才有效【只在_jspService()方法内部

  • request

    1个用户的1次请求

  • session

1个用户的所有请求

  • servletContext

所有用户的所有请求

7 案例

  • 制作企业通讯录
实现
  • index.jsp

    <%@ page import="com.itheima.domain.ContactsFactory" %>
    <%@ page import="com.itheima.domain.ContactProfile" %>
    <%@ page import="java.util.List" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <html lang='en'>
    <head>
      <meta charset='UTF-8'>
      <title>Title</title>
    </head>
    <body>
    <table border='1px'>
      <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>年龄</th>
        <th>籍贯</th>
        <th>手机</th>
        <th>邮箱</th>
      </tr>
    
      <!-- 通过dao,把List读取出来 -->
      <% List<ContactProfile> users = ContactsFactory.produce(); %>
      <!-- Scriptlet编写Java代码,遍历所有的通讯录实体 -->
      <% for (ContactProfile profile : contacts) { %>
      <tr>
        <!-- JSP表达式输出 -->
        <td> <%= profile.getNo() %> </td>
        <td> <%= profile.getName() %> </td>
        <td> <%= profile.getGender().equals("male") ? "男" : "女" %> </td>
        <td> <%= profile.getAge() %> </td>
        <td> <%= profile.getBirthplace() %> </td>
        <td> <%= profile.getMobile() %> </td>
        <td> <%= profile.getEmail() %> </td>
      </tr>
      <% } %>
    </table>
    </body>
    </html>
    

8 小结

Scripting ElementExample
注释<%-- --%>【掌握】
指令<%@ %>【了解】
声明<%! 声明 %>【了解 】
Scriptlet<% scriptlet %>
表达式<%= 表达式 %>
pageContext.findAttribute(name)从小往大
pageContext
request
session
application

第二部分 JSP深入 - 标签化JSP

1 标签化JSP概述

在开发JSP页面的过程中,可能会使用Scriptlet代码、表达式元素和声明元素等脚本代码,这种实现方式会使JSP页面难于阅读和维护。对于一些HTML编辑人员而言,JSP页面中的Java代码也是很难妥善处理的。

标签: 成对出现的,比如HTML标签、table标签、a标签

不是成对出现的:

<% for (ContactProfile profile : users) { %>

<% } %>

目的: 可以嵌入在JSP页面内部,减少JSP脚本的编写,替代JSP页面中的脚本元素。

2 EL表达式

2.1 EL表达式概述

Expression Language (also referred to as the EL), which provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans).

The EL allows page authors to use simple expressions to dynamically access data from JavaBeans components.

2.2 EL从域中取出数据
  • EL最主要的作用是获得四大域中的数据,格式${EL表达式}

  • session.setAttribute(“name”, “zhangsan”)

  • EL获得pageContext域中的值:​${pageScope.key};

  • EL获得request域中的值:${requestScope.key};

  • EL获得session域中的值:​${sessionScope.key};

  • EL获得application域中的值:${applicationScope.key};

  • EL从四个域中获得某个值​${key};

    同样是依次从pageContext域,request域,session域,application域中获取属性,在某个域中获取后将不在向后寻找
    
2.3 引用JavaBean对象属性或集合元素
引用对象属性
  • ${customer.orders.socks}
  • ${customer.address[“street”]}
引用集合元素
  • customer.orders 是一个List

    • ${customer.orders[1]}
  • customer.orders 是一个Map<String, Object>

    • ${customer.orders[“socks”]}
    • ${customer.orders.socks}
2.4 EL运算符【了解】
  • 算数运算

    • +, -, *, / and div, % and mod, - (取负数)
  • 字符串级联

    • +=

      int a =1;

      a += 2;

      String a = “abc”;

      a += “def”;

  • 逻辑运算

    • and and &&, or and ||, not and !
  • 关系运算

    • == and eq, != and ne, < and lt, > and gt, <= and ge, >= and le
    • 支持布尔、字符串、整型、符点数的关系运算.
  • Empty

    • empty
    • 前置操作符,判断一个值是否为null或空
    • 当empty后面的表达式为null时,empty返回true;
    • 当empty后面的表达式为""时,empty返回true
  • 条件运算

    • A ? B : C
  • Lambda 表达式

    • ->
  • 赋值

    • =
  • 分号

    • ;
2.5 小结

EL表达式的作用

  • 从域中获取数据

    ${ pageScope.key }

    ${ requestScope.key }

    ${ sessionScope.key }

    ${ applicationScope.key }

    ${ key }

  • 引用对象属性

    request.setAttribute(对象名,对象)

    ${ 对象名.属性名 }

  • 引用集合元素

    • list

    ${ list[索引] }

    • map

    ${ map[“键”] }

    ${ map.键 }

  • 运算操作

    empty 表达式

    判断后边的表达式是否为空

    null:true

    “”: true

3 JSTL技术

3.1 JSTL概述:JSP标准标签库

The JavaServer Pages Standard Tag Library (JSTL) encapsulates core functionality common to many JSP applications. Instead of mixing tags from numerous vendors in your JSP applications, you use a single, standard set of tags. This standardization allows you to deploy your applications on any JSP container that supports JSTL and makes it more likely that the implementation of the tags is optimized.

JSTL has iterator and conditional tags for handling flow control, tags for manipulating XML documents, internationalization tags, tags for accessing databases using SQL, and tags for commonly used functions.

JSTL(JSP Standard Tag Library),JSP标准标签库。JSTL标准标准标签库有5个子库,但随着发展,目前常使用的是他的核心库

标签库标签库的URI前缀
Corehttp://java.sun.com/jsp/jstl/corec
I18Nhttp://java.sun.com/jsp/jstl/fmtfmt
SQLhttp://java.sun.com/jsp/jstl/sqlsql
XMLhttp://java.sun.com/jsp/jstl/xmlx
Functionshttp://java.sun.com/jsp/jstl/functionsfn
3.2 JSTL下载与导入
JSTL下载

http://tomcat.apache.org/download-taglibs.cgi

  • taglibs-standard-impl-1.2.5.jar

    JSTL实现类库
    
  • taglibs-standard-spec-1.2.5.jar

    JSTL标准接口
    
  • taglibs-standard-jstlel-1.2.5.jar

    JSTL1.0标签-EL相关
    
  • taglibs-standard-compat-1.2.5.jar

    兼容版本
    
JSTL导入

taglibs-standard-impl-1.2.5.jartaglibs-standard-spec-1.2.5.jar两个jar包导入到web/WEB-INF/lib下,Add as Library - Module Library

3.3 JSTL核心库的常用标签
AreaFunctionTagsPrefix
CoreVariable supportremove
set
c
Flow control choose
  when
  otherwise
forEach[重点]
forTokens
if[重点]
URL management import
  param
redirect
  param
url
  param
Miscellaneous catch
out
choose标签【了解】
<c:choose>
     <!-- 条件判断,当满足时,进入到标签体里面 -->
     <c:when test="${customer.category == ’trial’}" >
         ...
     </c:when>
     <c:when test="${customer.category == ’member’}" >
         ...
     </c:when>
     <c:when test="${customer.category == ’preferred’}" >
         ...
     </c:when>
     <!-- 当以上所有的条件都不满足时,进入到标签体里面 -->
     <c:otherwise>
         ...
     </c:otherwise>
 </c:choose>
forEach标签【重点】
  • 增强性for循环

    for(ContactInfo contact : contacts)
    
    <c:forEach items = "${contacts}" var = "contact">
    </c:forEach>
    
  • 基础性for循环

    for(int i; i<=100; i+=2) {
        System.out.println(i)
    }
    
    <c:forEach begin = "0" end = "100" step = "2" var = "i">
    </c:forEach>
    
<c:forEacn
items="${collection}" 
[var="varName] 
[varStatus="varStatusName"]
[begin="begin"]
[end="end"]
[step="step"]>
body content
</c:forEach>
  • begin, 起始序号
  • end, 结束序号
  • step, 步长
  • varStatus支持在循环中获取相关的值,比如:
    • current, 当前项
    • index, 当前索引,从0开始[常用]
    • count, 迭代次数,从1开始[常用]
    • first, 布尔值,当前是否第1次
    • last, 布尔值,当前是否是最后1次
    • begin属性值
    • end属性值
    • step属性值
  • 增强性for循环

    注意:

    • items写法,一般为 items="${}",items的属性值,通过EL表达式获取
<%
for (ContactInfo contact : contacts) {

}
%>

<c:forEach items="${contacts}" var="contact">
<tr>
<td>${contact.id}</td>
</tr>
</c:forEach>
  • 基础性 for循环

    注意:

    1. 在循环当中需要使用到下标,要有var属性
    2. step默认值为1
<%
for (int idx = 0; idx <= 100; idx++) {

}
%>

<c:forEach begin="0" end="100" var="idx">
${idx}
</c:forEach>
if标签【重点】
<c:if test="${expression}" [var="varName"] [scope="{page|request|session|application}"]>
body evaluated if expression evaluates to true
</c:if>

4 小结

  • EL表达式

    • 最核心的功能是从域对象中获取数据

      ${ pageScope.name }

      ${ requestScope }

      ${ sessionScope }

      ${ applicationScope }

      ${ name }

      • 取JavaBean属性

      ${contact.property}

      • 取集合元素

      ${list[0]}
      ${map.key}
      ${map[“spec-key”]}

  • JSTL技术

    • forEach
    • 增强性for循环

      • Java
      for (ContactInfo contact : request.getAttribute("contacts")) {
      }
      
      • JSTL
      <c:forEach items="${contacts}" var="contact">
      </c:forEach>
      
    • 基础性for循环

      • Java
      for (int idx = 0; idx <= 100; idx++) {
      }
      
      • JSTL
      <c:forEach begin="0" end="100" var="idx">
      </c:forEach>
      
    • if
    • Java
    if (a != b) {
    }
    
    • JSTL
    <c:if test="${a != b}">
    </c:if>
    

第三部分 JavaEE模式【重点】

模式是通用问题的通用解决方案

1 模式概述

人类自从有思想以来,就在不断探寻和认识自己所生活的这个世界。从本质上说,面向过程和面向对象都是人们认识这个世界的方法;而具体的技术,则是在采用这种方法认识世界的过程中被发明、总结和归纳出来的最佳实践。对于学习者而言,掌握这些技术是重要的;掌握这些技术表示你已经继承了前人的经验积累,并且是一个捷径

– 《大象 - Thinking in UML》

每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。

– Christopher Alexander

  • 模式名称
    • 解决方案,给起的名字
  • 问题
    • 出门
  • 解决方案
    • 应该怎么检查、什么时候检查
  • 效果
    • 不会忘东西

2 Java EE经历的模式

  • Model 1 模式

    JSP + JavaBean

    弊端:随着业务复杂性导致JSP页面比较混乱

  • Model 2 模式

    JSP + Servlet + JavaBean

    优点:开发中使用各个技术擅长的方面

  • MVC

    • M - Model,模型。JavaBean封装数据
    • V - View,视图。JSP,页面展示
    • C - Controller,控制器。Servlet,获取数据、封装数据、传递数据、指派页面

3 Java EE的三层架构

  • SSH

    Struts2

    Spring MVC

    Hibernate

  • SSM/SSI

    SpringMVC

    Spring

    MyBatis/iBatis

在这里插入图片描述

  • Web层

    负责与客户端进行交互,表示页面
    
  • Service层

    业务层,负责处理复杂的业务代码
    
  • DAO层

    数据访问对象,只负责数据的访问(从数据库当中获取数据)
    

注意:三层架构,并不是每一次与特定的MVC相关。每一次里面,都可能会有完整的M、V、C

4 【扩展】面向对象

  • 面向过程

    更多关注的是过程

  • 面向对象

    更多关注的是结果

5 【扩展】做案例的思路

  1. 我要做什么

  2. Servlet

    1. 接收数据
    2. 处理数据
    3. 响应数据
  3. 使用什么技术实现

    1. 数据如果涉及到保存的话,那么考虑4个域对象

      • page

        Servlet的service方法内部

      • request

        1个用户的1次请求

      • session

        1个用户的所有请求

      • application

        所有用户的所有请求

第四部分 学习目标总结

  • 能够理解EL表达式

    最核心的功能:从域中获取数据

    ${ name }
    ${ list[1] }
    ${ map.key }
    ${ map[“key”] }

  • 能够应用EL表达式获取数据

    • 简单数据

      ${域变量名}

    • JavaBean

      ${域变量名.属性名}

    • Collection

      ${map.key名}

      ${map[“特殊名字”]}

      ${list[0]}

  • 能够应用EL表达式执行运算

    Java代码当中的绝大部分运算符都支持

    ${empty abc }
    判断abc的值是否为空
    null为空 - true
    ""为空 - true

  • 能够应用JSTL的标签库中的标签

    <c:forEach items="${collection}" var="varName">
    ${varName}
    </c:forEach>
    
    <c:forEach begin="0" end="100" step="2" var="varName">
    </c:forEach
    
    <c:if test="${条件判断}">
    </c:if>
    
  • 能够描述MVC架构模式

    模型视图控制器
    Servlet - 控制器 C
    JSP - 视图 V
    JavaBean - 模型 M

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值