- 1.概念
- 2.请求消息:客户端发送给服务器端的数据
- (1)请求行
- (2)请求头:客户端浏览器告诉服务器一些信息
- (3)请求空行
- (4)请求体(正文):
- 3.Request
- (1)request对象和response对象的原
- (2)request对象继承体系结构
- (3)request功能
- 1)获取请求消息数据
- 2)获取请求头数据
- 3)获取请求体数据
- 4)其他功能
- 获取请求参数通用方式
- 请求转发
- 共享数据
- 获取ServletContext(现在只是获取该对象,后面会具体讲解)
- 4.案例:用户登录
- (1)用户登录案例需求
- (2)分析
- (3)开发步骤
- 5.响应消息:服务器端发送给客户端的数据
- (1)数据格式
- 1)响应行
- 2)响应头
- 3)响应空行
- 4)响应体:传输的数据
- 6.Response对象
- (1)功能:设置响应消息
- (2)案例
- 1)完成重定向
- 重定向
- 重新向和转发的区别
- 路径写法
- 2)服务器输出字符数据到浏览器
- 步骤
- 注意
- 3)服务器输出字节数据到浏览器
- 4)验证码
- 7.ServletContext对象
- (1)概念
- (2)获取ServletContext对象
- (3)功能
- 8.案例
- (1)文件下载需求
- (2)分析
- (3) 步骤
- (4)问题:中文文件问题
- HTTP:Hyper Text Transfer Protocol 超文本传输协议
- 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求/响应模型的:一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
- 历史版本:
- 1.0:每一次请求响应都会建立新的连接
- 1.1:复用连接
POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*
@WebServlet("/requestServletDemo1")
public class ServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求方式 :GET,使用String getMethod()
String method = request.getMethod();
System.out.println(method);
//获取虚拟目录:/day14,使用String getContextPath()
String contextPath = request.getContextPath();
System.out.println(contextPath);
//获取Servlet路径: /demo1,使用String getServletPath()
String servletPath = request.getServletPath();
System.out.println(servletPath);
//获取get方式请求参数:name=zhangsan,使用String getQueryString()
String queryString = request.getQueryString();
System.out.println(queryString);
//获取请求URI:/day14/demo1,使用
//String getRequestURI() : /day14_war_exploded/requestServletDemo1
//StringBuffer getRequestURL() : http://localhost:8080/day14_war_exploded/requestServletDemo1
String requestURI = request.getRequestURI();
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURI);
System.out.println(requestURL);
//获取协议及版本:HTTP/1.1,使用String getProtocol()
String protocol = request.getProtocol();
System.out.println(protocol);
//获取客户机的IP地址,使用String getRemoteAddr()
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
2)获取请求头数据
- String getHeader(String name):通过请求头的名称获取请求头的值
- Enumeration getHeaderNames():获取所有的请求头名称
@WebServlet("/requestServletDemo2")
public class ServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Enumeration getHeaderNames():获取所有的请求头名称
Enumeration headerNames = request.getHeaderNames();
//遍历
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//String getHeader(String name):通过请求头的名称获取请求头的值
String value = request.getHeader(name);
System.out.println(name + ":" + value);
}
}
}
@WebServlet("/requestServletDemo3")
public class ServletDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//String getHeader(String name):通过请求头的名称获取请求头的值
String header = request.getHeader("user-agent");
if(header.contains("Chrome")){
System.out.println("通过谷歌浏览器访问。。。");
}else if(header.contains("Firefox")){
System.out.println("通过火狐浏览器访问。。。");
}else{
System.out.println("通过其他浏览器访问。。。");
}
}
}
3)获取请求体数据
- 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
- 步骤:
- 获取流对象
- BufferedReader getReader():获取字符输入流,只能操作字符数据
- ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
- 再从流对象中拿数据
- 获取流对象
@WebServlet("/requestServletDemo5")
public class ServletDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取流对象
BufferedReader br = request.getReader();
String line = null;
//2.再从流对象中拿数据
while((line = br.readLine()) != null){
System.out.println(line);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
注册页面
- 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
- String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
- String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
- Enumeration
getParameterNames():获取所有请求的参数名称 - Map
getParameterMap():获取所有参数的map集合 - 中文乱码问题:
- get方式:tomcat 8 已经将get方式乱码问题解决了
- post方式:会乱码
- 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
@WebServlet("/requestServletDemo6")
public class ServletDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
String username = request.getParameter("username");
System.out.println(username);
System.out.println("============================");
//2.String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies){
System.out.println(hobby);
}
System.out.println("============================");
//3.Enumeration getParameterNames():获取所有请求的参数名称
Enumeration parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
System.out.println("------------------------");
}
System.out.println("============================");
//4.Map getParameterMap():获取所有参数的map集合
Map parameterMap = request.getParameterMap();
Set keySet = parameterMap.keySet();
for(String key : keySet){
String[] values = parameterMap.get(key);
for (String value : values){
System.out.println(value);
}
System.out.println("************************");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
注册页面
中文乱码问题解决方式:
package com.request;
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.Enumeration;
import java.util.Map;
import java.util.Set;
@WebServlet("/requestServletDemo7")
public class ServletDemo7 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决中文乱码,需要设置流的字符编码
request.setCharacterEncoding("utf-8");//这个编码要和页面的编码保持一致
//1.String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
String username = request.getParameter("username");
System.out.println(username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
- 请求转发:一种在服务器内部的资源跳转方式
- 步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
- 特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中。
- 转发是一次请求
@WebServlet("/requestServletDemo8")
public class ServletDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8被访问。。。。。。");
//请求转发
request.getRequestDispatcher("/requestServletDemo9").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
@WebServlet("/requestServletDemo9")
public class ServletDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo9被访问。。。。。。");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
共享数据
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
- 方法:
- void setAttribute(String name,Object obj):存储数据
- bject getAttitude(String name):通过键获取值
- void removeAttribute(String name):通过键移除键值对
@WebServlet("/requestServletDemo8")
public class ServletDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8被访问。。。。。。");
//设置共享数据
request.setAttribute("msg", "hello");
//请求转发
request.getRequestDispatcher("/requestServletDemo9").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
@WebServlet("/requestServletDemo9")
public class ServletDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取共享的数据
Object msg = request.getAttribute("msg");
System.out.println(msg);
System.out.println("demo9被访问。。。。。。");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
获取ServletContext(现在只是获取该对象,后面会具体讲解)
- ServletContext getServletContext()
@WebServlet("/requestServletDemo10")
public class ServletDemo10 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);//org.apache.catalina.core.ApplicationContextFacade@22369334
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通常在开发过程只实现doPost()或doGet(),因为两个方法基本一样
this.doPost(request, response);
}
}
4.案例:用户登录
(1)用户登录案例需求
- .编写login.html登录页面 username & password 两个输入框
- 使用Druid数据库连接池技术,操作mysql,day14数据库中user表
- 使用JdbcTemplate技术封装JDBC
- 登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您
- 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
- 1.创建项目,导入html页面,配置文件,jar包
druid.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///day14 username=root password=root initialSize=5 maxActive=10 maxWait=3000
login.html
Title
- 2.创建数据库环境
CREATE DATAbase day14; USE day14; CREATE TABLE `user`( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) UNIQUE NOT NULL, `password` VARCHAR(32) NOT NULL ); INSERT INTO USER VALUES(1,'superbaby','123456');
- 3.创建包com.weeks.domain,创建类User
package com.weeks.domain;
public class User {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
'}';
}
}
- 4.创建包com.weeks.util,编写工具类JDBCUtils
package com.weeks.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class JDBCUtil {
private static DataSource ds;
static {
//1.加载配置文件
Properties properties = new Properties();
InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
try {
properties.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
};
public static DataSource getDataSource(){
return ds;
}
}
- 5.创建包com.weeks.dao,创建类UserDao,提供login方法
package com.weeks.dao;
import com.weeks.domain.User;
import com.weeks.util.JDBCUtil;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDao {
//声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDataSource());
public User login(User loginUser){
try {
//1.编写sql
String sql = "select * from user where username=? and password=?";
//2.调用query方法
User user = template.queryForObject(sql, new BeanPropertyRowMapper(User.class), loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace();//记录日志
return null;
}
}
}
- 6.编写com.weeks.web.servlet.LoginServlet类
package com.weeks.web.servlet;
import com.weeks.dao.UserDao;
import com.weeks.domain.User;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置编码
req.setCharacterEncoding("utf-8");
//2.获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//3.封装user对象
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password);
//4.调用UserDao的login方法
UserDao userDao = new UserDao();
User user = userDao.login(loginUser);
//5.判断user
if(user == null){
//登录失败
req.getRequestDispatcher("/failServlet").forward(req, resp);
}else{
//登录成功
//存储数据
req.setAttribute("user", user);
//转发
req.getRequestDispatcher("/successServlet").forward(req, resp);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
- 7.编写FailServlet和SuccessServlet类
package com.weeks.web.servlet;
import com.weeks.domain.User;
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;
@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取request域中共享的user对象
User user = (User) request.getAttribute("user");
if(user != null){
//给页面写一句话
//设置编码
response.setContentType("text/html;charset=utf-8");
//输出
response.getWriter().write("登录成功!" + user.getUsername() + ",欢迎您!");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package com.weeks.web.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;
@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setContentType("text/html;charset=utf-8");
//页面输出一句话
response.getWriter().write("登录失败!用户名或密码错误!");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
- 8.注意:配置好login.html中form标签的action属性,action="虚拟目录+Servlet的资源路径"



