1.Servlet简介

JavaWeb开发专题(五)-Servlet开发入门_java
我们之前学习的html技术是一种静态的网页技术,即不管在何时、何地、由谁来访问,效果都是一样的。而事实上,我们平时浏览的一些网页,90%以上都不是一成不变的,在不同的时间或者由不同的人来访问,可能就会显示不同的内容,例如,购物网站中的购买记录,张三登录时显示的是张三的,而李四登录时显示的是李四的,而他们查看的都是"购买记录页面",但内容却是不同的,单纯使用静态html技术是不可能做到这一点的,静态html已经无法满足用户的需求了!在明确了这一点之后,Sun公司就开发了一种可以生成动态html的技术,在使用这个技术编写动态网页时,需要遵守Sun公司制定的规范 – Servlet接口。

Servlet=servlet+applet(服务器端小程序) 负责在服务器端接收用户的请求。好比说饭店的服务员。

Servlet是Sun公司提供的一门用于开发动态web资源的技术。
运行在服务器端,一个小的Java程序。它可以接收从web浏览器发送过来的请求,也可以给浏览器产生相应。通常使用超文本传输协议(HTTP)
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet。
JavaWeb开发专题(五)-Servlet开发入门_html_02

Servlet/JSP是SUN公司定义的一套动态网页开发的技术。

2.Servlet快速入门

步骤:

  • 创建类实现Servlet接口(着重关注service方法)
package servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloServlet implements Servlet {
// 在当前类的实例创建完成之后执行的初始化方法
public void init(ServletConfig arg0) throws ServletException {
}
// 当前实例销毁时执行的方法
public void destroy() {
}
// 当前实例的配置信息
public ServletConfig getServletConfig() {
return null;
}
// 获取当前类信息
public String getServletInfo() {
return null;
}

/*
* 为请求提供服务的方法
* request:请求对象,其中包含请求中的所有数据
* response:响应对象,专门给客户端响应数据的
*/
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.getWriter().write("<html>");
response.getWriter().write("<head>");
response.getWriter().write("<title>this is title</title>");
response.getWriter().write("</head>");

response.getWriter().write("<body>");
response.getWriter().write("<h1>Hello</h1>");
response.getWriter().write("</body>");

response.getWriter().write("</html>");
}
}
  • 在web.xml进行servlet的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>web13</display-name>
<!-- 配置Servlet -->
<servlet>
<!-- Servlet的名字,可以自定义 -->
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<!-- 配置路径的映射 -->
<servlet-mapping>
<!-- Servlet的名字,必须和servlet标签中的一致 -->
<servlet-name>HelloServlet</servlet-name>
<!-- Servlet的访问路径 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>


<!-- 首页的默认地址 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
  • 启动测试
    访问地址:http://127.0.0.1:8080/hello

执行流程:
JavaWeb开发专题(五)-Servlet开发入门_html_03

3.Servlet的生命周期

生命周期就是指Servlet这个对象从生到死的整个过程,叫做生命周期。就像一个小孩出生、取名字、上学、工作、退休、死亡…
JavaWeb开发专题(五)-Servlet开发入门_xml_04
阶段1:tomcat容器给Servlet创建了对象!第一次请求就Servlet创建对象,创建对象只创建一次! Servlet是单例的!!!整个项目每个Servlet只会创建一个对象!

阶段2:对象创建完毕后,会调用初始化方法,初始化方法只会调用一次!

阶段3:针对请求进行处理,每次请求都会调用service方法,Service方法是提供服务的方法,每次请求都会调用一次!

阶段4:服务器关闭,那么Servlet自动死亡!调用Destory()方法。死亡一次!

JavaWeb开发专题(五)-Servlet开发入门_xml_05

4.HttpServlet类

在实际开发中,我们不会直接去实现Servlet接口,因为那样需要实现的方法太多。而是创建一个类,然后继承HttpServlet,HttpServlet是Tomcat针对HTTP协议的一个Servlet实现类,我们只需要重写其中的某些方法即可。
步骤:
1.定义一个类,继承HttpServlet
JavaWeb开发专题(五)-Servlet开发入门_html_06
2.快捷键:Shift+Alt+S,重写HttpServlet中的service方法,快捷键:Alt + Shift + S
JavaWeb开发专题(五)-Servlet开发入门_java_07

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("all")
public class DemoServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("hello");
}
}

3.在核心配置文件web.xml中配置Servlet程序

<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

4.发布项目到tomcat,启动tomcat,测试:在浏览器的地址栏输入http://127.0.0.1:8080/web09/hello
JavaWeb开发专题(五)-Servlet开发入门_xml_08

5.使用eclipse直接创建Servlet

JavaWeb开发专题(五)-Servlet开发入门_java_09
JavaWeb开发专题(五)-Servlet开发入门_xml_10
JavaWeb开发专题(五)-Servlet开发入门_html_11
Servlet创建好了,比较凌乱,稍微整理一下:

public class QuickServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

web.xml也自动生成好了servlet的相关配置
JavaWeb开发专题(五)-Servlet开发入门_xml_12
启动服务器,访问测试:
​​​ http://127.0.0.1:8080/quickServlet​

6.Servlet3.0使用注解的方式

  • 传统的方式
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.web.controller.ActionServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>/ActionServlet</url-pattern>
</servlet-mapping>

发一个Servlet,都要在web.xml中配置Servlet才能够使用,这实在是很头疼的事情,所以Servlet3.0之后提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述,简化开发流程。

  • 注解的方式
@WebServlet(value = "/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Hello,Web!!");
}
}

7.HttpServletRequest对象

7.1.HttpServletRequest简介

JavaWeb开发专题(五)-Servlet开发入门_xml_13
定义将客户端请求信息提供给某个 servlet 的对象。servlet 容器创建 ServletRequest 对象,并将该对象作为参数传递给该 servlet 的 service方法。
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

小结: 客户端请求协议都是基于HTTP所以我们选用HttpServletRequest来操作用户发送过来的请求的数据
跟请求相关信息都是去找HttpServletRequest对象!

7.2.HttpServletRequest获取表单参数

  • html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<h2>用户注册</h2>
<hr/>
<form action="UserServlet.do?action=register" method="post">
账号:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
性别:<input type="radio" name="sex" value="1" checked="checked"/>
<input type="radio" name="sex" value="0"/><br/>
爱好:<input type="checkbox" name="hobby" value="足球"/>足球
<input type="checkbox" name="hobby" value="篮球"/>篮球
<input type="checkbox" name="hobby" value="排球"/>排球
<input type="checkbox" name="hobby" value="悠悠球"/>悠悠球<br/>
<input type="submit" value="注册"/>
<input type="reset" value="取消"/>
</form>
</body>
</html>
  • Servlet程序
// 接收表单的值
String username = request.getParameter("username");
String password = request.getParameter("password");
String sex = request.getParameter("sex");
String[] hobby = request.getParameterValues("hobby");

// 封装成一个对象
Student s = new Student(username, password, sex, hobby);
System.out.println(s);

8.常见的请求方式 (get/post)

表单如果不指定,默认的请求方式是GET请求
点击超链接,直接浏览器输入地址 都属于get请求

8.1 GET请求

  • 参数传递方式 GET请求在浏览器地址栏传参数,以?分割URL和传输数据,参数之间以&相连
    JavaWeb开发专题(五)-Servlet开发入门_java_14
  • 数据量限制 GET提交的数据大小有限制(因为浏览器对URL的长度有限制)
  • 安全问题 GET方式提交数据,会带来安全问题(地址栏显示出来)
  • 乱码处理方式 每个参数都要处理
    JavaWeb开发专题(五)-Servlet开发入门_html_15

Tomcat8的版本中GET基本就不会乱码了,因为服务器对url的编码格式可以进行自动转换

8.2 GET优点

  • 效率高
  • 使用get场合:传递少量的非敏感的参数

8.3 POST请求

  • 参数传递方式
    POST方法是把提交的数据放在HTTP包的Body中(地址栏看不到)
  • 数据量限制
    POST方法提交的数据没有限制 (文件上传必须是POST)
  • 安全问题
    POST提交的数据相对安全
  • 乱码处理方式
    统一处理所有
    JavaWeb开发专题(五)-Servlet开发入门_java_16

8.4 POS优点

  • 安全性好
  • 传递数量大
  • 文件上传必须是POST请求(后期讲)

10.注册案例

10.1. 注册功能分析

注册的本质:将用户填写的数据添加到数据库的过程。
JavaWeb开发专题(五)-Servlet开发入门_java_17

10.2. 注册页面register.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>注册页面</title>
<style type="text/css">
*{font-size:14px;}
td:first-child{text-align:right;}
td:last-of-type a{vertical-align:middle;}
a:ACTIVE,a:VISITED {color:blue;}
#checkImg{vertical-align: middle;}
</style>
</head>
<body>
<center>
<form action="/register/regServlet" method="post">
<table>
<tr>
<td>用户名:</td>
<td>
<input type="text" name="username"/>
<font color="red"> *</font>
</td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password"/>
<font color="red"> *</font>
<font id="passwordMsg" color="red"></font>
</td>
</tr>
<tr>
<td>确认密码:</td>
<td>
<input type="password" name="repassword"/>
<font color="red"> *</font>
<font id="repasswordMsg" color="red"></font>
</td>
</tr>
<tr>
<td>年龄:</td>
<td><input type="text" name="age"/></td>
</tr>
<tr>
<td>性别:</td>
<td>
<input type="radio" name="sex" value="男"/>
<input type="radio" name="sex" value="女"/>
</td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="text" name="email"/></td>
</tr>
<tr>
<td>生日:</td>
<td><input type="text" name="birthday" /></td>
</tr>
<tr>
<td>擅长的技术:</td>
<td>
<input type="checkbox" name="hobby" value="C"/>C
<input type="checkbox" name="hobby" value="C++"/>C++
<input type="checkbox" name="hobby" value="Java"/>Java
<input type="checkbox" name="hobby" value="IOS"/>IOS
<input type="checkbox" name="hobby" value="PHP"/>PHP
<input type="checkbox" name="hobby" value="Android"/>Android
</td>
</tr>
<tr>
<td>地址:</td>
<td>
<select name="address">
<option value="none">--请选择地址--</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="南京">南京</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
</td>
</tr>
<tr>
<td>自我描述:</td>
<td>
<textarea cols="50" rows="5" name="description"></textarea>
</td>
</tr>
<tr>
<td></td>
<td style="text-align:left;padding-top:10px;">
<input type="submit" value="注册" />
<a href="login.jsp">登录</a></td>
</tr>
</table>
</form>
</center>
</body>
</html>

10.3.注册的Servlet

package servlet.request;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import util.JDBCUtils;

@SuppressWarnings("all")
public class RegisterServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决响应乱码问题
response.setContentType("text/html; charset=UTF-8");

// 解决请求中的中文乱码问题:只能解决post请求的乱码
request.setCharacterEncoding("UTF-8");

// 1. 获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String age = request.getParameter("age");
String sex = request.getParameter("sex");
String email = request.getParameter("email");
String birthday = request.getParameter("birthday");
// 爱好是多值,需要使用getParameterValues获取
String[] hobby = request.getParameterValues("hobby");
String hobbies = "";
for (String h : hobby) {
hobbies += "," + h;
}
// ,1,2,3
hobbies = hobbies.substring(1);
String address = request.getParameter("address");
String description = request.getParameter("description");

// 将数据入库
// 获取连接对象
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
pstmt = conn.prepareStatement("insert into user values(null,?,?,?,?,?,?,?,?,?)");
pstmt.setString(1, username);
pstmt.setString(2, password);
pstmt.setString(3, age);
pstmt.setString(4, sex);
pstmt.setString(5, email);
pstmt.setString(6, birthday);
pstmt.setString(7, hobbies);
pstmt.setString(8, address);
pstmt.setString(9, description);

pstmt.executeUpdate();
String appName = request.getContextPath();
response.getWriter().write("注册成功!<a href='"+appName+"/login.html'>立即登录</a>");

} catch (SQLException e) {
e.printStackTrace();
response.getWriter().write("系统正在维护,请稍后再试...");
} finally {
JDBCUtils.release(conn, pstmt, null);
}
}
}