1 Request
1.1 Request继承关系
ServletRequest Java提供的请求对象根接口
HttpServletRequest Java提供的对Http协议封装的请求对象接口
RequestFacade Tomcat定义的实现类
@WebServlet("/demo2")
public class Servlet2Demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet req = " + req);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost");
}
}
请求http://localhost:8080/tomcat-demo/demo2后,输出日志
doGet req = org.apache.catalina.connector.RequestFacade@1184683
所以继承关系为
RequestFacade extends HttpServletRequest extends ServletRequest
1.2 Request请求数据
1.2.1 获取请求行数据
@WebServlet("/demo2")
public class Servlet2Demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
System.out.println("method = " + method);
String path = req.getContextPath();
System.out.println("path = " + path);
StringBuffer url = req.getRequestURL();
System.out.println("url = " + url);
String uri = req.getRequestURI();
System.out.println("uri = " + uri);
String queryString = req.getQueryString();
System.out.println("queryString = " + queryString);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost");
}
}
请求地址: http://localhost:8080/tomcat-demo/demo2?username=zhangsan&pwd=123
输出结果
method = GET
path = /tomcat-demo
url = http://localhost:8080/tomcat-demo/demo2
uri = /tomcat-demo/demo2
queryString = username=zhangsan&pwd=123
1.2.2 获取请求头数据
代码示例
String agent = req.getHeader("user-agent");
System.out.println("agent = " + agent);
输出结果
agent = Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
1.2.3 获取请求体数据
1 在webApp包下创建req.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/tomcat-demo/demo2" method="post">
<input name="username"/>
<input type="submit"/>
</form>
</body>
</html>
2 在Servlet#doPost()方法中获取数据
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader bufferedReader = req.getReader();
String line = bufferedReader.readLine();
System.out.println(line);
}
}
3 启动服务,通过浏览器请求
http://localhost:8080/tomcat-demo/req.html
4 在html页面中输入内容后提交后,可看到日志输出
username=zhang&password=1123
1.2.4 获取请求参数的通用方式
1 doGet()和doPost()方法获取到的参数相同时
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String result = req.getQueryString();
System.out.println(result);//和doPost()方法的代码相同
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader bufferedReader = req.getReader();
String line = bufferedReader.readLine();
System.out.println(line);//和doGet()方法中的代码相同
}
}
2 处理上述问题方式1
直接在doPost()方法中调用doGet()方法
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String params = "";
String method = req.getMethod();
if ("GET".equals(method)) {
params = req.getQueryString();
} else if("POST".equals(method)) {
BufferedReader reader = req.getReader();
params = reader.readLine();
}
System.out.println(params);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3 方式二
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/tomcat-demo/req2" method="get">
<input type="text" name="username">
<input type="password" name="password">
<input type="checkbox" name="hobby" value="1"> 跑步
<input type="checkbox" name="hobby" value="2"> 骑车
<input type="submit" >
</form>
</body>
</html>
Servlet代码
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得所有参数
Map<String, String[]> map = req.getParameterMap();
for (String key : map.keySet()) {
System.out.println("key ---> " + key);
String [] values = map.get(key);
for (String value : values) {
System.out.println("value ---> " + value);
}
System.out.println();
}
// 获得单个参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("单个参数值 username = " + username + ", password = " + password);
//数组值
String[] hobbies = req.getParameterValues("hobby");
for (String hobby: hobbies) {
System.out.println(hobby);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
访问http://localhost:8080/tomcat-demo/req.html 后
日志输出
key ---> username
value ---> lisi
key ---> password
value ---> 432
key ---> hobby
value ---> 1
value ---> 2
单个参数值 username = lisi, password = 432
1
2
1.3 乱码问题
//=================乱码问题
//post方式设置解码格式
// req.setCharacterEncoding("UTF-8");
//get/post设置解码格式
username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
System.out.println("username = " + username);
日志输出
单个参数值 username = å¼ ä¸‰, password = 321
1
2
username = 张三
1.3 请求转发
@WebServlet("/req3")
public class RequestDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("req3 doGet ---> ");
req.setAttribute("key_req", "value from req3");
//转发
req.getRequestDispatcher("/req4").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("req4 doGet ---> value = " + req.getAttribute("key_req"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
访问http://localhost:8080/tomcat-demo/req3后
日志输出
req3 doGet --->
req4 doGet ---> value = value from req3
2 Response
2.1 Response设置响应数据
1 设置响应行
resp.setStatus(200);
2 设置响应头
resp.setHeader("Content-type", "text/json")
3 设置响应体
getWritter();
getOutPutStream();
2.2 Response请求重定向
定义两个Servlet
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(302);
resp.setHeader("location", "/tomcat-demo/resp2");
System.out.println("Resp1 doGet() ");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(200);
System.out.println("Resp2 doGet() ");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
请求地址
ocalhost:8080/tomcat-demo/resp1
日志打印
Resp1 doGet()
Resp2 doGet()
2.3 路径问题
重定向时
resp.setHeader("location", "/tomcat-demo/resp2");
转发时
req.getRequestDispatcher("/req4").forward(req, resp);
问题: 为什么转发是不需要加路径?
转发是相对于相对于服务端,重定向时相对于浏览器。
2.4 Response响应字符数据
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html, charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.write("hello");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2.5 Response响应字节数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应字节数据
FileInputStream stream = new FileInputStream("/Users/yl/Desktop/image.png");
ServletOutputStream os = resp.getOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while ((len = stream.read(buff)) != -1) {
os.write(buff, 0, len);
}
stream.close();
}
使用工具类简化形式
添加依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应字节数据
FileInputStream stream = new FileInputStream("/Users/yl/Desktop/image.png");
ServletOutputStream os = resp.getOutputStream();
//简化方式
IOUtils.copy(stream, os);
stream.close();
}
3 示例
3.1 登录示例
3.1.1 登录页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<div id="loginDiv">
<form action="/tomcat-demo/loginServlet" id="form" method="post">
<h1 id="loginMsg">LOGIN IN</h1>
<p>Username:<input id="username" name="username" type="text"></p>
<p>Password:<input id="password" name="password" type="password"></p>
<div id="subDiv">
<input type="submit" class="button" value="login up">
<input type="reset" class="button" value="reset">
<a href="register.html">没有账号?点击注册</a>
</div>
</form>
</div>
</body>
</html>
3.1.2 添加依赖
在pom中添加mysql和mybatis依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5 </version>
</dependency>
3.1.3 mybatis-config.xml配置
在resources目录下添加mybatis-config.xml配置
文件内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.test"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<package name="com.test.mapper"/>
</mappers>
</configuration>
3.1.4 创建servlet实现类
@WebServlet(urlPatterns = "/loginServlet")
public class LoginServlet extends HttpServlet {
private String TAG = getClass().getSimpleName();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(TAG + ": doGet() ---> ");
String username = req.getParameter("username");
String password = req.getParameter("password");
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.select(username, password);
sqlSession.close();
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
if (user != null) {
writer.write("登录成功");
} else {
writer.write("登录失败");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(TAG + ": doPost() ---> ");
this.doGet(req, resp);
}
}
3.1.5 添加mybatis查询语句
public interface UserMapper {
@Select("select * from tb_user where username = #{username} and password= #{password}")
User select(@Param("username") String username, @Param("password") String password);
}
3.1.6 mysql添加测试数据
//tb_user表
mysql> desc tb_user;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(20) | YES | | NULL | |
| password | varchar(20) | YES | | NULL | |
| gender | char(1) | YES | | NULL | |
| addr | varchar(30) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
//添加测试数据
mysql> insert into tb_user(username, password) values('zhangsan', '123'), ('lisi', '125');
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0
3.1.5 测试请求
请求地址: http://localhost:8080/tomcat-demo/login.html
当username与pwd输入正确的用户名和密码时,提示登录成功
3.2 注册示例
3.2.1 注册页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎注册</title>
</head>
<body>
<div class="form-div">
<div class="reg-content">
<h1>欢迎注册</h1>
<span>已有帐号?</span> <a href="login.html">登录</a>
</div>
<form id="reg-form" action="/tomcat-demo/registerServlet" method="post">
<table>
<tr>
<td>用户名</td>
<td class="inputs">
<input name="username" type="text" id="username">
<br>
<span id="username_err" class="err_msg" style="display: none">用户名不太受欢迎</span>
</td>
</tr>
<tr>
<td>密码</td>
<td class="inputs">
<input name="password" type="password" id="password">
<br>
<span id="password_err" class="err_msg" style="display: none">密码格式有误</span>
</td>
</tr>
</table>
<div class="buttons">
<input value="注 册" type="submit" id="reg_btn">
</div>
<br class="clear">
</form>
</div>
</body>
</html>
3.2.2 注册Servlet
@WebServlet(urlPatterns = "/registerServlet")
public class RegisterServlet extends HttpServlet {
private String TAG = getClass().getSimpleName();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(TAG + ": doGet() ---> ");
//请求数据
String username = req.getParameter("username");
String password = req.getParameter("password");
username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
User userRegister = new User();
userRegister.setUsername(username);
userRegister.setPassword(password);
//创建UserMapper
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//查询本地user是否存在
User user = userMapper.selectByUsername(username);
resp.setContentType("text/html;charset=utf-8");
if (user == null) {
userMapper.add(userRegister);
sqlSession.commit();
sqlSession.close();
resp.getWriter().write("注册成功!");
} else {
resp.getWriter().write("用户名已存在!");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(TAG + ": doPost() ---> ");
this.doGet(req, resp);
}
}
3.2.3 sql语句
public interface UserMapper {
@Select("select * from tb_user where username = #{username} and password= #{password}")
User select(@Param("username") String username, @Param("password") String password);
@Insert("insert into tb_user values(null, #{username}, #{password}, null, null)")
void add(User user);
@Select("select * from tb_user where username = #{username}")
User selectByUsername(String username);
}
3.2.4 测试请求
请求http://localhost:8080/tomcat-demo/register.html地址后
输入用户名和密码,当musql中不存在此用户名时,即可注册成功