Servlet

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层,使用 它可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页(前提是需要把Tomcat配置完成),准确的说它是服务 HTTP 请求并实现 javax.servlet.Servlet 接口的 Java 类。

Servlet生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

以上的都是类继承自HttpServlet,需要重写的这些方法

init() 方法

init 方法被设计成只调用一次,它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用,因此,它是用于一次性初始化的。

init 方法的定义如下: 

public void init() throws ServletException {
  // 初始化代码...
}

service() 方法

service方法是执行实际任务的主要方法,Servlet 容器(即 Web 服务器)调用 service方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端,每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务,service方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

service方法的定义如下:

public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{
          // Servlet 代码
}

service 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法,因此,不用对 service 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可,它们两个是最常用的方法,下面是两个方法的特点:

doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 或 HTML METHOD="get" 的表单,它由 doGet() 方法处理。

doGet方法的定义格式如下:

public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
    // Servlet 代码
}

doPost() 方法

POST 请求来自于一个特别指定了 METHOD = "POST"  的 HTML 表单,它由 doPost() 方法处理。

doPost方法的定义如下:

public void doPost(HttpServletRequest request,
                   HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

destroy() 方法

destroy 方法只会被调用一次,在 Servlet 生命周期结束时被调用,也就是服务器被关掉时调用,destroy 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动,在调用 destroy 方法之后,servlet 对象被标记为垃圾回收。

destroy 方法定义如下所示:

public void destroy() {
    // 终止化代码...
  }

使用 Servlet 读取表单数据

Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析(也就是请求,request 的重要方法):

  • getParameter("参数名");//可以调用 request.getParameter() 方法来获取表单参数的值。
  • getParameterValues("参数名");//如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。
  • getParameterNames("参数名");//如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。
  • setCharacterEncoding("解码的字符集"); //设置请求的字符编码
  • getMethod();//返回请求方式 get, post
  • getRequestURI(); // 返回当前的请求路径
  • getRemoteAddr();//获取访问者的ip地址

post 请求中的汉字会有乱码问题

原因:是因为浏览器解析编码使用的是iso-8859-1编码,会使中文编乱,因此要在getParameter 方法之前,调用setCharacterEncoding("字符编码"),这样可以解决该问题,请求和响应遇到乱码问题都可以通过设置字符编码解决问题。

代码演示

浏览器上显示日期,刷新会变动

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.Date;
//自定义路径,浏览器上显示的完整路径是http://localhost:8080/date
@WebServlet(urlPatterns = "/date")
public class MyServlet extends HttpServlet {

    @Override
    //                       req 请求                resp 响应
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应的字符编码
        resp.setCharacterEncoding("utf-8");
        // 告知浏览器,请浏览器用 utf-8 编码来显示
        resp.setContentType("text/html;charset=utf-8");
        Date date = new Date();
        String html = "<html><body><h1>当前时间是:" + date + "</h1></body></html>";
        // 将一段 html 作为响应内容,写入输出流,输出在浏览器
        resp.getWriter().print(html); // iso-8859-1 英文字符集
    }
}

结果

验证码的生成(动态图图片的生成)

import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
//自定义的一个路径,在浏览器中打入,http://localhost:8080/servlet2就可以搜到结果,不过你确定服务器打开哟
@WebServlet(urlPatterns = "/servlet2")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 图片验证码
        // 1. 创建图片对象, 构造参数分别代表 宽、高、图片格式
        BufferedImage image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB);

        // 2. 创建画布对象
        Graphics2D g = image.createGraphics();

        // 3. 填充画布
        g.setColor(Color.GREEN);//设置画布颜色,绿色
        g.fillRect(0,0,200,100);//设置画布大小
        // 写入文字
        g.setColor(Color.BLACK);//设置背景色,黑色
        g.setFont(new Font("微软雅黑", Font.ITALIC, 32));//设置字体样式,微软雅黑、粗体、字体大小32
        String s = random(4);//调用下面的随机生成验证码的方法
        g.drawString(s, 0, 32);

        g.setColor(Color.RED);//画一根斜线,阻挠判断
        g.drawLine(0,0,200,100);//斜线的位置

        // 4. 把图片内容输出到响应
        resp.setContentType("image/png");//设置响应的内容格式
        // 参数1 图片对象, 参数2 图片压缩格式 png|jpeg, 参数3: 输出字节流
        ImageIO.write(image, "png", resp.getOutputStream());
    }
    //随机生成验证码内容的方法,n表示要生成几位验证码,上面是4,因此显示四位验证码
    Random random = new Random();
    String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    public String random(int n) {
        StringBuilder sb = new StringBuilder(n);
        for (int i = 0; i < n; i++) {
            int idx = random.nextInt(str.length()); // 随机的下标
            sb.append(str.charAt(idx));
        }
        return sb.toString();
    }
}

结果

 

Jsp

JSP全称Java Server Pages,是一种动态网页开发技术,它使用JSP标签在HTML网页中插入Java代码,标签通常以<%开头以%>结束,它也是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。

Jsp生命周期

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

以下是JSP生命周期中所走过的几个阶段:

  • 编译阶段

        servlet容器编译servlet源文件,生成servlet类

  • 初始化阶段

        加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法

  • 执行阶段

       调用与JSP对应的servlet实例的服务方法

  • 销毁阶段

       调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

JSP 底层原理

在第一次发送请求时,会把 jsp 文件转义为 java(servlet) 代码,并进一步编译为 class 文件,把页面上的静态内容(html代码),使用 out.write 方法进行打印,其中 out 对应着响应的字符输出流,至于 `<% 代码 %>` 中的代码会原封不动搬移到 jsp 转义生成的 java 代码中,它的本质仍是一个 servlet。

引入标准标签库(简称jstl)

1. 引入标签库 jar包
   <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
   </dependency>
2. 在页面上声明要使用的标签库
   <%@ taglib prefix="标签前缀" uri="标签的唯一标识" %>   标签前缀可以随意起一个名字,这里取名为c,下面都以c为标签头
3、核心标签(uri="http://java.sun.com/jsp/jstl/core"

  •  forEach 进行遍历

  格式如下:
   <c:forEach items="要遍历的集合" var="临时变量名" begin="起始的下标" end="结束下标" varStatus="保存下标的对象">
   </c:forEach>   这里的c就是标签前缀

  •   if  条件判断

    <c:if test="条件">内容</c:if>

  •   choose  条件判断

     <c:choose>
         <c:when test="条件1">内容</c:when>
         <c:when test="条件2">内容</c:when>
         <c:when test="条件3">内容</c:when>

            ......
         <c:otherwise>内容</c:otherwise>
      </c:choose>

4、核心标签(uri="http://java.sun.com/jsp/jstl/fmt"),可以用来快速改变格式,如:日期,货币

  • formatNumber 改变数字格式

       <前缀名:formatNumber value="${变量名} pattern="数字格式">

      如:number为8888.8 ,<fmt:formatNumber value="${number} pattern="¤##,###.##">,¤表示货币符号,#表示一位数字 不够用0代替,结果为¥8,888.80,如果number为8888.8888,结果就为8,888.89

  • formatDate 改变日期格式

       <前缀名:formatDate value="${变量名} pattern="日期格式">

      如:<fmt:formatNumber value="${date} pattern="yyyy年MM月dd日 HH:mm:ss">,结果就为某年某月某日 时:分:秒

JSP新旧动态内容生成方式

  • 新的生成动态内容方式

         jstl 标签 + EL 表达式 (推荐)

 <%@page contentType="text/html;charset=utf-8" language="java"%>
       <html>
           <%
                 java代码
           %>
      </html>
  • 旧的生成动态内容的方式

        1)  <% 代码 %>      称为jsp脚本, 其中的变量是方法内的局部变量
        2)  <%= 表达式%>    称为jsp表达式, 用来输出值,不用加“;”结束
             如:使用jsp表达式获取作用域内容  <%= request.getAttribute("name") %>
                     使用el表达式获取作用域的内容  ${name}
        3)  <%! 代码 %>  jsp的声明, 其中的变量是类的成员变量
        4) 注释  <%-- 注释内容 --%>  会阻止java代码的运行,包括 jstl 标签和 EL 表达式 都可以使用这种办法注释
        5)  <%@ 指令名 %>
              page  用来指明页面的内容类型和编码方式 , isELIgnored="true|false" 表示是否忽略 EL 表达式
              taglib 用来引入一个标签库  prefix="前缀" uri="标签库的标识"
              include 用来执行页面的包含操作

              如:<%@ include file="文件路径" %>  用来引入外部文件

                      <%@ page contentype="text/html;charset=UTF-8" language="java" %>  指明页面的内容类型和编码方式以及程序语言

                      <%@ taglib prefix="标签前缀" uri="标签的唯一标识" %> 引入标签库

代码演示

浏览器上显示日期,刷新会变动<% 代码 %> 

<%@ page import="java.util.Date" %><%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2019/1/6 0006
  Time: 14:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>
    <%
        Date date = new Date();
        // out 就相当于 resp.getWriter() 响应输出流
        out.print(date);
    %>
    </h1>
</body>
</html>

结果

 

jsp 中的隐式对象 (9个)

  1.  pageContext 页面作用域
  2.  request 请求对象
  3.  session 会话对象
  4.  application 应用程序对象
  5.  response 响应对象
  6.  out 响应输出流
  7.  page 当前的jsp对象(this)
  8.  config 用来读取和jsp配置相关的信息
  9.  exception 必须在当前页面的 page 指令中添加 isErrorPage="true", 表示一个异常对象

 一个请求的结构

GET 两个部分

  1. GET 路径/HTTP 1.1  //请求行
  2. 请求头

          Host: 要访问那个虚拟主机 一个服务器下有多有 host, 每一个host 下,又有多个应用程序
          Accept: 可以处理的内容格式:例如 text/html
          Accept-Encoding : 能够支持的压缩格式
          Accept-Language : 支持的语言, 例如 zh-CN

POST 三个部分

  1.     Content-Type: 请求体的格式 application/www-form-urlencoded (普通表单格式)
  2.     Content-Length: 请求体内容的长度
  3.     请求体

            post的请求参数放入了请求体当中,例如:username=zhangsan&password=123,如果有中文,会自动编码 

响应的3个部分

1. 状态码

  •      200 表示响应正确返回
  •      404 表示请求的资源不存在
  •      500 表示服务器内部出现了异常
  •      304 表示该内容没有被修改,那么服务器只会返回状态码和头,不需要返回响应体(图片,html,css,js)
  •      400 请求参数格式有误.
  •      403 验证没通过,或权限不足

2. 响应头

  •      content-type: 响应的内容格式, 例如 text/html;charset=utf8
  •      content-length: 响应体的长度(字节)
  •      Date: 响应生成时间

3. 响应体

  •     html内容,图片内容

请求转发

servlet 中还是用来处理表单请求,用它跳转至 jsp (jsp 用来生成html代码并返回)这就是请求转发

request.getRequestDispatcher("jsp路径").forward(request, response);//用来请求转发的代码

如何把servlet中的变量传递给jsp显示

作用域传参

       request.setAttribute("变量名", 对象); 这个对象是object类型,也就是很支持很多种类型数据,如:集合、基本数据类型等

  • 取(在jsp页面),通过 EL(Expression Language) 表达式取

      ${ 变量名 }

     ${ 变量名.属性名 }    el 表达式中的属性名,对应着java对象中的 get,set方法名,如:getUsername(),el表达式为${变量名.username},这个变量名是从存中取的

jsp 中的 EL 表达式主要作用是从作用域中取出变量并显示,除此之外还可以在jsp中做一下事情:

  •  做简单运算

        <h3>算数运算 ${ 18 + 20 }</h3>
        <h3>比较运算 ${ 18 > 20 }</h3>
        <h3>逻辑与运算 ${ 18 > 20 and 19 < 30 }</h3>
       <h3>逻辑或运算 ${ 18 > 20 or 19 < 30 }</h3>
       <h3>逻辑非运算 ${ not (18 > 20) }</h3>
       <h3>三元运算 ${ (false)?"真":"假" }</h3>
       <h3>空运算 ${ empty names}</h3>       是空就返回true,否则false

   如:九九乘法表(下面是乘法表的jsp代码)

<%--指明页面的内容类型和编码方式以及程序语言--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--在表格中显示九九乘法表--%>
    <table border="1" width="100%">
        <%--外foreach循环输出一到九,再与内循环相乘,begin 开始循环的数字,end 结束循环的数字,var 变量名(随便起)表示开始到结束的数字,下面就用它表示1~9,不过要写在‘${}’中--%>
        <c:forEach begin="1" end="9" var="i">
            <tr>
                <c:forEach begin="1" end="${i}" var="j">
                    <td> ${j} * ${i} = ${i*j} </td>
                </c:forEach>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

  结果 

  •  用来显示作用域中的变量

         list集合 显示 可以用 [下标]
         list集合 显示大小  list集合名.size()
         map 显示  可以用 ${map集合名.键值}
         map 显示  可以用 ${map集合名["键值"]}
         map 显示  可以用 ${map集合名.get("键值")}
     建议map使用字符串作为key,如果非要用整数作为key,必须用 Long, 只能用[]语法取,不能用“.”语法,显示java bean(也就是调用“.”语法), 底层实际调用的是get方法,嵌套的对象可以多次调用“.”语法。

        param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值
        paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组

代码演示

 servlet和jsp的应用

1、显示作用域中的变量

存储信息的代码要实现序列化,因为这样把信息存储到硬盘中,这样不会使用结束后信息就消失了,写程序时分包最好把它分在domain包(domain object  领域对象 (entity实体对象, javabean, pojo (plain old java object)) 他们的都是同一种java类不同称呼,都具有私有属性,get set方法,用来封装数据),下面是Student和Address的数据存储代码

import java.io.Serializable;
import java.util.Date;

// domain object
// 1. 提供一个无参构造
// 2. 提供一个 toString (敏感信息不要放在 toString中)
// 3. 建议实现 Serializable 接口
// 私有属性, 有get set 方法: 称为 java Bean
public class Student implements Serializable {
    private String name;
    private String age;
    private Address homeAddress;

    public Address getHomeAddress() {
        return homeAddress;
    }

    public void setHomeAddress(Address homeAddress) {
        this.homeAddress = homeAddress;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
import java.io.Serializable;
public class Address implements Serializable {

    private String city;
    private String street;


    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

servlet代码

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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//指定页面的地址,搜索时要写上本地地址+指定页面地址
@WebServlet(urlPatterns = "/servlet3")
public class Servlet3 extends HttpServlet {
    //默认的请求是get方式因此只要doGet处理代码就好
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        req.setAttribute("names", list);

        Map<String, String> map = new HashMap<>();
        map.put("beijing", "北京");
        map.put("shanghai", "上海");
        req.setAttribute("cities", map);

        Map<Integer, String> map2 = new HashMap<>();
        map2.put(1, "张三丰");
        map2.put(2, "王重阳");
        req.setAttribute("gaoshou", map2);


        Address addr = new Address();
        addr.setCity("西安");
        addr.setStreet("太白南路");
        Student student = new Student();
        student.setName("王二");
        student.setAge("18");
        student.setHomeAddress(addr);

        req.setAttribute("s1", student);
        //请求转发到el1.jsp页面,也就是把数据显示到这个页面上
        req.getRequestDispatcher("el1.jsp").forward(req, resp);
    }
}

jsp页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <%-- items="要遍历的集合" var="临时变量名"
           临时变量中存储的是每次循环中第i个元素
           在循环中再利用 ${} 显示临时变量的值 --%>
    <!-- s 中 getIndex() 获取下标值, getCount() 获取下标值(从1开始)  -->
    <c:forEach items="${names}" var="n" varStatus="s">
        <p>${s.count} ${n}</p>
    </c:forEach>

    <%--遍历names集合--%>
    <ul>
        <c:forEach items="${names}" var="n">
            <li>${n}</li>
        </c:forEach>
    </ul>

    <%--如果names集合为空就显示暂无数据--%>
    <c:if test="${ empty names }">
        <table border="1" width="100%">
            <tr><td>暂无数据</td></tr>
        </table>
    </c:if>

    <%--如果names集合不为空就显示names集合的内容,标签中的if没有else,因此要写相反的条件达成目标--%>
    <c:if test="${ not empty names}">
        <table border="1" width="100%">
            <c:forEach items="${names}" var="n">
                <tr>
                    <td>${n}</td>
                </tr>
            </c:forEach>
        </table>
    </c:if>

    <!-- items 中如果不用 el 表达式,那么会把 names 当成一个字符串-->
    <c:forEach items="names" var="n">
        <p>${n}</p>
    </c:forEach>

    <!-- 遍历 map 集合, entry 对象 entry中有getKey(), getValue() -->
    <ul>
        <c:forEach items="${cities}" var="e" >
            <li>${e.key}  ----  ${e.value} </li>
        </c:forEach>
    </ul>

    <%--遍历输出1~9--%>
    <c:forEach begin="1" end="9" var="i">
        ${i}
    </c:forEach>
    
    <%--param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值--%>
    <%--paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组--%>
    <h3>${ param.ername }</h3>
    <h3>${ param["username"] }</h3>
    <h3>${ paramValues.hobby[0] } ${ paramValues.hobby[1] }</h3>

    <h3>算数运算 ${ 18 + 20 }</h3>
    <h3>比较运算 ${ 18 > 20 }</h3>
    <h3>逻辑运算 ${ 18 > 20 and 19 < 30 }</h3>
    <h3>逻辑运算 ${ 18 > 20 or 19 < 30 }</h3>
    <h3>逻辑运算 ${ not (18 > 20) }</h3>
    <h3>三元运算 ${ (false)?"真":"假" }</h3>
    <h3>空运算 ${ empty names}</h3>

    <h3>显示list的数据 ${names[1]} </h3>
    <h3>显示list的数据 ${names.size()}  getSize()</h3>

    <h3>
        显示map的数据 ${ cities.beijing }
    </h3>
    <h3>
        显示map的数据 ${ cities["beijing"] }
    </h3>
    <h3>
        显示map的数据 ${ cities.get("beijing") }
    </h3>
    <h3>
        ${ gaoshou[1] }
    </h3> 
    <h3>
        显示学生对象的信息
        ${s1.name} ${s1.age}
        ${s1.homeAddress.city} ${s1.homeAddress.street}
    </h3>
<h3>
</h3>
</body>
</html>

结果

注:符号“.”中调用的不是属性,而是get或set方法,页面会自动识别该名字,然后让首字母大写后面加上小括号,接着在前面加上get或set,等同于直接调用get或set方法

2、网页提交的信息显示在服务器上

jsp中的代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script>
        function checkEmail() {
            // 获取用户填写的邮箱值
            var value = document.getElementById("email").value;
            if(/^\w+@\w+(\.(com|net|cn)){1,2}$/.test(value)){
                document.getElementById("emailMsg").innerText = "邮箱格式正确";
                return true;
            } else {
                document.getElementById("emailMsg").innerText = "邮箱格式错误";
                return false;
            }
        }
        function checkPass() {
            // 获取用户填写的密码
            var value = document.getElementById("pass").value;
            if(value.length >= 6) {
                document.getElementById("passMsg").innerText ="密码格式正确";
                return true;
            } else {
                document.getElementById("passMsg").innerText ="密码必须6位以上";
                return false;
            }
        }
        //判断是否可以提交,如果密码和邮箱填对,那么与运算就是true,验证也就通过,反之则不行
        function checkAll() {
            return checkEmail() && checkPass();
        }
    </script>
</head>
<body>
<a href="1.html">跳转至1.html</a>
    <!-- onsubmit 事件 会在表单提交之前触发,如果 它返回为真表单可以提交, 如果返回为假,表单就不能提交了 -->
    <form action="servlet1" method="post" onsubmit="return checkAll()">
        <p> 邮箱地址  <input type="text" name="email" onblur="checkEmail()" id="email"/> <span id="emailMsg"></span> </p>
        <p> 密码  <input type="password" name="password" onblur="checkPass()" id="pass"/> <span id="passMsg"></span> </p>
        <p>
       男 <input type="radio" name="sex" value="男" checked>
       女 <input type="radio" name="sex" value="女">
        </p>

        <p>
            睡觉 <input type="checkbox" name="hobby" value="睡觉">
            玩游戏 <input type="checkbox" name="hobby" value="玩游戏">
            刷微博 <input type="checkbox" name="hobby" value="刷微博">

        </p>
        <p>
            <!-- option 没有给 value, 就会把文字发送给服务器,如果给了 value, 会把 value 的值发给服务器, multiple 表示可以多选-->
            <select name="city" multiple>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="shengzhen">深圳</option>
            </select>
        </p>
        <p>
            <!-- 没有给 value, 就会把文字发送给服务器 -->
            <select name="city2" multiple>
                <option >北京</option>
                <option >上海</option>
                <option >深圳</option>
            </select>
        </p>
        <p>
            <!-- disabled(不可修改,忽略) 的表单项 提交时不会发送给服务器,readonly(只读,也是不可修改,不忽略) 的表单项 提交时会发送给服务器-->
            <input type="text" name="username" value="张三" readonly />

        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

servlet中的代码,结果输出到服务器

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.Arrays;
//自定义地址
@WebServlet(urlPatterns = "/servlet1")
public class Servlet1 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置解码的字符集, 必须出现在 getParameter 方法调用之前
        req.setCharacterEncoding("utf-8");


        //获取表单参数的值,getParameter只能获取一个值,这里这个参数是单选框的name的值,这样可以获取sex的value的值
        String sex = req.getParameter("sex");
        System.out.println("性别是:" + sex);


        // 如果一个请求参数有多个值,用getParameterValues,这里获取的是复选框的value值
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("爱好是:" + Arrays.toString(hobbies));

        //输出给 value 的 select,输出的是 value 中的值
        String[] cities = req.getParameterValues("city");
        System.out.println("城市是:" + Arrays.toString(cities));
        
        //输出没有给 value 的 select,输出的是 <option > 标签之中的值
        String[] cities2 = req.getParameterValues("city2");
        System.out.println("城市是:" + Arrays.toString(cities2));
        
        //获取文本框的值,文本框的 name 的值是 username
        String username = req.getParameter("username");
        System.out.println("用户名:" + username);

        System.out.println("=====================");
        System.out.println("请求方式:" + req.getMethod());//获得请求方式,get或post
        System.out.println("请求地址:" + req.getRequestURI());//获得请求地址,当前地址
        System.out.println("远程地址:" + req.getRemoteAddr()); //获取远程地址 0:0:0:0:0:0:0:1 ipv6 等价于  127.0.0.1  ipv4
    }
}

结果

jsp中的结果

服务器中显示的结果

性别是:女
爱好是:[睡觉]
城市是:[shanghai]
城市是:[北京]
用户名:张三
=====================
请求方式:POST
请求地址:/servlet1
远程地址:0:0:0:0:0:0:0:1

总结

Servlet 与 JSP的内容很多,容易弄混作用域,以及容易让人弄混跳转的地址,可以这么说通过Servlet把请求的信息通过JSP表示的格式显示出来,爱生活,爱Java。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐