配置Servlet环境
-
idea配置Maven
-
idea配置tomcat
-
配置Servlet
pom.xml中导入Servlet API依赖包
<!-- 加入 servlet 依赖 -->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId>
<!-- servlet 版本和 tomcat 版本有对应关系,切记 -->
<version>3.1.0</version>
<!-- 这个意思是我们只在开发阶段需要这个依赖,部署到 tomcat 上时就不需要了 -->
<scope>provided</scope>
</dependency>
</dependencies>
刷新Maven即可生成
Servlet
Servlet的框架是由两个Java包组成:javax.servlet和javax.servlet.http. 在javax.servlet包中定义了所有的Servlet类都必须实现或扩展的的通用接口和类.在javax.servlet.http包中定义了采用HTTP通信协议的HttpServlet类.
- servlet的生命周期
init方法,负责初始化Servlet对象.
service方法,负责相应客户的请求.
destory方法,当Servlet对象退出声明周期时,负责释放占有的资源.
HttpServlet
HttpServlet是Servlet接口的一个实现类,并且它是一个抽象类,servlet.http包中定义了采用HTTP通信协议(一个无状态协议)的HttpServlet类。
- URL的查找过程
- 响应流程
1.Web客户端向Servlet容器发出Http请求
2.Servlet容器解析Web客户的Http请求
3.Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息
4.Servlet容器创建一个HttpResponse对象
5.Servlet容器调用HttpServlet的service方法,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象
6.HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息
7.HttpServlet调用HttpResponse的有关方法,生成响应数据
8.Servlet容器把HttpServlet的响应结果传给Web客户
其中HttpServlet首先必须读取Http请求的内容,Servlet容器负责创建HttpServlet对象,并把Http请求直接封装到HttpServlet对象中。
- 创建HttpServlet步骤
1.继承HttpServlet抽象类
2.重写HttpServlet的部分方法,如doGet()或doPost()方法
3.获取HTTP请求信息。通过HttpServletRequest对象来检索HTML表单所提交的数据或URL上的查询字符串
4.生成HTTP响应结果。通过HttpServletResponse对象生成响应结果
方式1-表单提交
<!--method是请求方法 action是请求路径不带任何反斜杠-->
<form method="post" action="login">
<!--name表示请求数据的键-->
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
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;
//注解映射服务路径
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
/**
* 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
* 如果请求方法没有重写,就调用父类的doXXX(对应请求方法),返回405
* 如果重写,会将请求数据包装为一个Request请求对象,这时候虽然还没有响应,但是也
* 包装了一个Response响应对象
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求,响应编码,及响应数据类型(为响应体设置Content-Type数据类型)
req.setCharacterEncoding("UTF-8");//设置请求体编码
resp.setCharacterEncoding("UTF-8");//响应体编码
resp.setContentType("text/html");//响应体数据类型
//解析数据
//request.getParameter方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
String u = req.getParameter("username");
String p = req.getParameter("password");
System.out.printf("=====================用户名(%s)密码(%s)%n", u, p);
//返回响应数据
PrintWriter pw=resp.getWriter();
pw.println("登录成功");
pw.println("<h3>欢迎你,"+u+"</h3>");
pw.flush();//数据缓存-不缓存可能没有数据
pw.close();//响应完毕一定要关闭响应流
}
}
方式2-Ajax异步请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
<!--导入js-->
<script type="text/javascript" src="js/jquery@3.3.1/jquery.js"></script>
<script>
$(function(){
$("#loginBtn").click(function (){
$.ajax({
type:"post",
url:"loginJSON",
dataType:"json",
data:{
username:$("#username").val(),
password:$("#password").val(),
},
success(r){
//alert(JSON.stringify(r));
if(r.success){
//alert("登陆成功")
//隐藏标签
$("#container").hide();
}else{
alert("用户名或密码错误");
}
}
})
}
)
})
</script>
</head>
<body>
<div id="container">
用户名:<input id="username" type="text" name="username"/><br />
密码:<input id="password" type="password" name="password"/><br />
<input id="loginBtn" type="button" value="登录" />
</div>
<p>第一篇文章</p>
<p>第二篇文章</p>
<p>第二篇文章</p>
</body>
</html>
LoginJSON
package org.example.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.io.PrintWriter;
@WebServlet("/loginJSON")
public class LoginJSONServlet extends HttpServlet {
/**
* 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
* 如果请求方法没有重写,就调用父类的doXXX(对应请求方法),返回405
* 如果重写,会将请求数据包装为一个Request请求对象,这时候虽然还没有响应,但是也
* 包装了一个Response响应对象
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求,响应编码,及响应数据类型(为响应体设置Content-Type数据类型)
req.setCharacterEncoding("UTF-8");//设置请求体编码
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json");
//解析数据
//request.getParameter方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
String u = req.getParameter("username");
String p = req.getParameter("password");
System.out.printf("=====================用户名(%s)密码(%s)%n", u, p);
//返回响应数据
PrintWriter pw=resp.getWriter();
//JSON数据
if("abc".equals(u)&&"123".equals(p)){
pw.println("{\"success\": true}");
}else{
pw.println("{\"success\": false}");
}
pw.flush();
pw.close();
}
}
请求转发和请求重定向
- 请求转发
请求转发: xxServlet收到请求,然后直接转发给yyServlet,然后yyServlet返回给客户端。整个过程中,客户端发出一个请求,收到一个响应。
- 重定向
重定向:xxServlet收到请求,然后发出一个响应给客户端,客户端立即又发送一个请求访问xxServlet中给的URL,即yyServlet的路径,然后yyServlet给客户端一个响应。整个过程中,客户端发出两个请求,收到两个响应。
- 实现方法
请求转发:利用RequestDispather接口中的forward方法实现请求转发。
请求重定向:利用HttpServletResponse的sendRedirect方法实现请求重定向。
- 区别
- 转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
- 转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;
- 转发是服务器行为,重定向是客户端行为;
- 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求的;
- 转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围
- 实现
login.html
<form method="post" action="login301">
<!--name表示请求数据的键-->
用户名:<input type="text" name="username"/> <br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
home.html
<div id="container">
用户名:<input id="username" type="text" name="username"/><br />
密码:<input id="password" type="password" name="password"/><br />
<input id="loginBtn" type="button" value="登录" />
</div>
<p>第一篇文章</p>
<p>第二篇文章</p>
<p>第二篇文章</p>
Login301Servlet.java
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;
@WebServlet("/login301")
public class Login301Servlet extends HttpServlet {
/**
* 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
* 如果请求方法没有重写,就调用父类的doXXX(对应请求方法),返回405
* 如果重写,会将请求数据包装为一个Request请求对象,这时候虽然还没有响应,但是也
* 包装了一个Response响应对象
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求,响应编码,及响应数据类型(为响应体设置Content-Type数据类型)
req.setCharacterEncoding("UTF-8");//设置请求体编码
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
//解析数据
//request.getParameter方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
String u = req.getParameter("username");
String p = req.getParameter("password");
System.out.printf("=====================用户名(%s)密码(%s)%n", u, p);
if("abc".equals(u)&&"123".equals(p)){
//重定向
resp.sendRedirect("home.html");
}else if("abc".equals(u)){
//转发
req.getRequestDispatcher("home.html").forward(req,resp);
}else{
//返回响应数据
PrintWriter pw=resp.getWriter();
pw.println("登录失败");
pw.println("<h3>用户名,"+u+"或密码错误</h3>");
pw.flush();
pw.close();
}
}
}
请求转发图
请求重定向