Web应用技术(第八周/第4次练习/4h)

这一次练习对JSP和Servlet进行了补充学习

    • 1.JSP的本质:
    • 2.include指令的作用:
    • 3.EL表达式语言与JSTL:
      • 关于EL表达式:
        • (1)EL表达式用于取参数值与参数值的设定:
        • (2)EL表达式的本质:
        • (3)开启EL表达式:
      • 关于JSTL:
        • 一般标签:
        • 自闭合标签:
    • 4.JavaBean:
    • 5.JavaDao:
    • 6.HTTP协议响应代码:
    • 6.JSP作用域:
    • 7.HttpServletRequest和HttpServletResponse
    • 8.中文编码问题:

这一次练习根据 how2j对JSP和Servlet进行了补充学习。

1.JSP的本质:

JSP文件虽然是Java、html、jsp标签的合体,但它在运行时会被转换成"文件名_jsp.java"的一个servlet,借用how2j上的图片来说明:
Web应用技术(第八周/第4次练习/4h)_第1张图片

  1. 把 hello.jsp转译为hello_jsp.jav
  2. hello_jsp.java 位于 d:\tomcat\work\Catalina\localhost_\org\apache\jsp
  3. hello_jsp.java是一个servlet
  4. 把hello_jsp.java 编译为hello_jsp.class
  5. 执行hello_jsp,生成html
  6. 通过http协议把html 响应返回给浏览器

2.include指令的作用:

在第一次学习这个指令的时候,只在想着这个指令是什么而在很大程度上忽略了它的作用。既然include指令将一个页面的jsp代码插入到另一个页面,那么我们可以将需要多次使用的页面元素,如页眉、页尾等,写到单独的jsp页面中,在以后使用时,通过include指令插入即可。

页尾元素代码:
Web应用技术(第八周/第4次练习/4h)_第2张图片
插入页尾元素:

<%@include file ="footer.jsp" %>

页尾元素实现效果:
Web应用技术(第八周/第4次练习/4h)_第3张图片

3.EL表达式语言与JSTL:

EL表达式常常与JSTL配合起来使用

关于EL表达式:

EL表达式的格式:

${参数}

(1)EL表达式用于取参数值与参数值的设定:

  • 在一个普通的JSP页面中,开启EL支持后使用 "${参数}"就可以向网页取出并输出参数的值,或者配合JSTL标签,设定JSTL标签定义变量的值,具体例子见下文。

(2)EL表达式的本质:

	EL表达式`${参数}`本质上还是一个JSP表达式,可以在 JSP 页面中用于获取变量值、执行函数等操作。而 `<%=参数 %>` 是一种 JSP 脚本表达式,可以在 JSP 页面中用于输出文本内容,但不支持 JSP EL(Expression Language)表达式的语法。也就是说用JSTL声明并赋值的参数是不可以用 `<%=参数 %>`调用的。值得一提的是,在Java片段中声明的变量,使用EL表达式也调用不了。但是,可以通过将这些变量存储在 request、session 或 application 等范围中,然后通过 EL 表达式获取对应范围中的变量值来实现在 JSP 页面中访问这些变量。
<%
    String name = "Tom";
    
    request.setAttribute("name", name);  
%>
<p>My name is ${requestScope.name}.p>

(3)开启EL表达式:

不同版本的tomcat是否默认开启对EL表达式的支持,是不一定的(Tomcat7.0默认开启)。我们可以通过在<%@page 标签里加上isELIgnored="false"
来开启EL表达式。

关于JSTL:

与HTML标签相似,JSTL标签分为一般标签和自闭和标签:
在使用JSTL标签库前,需要使用
<%@ taglib uri="http://java.sun.com/jsp/jstl/库名" prefix="引用前缀名"%>来引入标准库中的标签库,我们暂时以(可自定义)
以c表示访问标签库core的前缀
以fmx表示访问标签库fmx的前缀

一般标签:

一般标签是指需要使用开始标签和结束标签才能实现其功能的标签
(1)if else:
在正常的Java片段中的if-else的条件判断语句写在大括号中(可以使用逻辑操作符连接)

<c:if  bool  = " ${ hp < 5} ">
这个英雄状态不好
c:if>

(2)choose、when和otherwise:
标签组合起来可以实现类似于 switch 语句的功能

<c:choose>
  <c:when test="${dayOfWeek == 1}">
    <p>星期日p>
  c:when>
  <c:when test="${dayOfWeek == 2}">
    <p>星期一p>
  c:when>
  <c:when test="${dayOfWeek == 3}">
    <p>星期二p>
  c:when>
  <c:otherwise>
    <p>其他日p>
  c:otherwise>
c:choose>

(3)forEach:
标签用于迭代集合、数组或者其他可迭代对象中的元素。

<%
    List<String> heros = new ArrayList<String>();
    heros.add("塔姆");
    heros.add("艾克");
    heros.add("巴德");
    heros.add("雷克赛");
    heros.add("卡莉丝塔");
    request.setAttribute("heros",heros);
%>
 

<table width="200px" align="center" border="1" cellspacing="0">
<tr>
    <td>编号td>
    <td>英雄td>
tr>
   
<%
int i =0;
for (String hero : heros) {
i++;
%>
  
<tr>
    <td><%=i%>td>
    <td><%=hero%>td>
tr>
  
<%}%>
   
table>
 
<br>

<table width="200px" align="center" border="1" cellspacing="0">
<tr>
    <td>编号td>
    <td>英雄td>
tr>
   
<c:forEach items="${heros}" var="hero" varStatus="st"  >
    <tr>
        <td><c:out value="${st.count}" />td>
        <td><c:out value="${hero}" />td>
    tr>
c:forEach>
table>

(4)forTokens:
专门用于字符串拆分,并且可以指定多个分隔符:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  
<c:set var="heros" value="塔姆,艾克;巴德|雷克赛!卡莉丝塔" />
 
<c:forTokens items="${heros}" delims=":;|!" var="hero">
    <c:out value="${hero}" /> <br />

自闭合标签:

(1)set
set标签用于将一个值赋给指定的变量,供模板中其他部分使用

<c:set var="name" value="Tom" />
<h1>${name}h1>

(2)out
用来输出变量的一个标签

<c:set var="name" value="${'gareen'}" scope="request" />

通过标签获取name: <c:out value="${name}" />

其实也可以使用

${name}

直接向网页输出。
(3)remove
通过remove标签可以从作用域中移除一个变量或属性。

<c:set var="name" value="Tom" />
<c:set var="age" value="20" />
<c:remove var="name" />
<p>${name}p> 

(4)formatDate:
该标签用于格式化输出日期:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
    
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix='fmt' %>  

<%
	Date now = new Date();
	pageContext.setAttribute("now",now);
%>

完整日期: <fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/><br>
完整时间: <fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/><br>
常见格式: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>

Web应用技术(第八周/第4次练习/4h)_第4张图片
通过改变pattern中参数得组合可以输出不同格式得日期时间。
(5)formatNumber:

formatNumber用于格式化输出数字:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
    
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix='fmt' %>  

<c:set var="money" value="888.8" />
<c:set var="pi" value="3.1415926" />
最少两个小数点:
<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>
<br>
最多两个小数点:
<fmt:formatNumber type="number" value="${pi}" maxFractionDigits="2" />

4.JavaBean:

JavaBean指的是一种遵守特定规则的Java类,用于封装一组相关的数据和逻辑,通常包括了一个无参构造函数和通过get/set方法来获取和设置数据的一组属性。它可以被用于在JSP页面和Java程序之间传递和存储数据。

以下是一个JavaBean的实例对象:

package bean;
public class Hero {
    public int id;
    public String name;
    public float hp;
    public int damage;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getHp() {
        return hp;
    }
    public void setHp(float hp) {
        this.hp = hp;
    }
    public int getDamage() {
        return damage;
    }
    public void setDamage(int damage) {
        this.damage = damage;
    }
     
}

通常,JavaBean有以下标准:

1.使用public修饰符定义类,使用一个不带参的构造函数。

2.对应每个属性都有public的getter/setter方法。

3.getter/setter方法必须遵循JavaBeans命名规范,即get/set后跟着属性名的首字母大写版本,例如:getName()和setName()。

4.如果有属性是boolean,那么就对应is和setter方法。

5.可选地,JavaBean还可以实现Serializable接口,用于支持JavaBean实例的持久化。

5.JavaDao:

JavaDao(Data Access Object,数据访问对象)是使用Java语言编写的一种设计模式,用于将数据访问逻辑与业务逻辑分离,以提高代码的可维护性和可重用性。 简单来说,Java DAO 是表示数据访问层的类和接口的集合,它负责处理与数据库相互作用的所有代码。典型的 Java DAO 通常包含 CRUD(Create,Read,Update,Delete)操作,以及其他特定的数据访问逻辑。

写一个JavaDao通常有以下步骤:

(1)先写一个接口用于规范实现该接口必须有哪些方法:

public interface UserDao {
    public User findUserById(int id);
    public List<User> findAllUsers();
    public void insertUser(User user);
    public void deleteUser(int id);
    public void updateUser(User user);
}

(2)再写一个具体的JavaDao:

public class UserDaoImpl implements UserDao {
    // JDBC连接、预编译语句等的常量定义
    // ...

    @Override
    public User findUserById(int id) {
        // 使用JDBC访问数据库获取用户信息的代码
        // ...
        return user;
    }

    @Override
    public List<User> findAllUsers() {
        // 使用JDBC访问数据库获取所有用户信息的代码
        // ...
        return userList;
    }

    @Override    
    public void insertUser(User user) {
        // 使用JDBC访问数据库将用户信息插入到users表中的代码
        // ...
    }

    @Override
    public void deleteUser(int id) {
        // 使用JDBC访问数据库将用户信息从users表中删除的代码
        // ...
    }

    @Override
    public void updateUser(User user) {
        // 使用JDBC访问数据库更新用户信息的代码
        // ...        
    }
}

6.HTTP协议响应代码:

HTTP协议响应代码how2j写得挺有意思的

Web应用技术(第八周/第4次练习/4h)_第5张图片

HTTP协议响应代码的作用是告知客户端请求的处理结果。客户端发送HTTP请求到服务器,服务器根据请求的内容和状态进行处理,并通过响应代码告知客户端请求的处理结果。响应代码提供了一种标准化的方式,使得客户端能够根据不同的响应代码来采取相应的操作,例如显示请求结果、进行重定向、处理错误等。

以下是常见的HTTP协议响应代码的种类及其含义:

1xx(信息性状态码):

  • 100 Continue:服务器已收到请求的初始部分,并且客户端应继续发送其余部分。
  • 101 Switching Protocols:服务器已理解并接受客户端的请求,将切换到协议升级的新协议。

2xx(成功状态码):

  • 200 OK:请求成功,服务器正常处理请求并返回所需的数据。
  • 201 Created:请求已成功处理,并创建了新的资源。
  • 204 No Content:请求成功处理,但没有返回任何内容。

3xx(重定向状态码):

  • 301 Moved Permanently:请求的资源已永久移动到新位置。
  • 302 Found:请求的资源暂时移动到其他位置。
  • 304 Not Modified:客户端可以使用缓存的版本,无需从服务器重新获取。

4xx(客户端错误状态码):

  • 400 Bad Request:服务器无法理解请求,可能是请求语法有误。
  • 401 Unauthorized:请求需要身份验证。
  • 403 Forbidden:服务器拒绝请求,没有权限访问请求的资源。
  • 404 Not Found:请求的资源不存在。

5xx(服务器错误状态码):

  • 500 Internal Server Error:服务器在处理请求时遇到了错误。
  • 502 Bad Gateway:服务器作为网关或代理,从上游服务器接收到无效的响应。
  • 503 Service Unavailable:服务器暂时无法处理请求,通常是由于过载或维护。

6.JSP作用域:

JSP作用域是指在JSP页面中定义的变量在不同的范围内可见的能力。JSP作用域分为四种:page、request、session和application。

  • page作用域:变量仅在当前JSP页面中可见。在页面中定义的变量只能在当前页面中使用。

  • request作用域:变量在同一个HTTP请求中可见。在一个JSP页面中设置的变量可以在同一个请求中的其他JSP页面中使用。

  • session作用域:变量在同一个HTTP会话中可见。在一个JSP页面中设置的变量可以在同一个会话中的其他JSP页面中使用。

  • application作用域:变量在整个Web应用程序中可见。在一个JSP页面中设置的变量可以在整个应用程序的其他JSP页面中使用。

举一个简单的例子:

<%@ page language="java" %>
<html>
<head>
    <title>JSP作用域示例title>
head>
<body>
    <%-- page作用域 --%>
    <% 
        String name = "John";
        pageContext.setAttribute("name", name);
    %>
    <h1>Page作用域变量: <%= pageContext.getAttribute("name") %>h1>

    <%-- request作用域 --%>
    <%
        String age = "25";
        request.setAttribute("age", age);
    %>
    <h1>Request作用域变量: <%= request.getAttribute("age") %>h1>

    <%-- session作用域 --%>
    <%
        String email = "[email protected]";
        session.setAttribute("email", email);
    %>
    <h1>Session作用域变量: <%= session.getAttribute("email") %>h1>

    <%-- application作用域 --%>
    <%
        String phone = "123-456-7890";
        application.setAttribute("phone", phone);
    %>
    <h1>Application作用域变量: <%= application.getAttribute("phone") %>h1>

body>
html>

在这个示例中,我们定义了四个不同作用域的变量,分别是page、request、session和application。在JSP页面中,我们使用pageContext、request、session和application对象来设置和获取这些变量。在页面上,我们展示了每个作用域的变量值。

7.HttpServletRequest和HttpServletResponse

在Java Web开发中,HttpServletRequest和HttpServletResponse是两个非常重要的对象。

HttpServletRequest

HttpServletRequest对象代表了一个HTTP请求,包含了客户端发送给服务器的所有信息。它提供了许多方法来获取请求的信息,例如URL、请求参数、请求头、Session、Cookie等等。HttpServletRequest可以被用于处理用户提交的表单数据,或者读取客户端上传的文件。

下面是一个简单的代码示例,演示了如何使用HttpServletRequest对象:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name"); // 获取请求参数
        if (name == null || name.isEmpty()) {
            name = "World";
        }
        String message = "Hello, " + name + "!";

        request.setAttribute("message", message); // 设置请求属性

        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/views/hello.jsp");
        dispatcher.forward(request, response); // 转发请求
    }
}

在这个示例中,我们定义了一个Servlet,它通过HttpServletRequest获取了请求参数name,如果没有提供则默认为World。然后我们通过setAttribute()方法将一个消息存储到请求属性中,并使用RequestDispatcher将请求转发到一个JSP页面。

HttpServletResponse

HttpServletResponse对象代表了一个HTTP响应,包括了要发送给客户端的所有内容。它提供了许多方法来设置响应的状态码、响应头、Cookie、输出流等等。HttpServletResponse可以被用于返回文本、HTML、JSON、XML等各种类型的内容。

下面是一个简单的代码示例,演示了如何使用HttpServletResponse对象:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html"); // 设置响应类型

        PrintWriter out = response.getWriter(); // 获取输出流
        out.println("");
        out.println("

Hello, World!

"
); out.println(""); } }

在这个示例中,我们定义了一个Servlet,它通过setContentType()方法设置了响应类型为HTML。然后我们通过getWriter()方法获取输出流,并使用它输出了一些HTML内容。

总之,HttpServletRequest和HttpServletResponse是Java Web开发中非常重要的两个对象。它们分别代表了HTTP请求和响应,提供了许多方法来处理和生成Web页面。

8.中文编码问题:

见博客Web应用技术(第八周/第5次练习/2h)。

你可能感兴趣的:(前端,servlet,java)