一、HttpServletRequest、HttpServletResponse
1、HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求中的所有信息都封装在这个对象中,通过此种方式来获取请求中的数据。
- getRequestURL:获取客户端的完整URL
- getRequesURI:获取请求行中的资源名部分
- getQueryString:获取请求行的参数部分
- getMethod:获取请求方式
- getSchema:获取请求的协议
- getRemoteAddr:获取客户端的ip地址
- getRemoteHost:获取客户端的完整主机名
- getRemotePort:获取客户端的网络端口号
- 获取请求头信息
getHeader(String name)
getHeaders(String name) - 获取客户端请求参数(用户提交的数据)
getParameter(name)
getParameterValues(String name)
getParameterNames()
getParameterMap()
2、HttpServletResponse
HttpServletResponse对象是服务器的响应对象,这个对象中封装了向客户端发送数据,发送响应头,发送响应状态码的方法。
- 设置响应头
setHeader(String key,String value) 添加响应信息,key重复会覆盖
addHeader(String key,String value) 添加响应信息,key重复不会覆盖 - 设置响应状态
sendError(int num,String msg ) 添加响应状态 - 设置响应实体
getWriter().write(msg) 响应具体的数据给浏览器
3、例子练习
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="bobo" method="get">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="pwd"/><br/>
爱好:<br/>
<input type="checkbox" name="fav" value="1"/>java
<input type="checkbox" name="fav" value="1"/>c
<input type="checkbox" name="fav" value="1"/>c++
<input type="submit" value="登录"/>
</form>
</body>
</html>
package com.bobo;
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;
import java.util.Enumeration;
/**
* HttpServletRequest:用来存储客户端请求的参数
* 请求头
* 请求行
* 请求体
*
* HttpServletResponse:表示服务端返回数据的响应对象
* 响应头
* 响应行
* 响应体
*/
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Post 请求");
this.doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Get 请求");
/**
* 获取请求行信息
*/
//获取请求中的请求方式
System.out.println("请求方式:" + request.getMethod());
//获取请求中的完整地址
System.out.println("请求URL:" + request.getRequestURL());
//获取请求中的资源路径
System.out.println("请求URI:" + request.getRequestURI());
//获取请求中的协议
System.out.println("请求协议:" + request.getScheme());
/**
* 获取请求头信息
*/
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
String value = request.getHeader(key);
System.out.println(key + ":" + value);
}
/**
* 获取用户请求参数,注意:无论用户请求方式是Get还是Post,获取用户请求的方式不变
*/
//注意:这里的参数要和jsp表单中的name属性相同
String username = request.getParameter("username");
String password = request.getParameter("pwd");
System.out.println("username:" + username + " password:" + password);
//第二种方式
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String key = parameterNames.nextElement();
String value = request.getParameter(key);
System.out.println("key:" + key + " value:" + value);
}
//获取相同名字的多个值,例如checkbox
String[] favs = request.getParameterValues("fav");
System.out.println(Arrays.toString(favs));
/**
* 其它常用方法
*/
//获取远程客户端地址、端口
System.out.println("RemoteAddr:"+request.getRemoteAddr()+" RemotePort:"+request.getRemotePort());
//获取本机地址、本机名
System.out.println("LocalAddr:"+request.getLocalAddr()+" LocalName:"+request.getLocalName());
/**
* ---------响应信息
*/
//服务端返回数据的格式
response.setHeader("Context-Type","text/html");
//response.setContentType("text/html");
//设置响应头,两种方式:1、setHeader 2、addHeader
//如果存在相同的key会覆盖上一个值
response.setHeader("set","bobo1");
response.setHeader("set","bobo2");
//如果存在相同的key,不会覆盖上一个值
response.addHeader("add","bobo1");
response.addHeader("add","bobo2");
response.getWriter().write("<b>this is back data<b>");
}
}
二、Servlet乱码问题解决
- 使用String重新进行编码
String name = new String(name.getBytes(“ios-8859-1”),”utf-8”) - get请求乱码
request.setCharacterEncoding(“utf-8”);
在server.xml中添加属性useBodyEncodingForURI=true - post请求乱码
request.setCharacterEncoding(“utf-8”); - response乱码
response.setCharacterEncoding(“UTF-8”);
response.setContentType(“text/html;charset=utf-8”)
三、请求转发和重定向
1、请求转发
request.getRequestDispatcher("fail").forward(request,response);
- 客户端只发送一次请求。
- 浏览器的地址栏地址没有变化。
- 请求过程中只有一个request和response。
- 几个servlet共享一个request和response。
- 对客户端透明,客户端不需要知道服务端做了哪些操作。
2、重定向
response.sendRedirect("fail");
- 浏览器发送两次请求。
- 浏览器的地址发生变化。
- 请求过程产生两个request对象和两个response对象。
- 两个servlet不能共享同一个request和response对象。
四、Servlet加载MySql数据库
1、驱动下载地址:
https://dev.mysql.com/downloads/connector/j/
2、把下载下来的驱动jar包放到项目的WEB_INF下面
3、加载MySql数据库代码
public class UserDaoImpl implements UserDao {
@Override
public User checkUser(User user) {
//定义链接对象
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
User u = null;
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取链接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/login", "root", "root");
//获取预处理块
statement = conn.prepareStatement("select * from user where name = ? and pwd = ?");
//给?赋值
statement.setString(1, user.getUserName());
statement.setString(2, user.getPassword());
//执行sql语句
resultSet = statement.executeQuery();
//从result中获取结果
while (resultSet.next()) {
u = new User(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("pwd"));
}
} catch (Exception e) {
e.printStackTrace();
try {
resultSet.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
try {
statement.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
return u;
}
}
五、Servlet之Cookie
HTTP是一个无状态的协议,当一个客户端向服务端发送请求,在服务器返回响应后,连接就关闭了,在服务器端不保留连接信息。
思考:当客户端发送多次请求且需要相同的请求参数的时候,应该如何处理?
1、什么是Cookie?
- Cookie是一种在客户端保持HTTP状态信息的技术.
- Cookie是在浏览器访问服务器的某个资源时,由web服务器在响应头传送给浏览器的数据.
- 浏览器如果保存了某个cookie,那么以后每次访问服务器的时候,都会在请求头传递给服务端.
- 一个cookie只能记录一种信息,是key-value形式.
- 一个web站点可以给浏览器发送多个cookie,一个浏览器也可以存储多个站点的cookie。
2、cookie的基本原理
3、cookie基本操作
- 创建cookie对象
Cookie cookie = new Cookie(String key,String value); - 设置cookie参数
cookie.setMaxAge(int seconds)
cookie.setPath(String url) - 响应Cookie给客户端
response.addCookie(Cookie cookie) - 获取cookie属性
Cookie[] cookies = request.getCookies()
4、cookie实现免登陆例子
https://github.com/SevenYearZhao/Java-servlet-and-jsp/tree/master/CookieProject
六、servlet之session
1、什么是session
- Session表示会话,在一段时间内,用户与服务器之间的一系列的交互操作。
- session对象:用户发送不同请求的时候,在服务器端保存不同请求共享数据的存储对象。
2、特点
- Session是依赖cookie技术的服务器端的数据存储技术。
- 由服务器进行创建。
- 每个用户独立拥有一个session对象。
- 默认存储时间是30分钟。
3、Servlet之Session机制
用户使用浏览器第一次向服务器发送请求, 服务器在接受到请求后, 调用对应的 Servlet 进行处理。 在处理过程中会给用户创建一个 session 对象, 用来存储用户请求处理相关的公共数据, 并将此 session 对象的 JSESSIONID 以 sessoin 的形式存储在浏览器中(临时存储, 浏览器关闭即失效)。 用户在发起第二次请求及后续请求时, 请求信息中会附带 JSESSIONID, 服务器在接收到请求后,调用对应的 Servlet 进行请求处理, 同时根据 JSESSIONID 返回其对应的 session 对象
4、Session基本操作
- 创建sessoin对象
HttpSession session = request.getSession() - 向Session对象中添加值
sessoin.setAttribute(String name,Object object) - 获取Session中的值
session.getAttribute(String name) - 设置sessoin属性
session.setMaxInactiveInterval(5)//设置存活时间
session.invalidate(); //session强制失效
5、Session实现数据用户登录例子
解决了使用request.sendDirectly()重定向servlet丢失用户名的情况。
https://github.com/SevenYearZhao/Java-servlet-and-jsp/tree/master/SessionProject
七、Servlet之ServletContext和ServletConfig
1、ServletContext
思考:不同用户的数据共享怎么办?
使用ServletContext来处理。
什么是ServletContext?
- 运行在JVM上的每一个web应用程序都有一个与之对应的Servlet上下文(Servlet运行环境)
- Servlet API提供ServletContext接口用来表示Servlet上下文,ServletContext对象可以被web应用程序中的所有servlet访问
- ServletContext对象是web服务器中的一个已知路径的根
ServletContext原理
ServletContext 对象由服务器进行创建, 一个项目只有一个对象。 不管在项目的任意位置进行获取得到的都是同一个对象, 那么不同用户发起的请求获取到的也就是同一个对象了, 该对象由用户共同拥有。
Servletcontext API
2、ServletConfig
思考:使用ServletContext对象可以获取web.xml中的全局配置文件,在web.xml中,每个Servlet也可以进行单独的配置,那么该怎么获取配置信息呢?使用ServletConfig对象。
作用:
ServletConfig对象是Servlet的专属配置对象,每个Servlet都单独拥有一个ServletConfig对象 ,用来获取web.xml中的配置信息。
使用:
获取ServletConfig对象。
获取web.xml中的servlet配置信息。