Servlet之Request和Response的快速上手
阅读提示:
1、Request和Response概述
- request:获取请求数据 - 浏览器会发送HTTP请求到后台服务器[Tomcat]
- HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
- 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
- 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
- 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务
 
- response:设置响应数据 - 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
- 把响应数据封装到response对象中
- 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
- 浏览器最终解析结果,把内容展示在浏览器给用户浏览
 
- 案例 - @WebServlet("/demo")
 public class ServletDemo extends HttpServlet {
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 //使用request对象 获取请求数据
 String name = request.getParameter("name"); //用于获取请求参数,如url?name=zhangsan //使用response对象 设置响应数据
 response.setHeader("content-type","text/html;charset=utf-8");
 response.getWriter().write("<h1>"+name+",欢迎您!</h1>");
 } @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 System.out.println("Post...");
 }
 }
 
2、Request对象
2.1 Request继承体系
| 类或接口 | 说明 | 
|---|---|
| ServletRequest | Java提供的请求对象根接口 | 
| ↑ | -- | 
| HttpServletRequest | Java提供的针对HTTP协议封装的请求对象接口 | 
| ↑ | -- | 
| RequestFacade | Tomcat定义的实现类 | 
2.2 Request获取请求数据
2.2.1 获取请求行
- 请求行示例 - GET /request-demo/req1?name=zhangsan&password=123/ HTTP/2 - 分别为请求方式、请求资源路径和参数、协议和版本号 
- 获取方法 - // 获取请求方式 GET
 String getMethod();
 // 获取虚拟目录(项目访问路径) /request-demo
 String getContextPath();
 // 获取URL(统一资源定位符)http://localhost:8080/request-demo/req1
 StringBuffer getRequestURL();
 // 获取URI(统一资源标识符)/request-demo/req1
 String getRequestURI();
 // 获取请求参数(GET方式)name=zhangsan&password=123
 String getQueryString();
 
2.2.2 获取请求头
- 请求头示例 - User-Agent: Mozilla/5.0 Chrome/91.0.4472.106 
- 获取方法 - // 获取请求头,参数为对应的键
 String getHadder(String name);
 
2.2.3 获取请求体
- 请求体用于POST请求方式 
- 获取方法 - // 获取字节流,用于二进制数据
 ServletInputStream getInputStream();
 // 获取字符流,用于纯文本数据
 BufferedReader getReader();
 
2.2.4 获取请求参数的通用方式
- 存在问题 - BufferedReader getReader();获取文本数据需要手动解析
- 改进方法 - // 获取所有参数Map集合(Map集合的Value元素采用数据,以应对多选等情况)
 Map<String,String[]> getParameterMap();
 // 根据名称获取参数值(数组)
 String[] getParameterValues(String name);
 // 根据名称获取参数值(单个值)
 String getParameter(String name);
 
2.3 请求参数中文乱码问题
2.3.1 POST请求解决方案
- 分析原因 - POST的请求参数是通过 - request的- getReader()来获取流中的数据
- TOMCAT在获取流的时候采用的编码是 - ISO-8859-1
 
- 在获取参数前设置使用需要的编码 - // 设置字符输入流编码,设置字符集和页面保持一致,不区分大小写
 request.setCharacterEncoding("UTF-8");
 
2.3.2 GET请求解决方案
- 分析原因 - 字符串用过HTTP由浏览器提交到服务器
- 服务器不支持中文,会将字符进行URL编码
- 将URL编码发送到服务器,由服务器进行解码
- TOMCAT服务器对GET请求获取请求参数的方式是request.getQueryString(),与POST请求不同
- TOMCAT默认使用ISO-8859-1进行URL解码
- TOMCAT中getParameter(String name);方法将URL解码采用的编码格式写死,无法修改
 
- 在获取参数前设置使用需要的编码 - // 浏览器采用UTF-8将字符进行RUL编码
 // 服务器采用ISO-8859-1进行URL解码,此时采用编码为ISO-8859-1,出现乱码 // 使用ISO-8859-1编码将乱码字符编回二进制码,得到其字节数组
 byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
 // 将字节数组使用UTF-8重新编码
 username = new String(bytes, StandardCharsets.UTF_8);
 
- 备注 - Tomcat 8.0以上 - 解决了GET请求的乱码问题,设置了URL解码的默认方式为UTF-8 
- URL编解码 - // 编码
 URLEncoder.encode(str,"UTF-8");
 // 解码
 URLDecoder.decode(s,"ISO-8859-1");
 
2.4 Request 请求转发
- 请求转发是一种在服务器内部的跳转方式 
- 实现请求转发 - 接收资源A请求,执行其对应Servlet方法
- 资源A中要跳转到资源B
- 将请求转发到资源B
- 执行资源BServlet方法
 - // 在资源A中
 req.getRequestDispatcher("资源B路径").forward(req,resp);
 
- 请求转发资源间共享数据:使用Request对象 - 将该需要共享的数据(有需要时封装为对象)放在Request域中,可在转发后进行获取 - // 以(k, v)存储数据到request域中
 void setAttribute(String name,Object o);
 // 根据key获取value
 Object getAttribute(String name);
 // 根据key删除该键值对
 void removeAttribute(String name);
 
- 请求转发的特点 - 浏览器地址栏的路径不发生变化
- 只能转发到当前服务器内部资源
- 一次请求,可以在转发的资源间使用request共享数据
 
3、Response对象
3.1 Response继承体系
| 类或接口 | 说明 | 
|---|---|
| ServletResponse | Java提供的响应对象根接口 | 
| ↑ | -- | 
| HttpServletResponse | Java提供的针对HTTP协议封装的响应对象 | 
| ↑ | -- | 
| ResponseFacade | Tomcat定义的实现类 | 
3.2 Response设置响应数据功能介绍
- 设置响应行 - HTTP/2 200 OK - // 设置响应状态码
 void setStatus(int sc);
 
- 设置响应头 - Content-Type:text/html - // 设置响应头键值对
 void setHeader(String name,String value);
 
- 设置响应体 - HTML代码等,通过字符、字节输出流的方式网浏览器写 - // 获取字符输出流
 PrintWriter getWriter();
 // 获取字节输出流
 ServletOutputStream getOutputStream();
 
3.3 Response请求重定向
- 重定向:一种资源跳转的方式,区别于转发 - 浏览器发送发送请求到服务器,其中资源A接收到请求
- 资源A无法处理,但知道资源B资源可以处理,对浏览器做出响应,告知状态和处理方法
- 响应状态码:302
- 响应头给出资源位置:location:xxx
 
- 响应状态码:
- 浏览器接收到响应状态码302
- 浏览器重新发送请求到请求头中location对应的地址寻找到资源B
- 资源B接收请求后,进行处理,返回结果到服务器
 
- 重定向实现方式 - /*
 // 设置响应状态码和响应头
 resp.setStatus(302);
 resp.setHeader("location","项目虚拟目录(项目访问路径)+资源B的访问路径");
 */ // 设置重定向
 resp.sendRedirect("虚拟目录(项目访问路径)+资源B的访问路径");
 
- 重定向的特点(区别于请求转发) - 浏览器地址栏路径发生变化
- 可以重定向到任意资源位置,不局限于服务器内部
- 两次请求之间,不能在多个资源使用Request域共享数据
 
3.4 路径问题
- 关于虚拟目录(明确路径被谁使用) - 浏览器使用:需要加虚拟目录(项目访问路径) -- 如重定向
- 服务器使用:无需虚拟目录 -- 如请求转发
 
- 举例 - 需要加虚拟目录
- <a herf='路径'>
- <from action='路径'></from>
- resp.sendRedirect("路径")
 
- 不需要虚拟目录
- req.getRequestDispatcher("路径");
 
 
- 需要加虚拟目录
- 动态获取虚拟目录 - <!-- pom.xml中全局配置 -->
 <build>
 <plugins>
 <plugin>
 <groupId>org.apache.toncat.maven</groupId>
 <artifactId>tomcat-maven-plugin</artifactId>
 <version>2.2</version>
 <configuration>
 <path> <!-- 全局虚拟目录 --> </path>
 </configuration>
 </plugin>
 <!-- ... -->
 </plugins>
 </build>
 - // 动态获取虚拟目录
 String contextPath = request.getContextPath();
 
3.5 Response相应字符数据
字符输出流不需要关闭,其由Response对象获取,会随Response对象的回收而回收
- 返回简单字符串 - aaa- // 通过Response对象获取字符输出流
 PrintWriter writer = response.getWriter();
 // 写数据
 writer.write("aaa");
 
- 返回HTML代码,切能被解析 - // 通过Response对象获取字符输出流
 PrintWriter writer = response.getWriter();
 // 设置响应头content-type,让浏览器以HTML格式进行解析
 response.setHeader("content-type","text/html");
 // 写HTML代码
 writer.write("<h1>aaa</h1>");
 
- 返回中文字符串,设置编码格式为UTF-8(通过Response获取的字符输出流默认编码为 - ISO-8859-1)- // 通过Response对象获取字符输出流
 PrintWriter writer = response.getWriter();
 // 设置响应头content-yupe,使用HTML格式解析,并注明字符集
 // response.setHeader("content-type","text/html;cahrset=utf-8");
 response.setContentType("text/html;cahrset=utf-8");
 // 写HTML代码
 writer.write("你好");
 // writer.write("<h1>你好</h1>");
 
3.6 Response相应字节数据
- 返回字节数据使用方法 - // 通过Response对象获取字节输出流
 ServletOutputStream outputStream = resp.getOutputStream();
 // 通过字节输出流写数据
 outputStream.write(字节数据);
 
- 示例 - // 读取文件
 FileInputStream fis = new FileInputStream("d://demo.jpg");
 // 获取response字节输出流
 ServletOutputStream os = response.getOutputStream();
 // 完成流的copy
 byte[] buff = new byte[1024];
 int len = 0;
 while ((len = fis.read(buff))!= -1){
 os.write(buff, 0, len);
 } fis.close();
 
- 使用工具类改进示例 - <!-- 在pom.xml中添加配置 -->
 <dependencies>
 <!-- ... -->
 <dependency>
 <dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>2.6</version>
 </dependency>
 </dependency>
 </dependencies>
 - // 读取文件
 FileInputStream fis = new FileInputStream("d://demo.jpg");
 // 获取response字节输出流
 ServletOutputStream os = response.getOutputStream();
 // 完成流的copy
 // byte[] buff = new byte[1024];
 // int len = 0;
 // while ((len = fis.read(buff))!= -1){
 // os.write(buff, 0, len);
 // }
 IOUtils.copy(fis, os); fis.close();
 
4、用户注册登录案例
4.1用户登录和注册案例
4.1.1 需求分析
- 登录
- 用户填写用户名密码,提交到LoginServlet
- 在LoginServlet中使用MyBatis查询数据库,验证用户名密码是否正确
- 如果正确响应登录成功,否则响应登录失败
 
- 注册
- 用户填写用户名密码,提交到RegisterServlet
- 在LoginServlet中使用MyBatis查询数据库,验证用户名是否存在
- 若不存在则向数据库中插入新的用户数据,否则响应注册失败
 
4.1.2 环境准备
- 依赖导入 - <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion> <groupId>priv.dandelion</groupId>
 <artifactId>day09RequestResponse</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>war</packaging> <dependencies>
 <!--mybatis 依赖-->
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>3.5.5</version>
 </dependency> <!--mysql 驱动-->
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>5.1.34</version>
 </dependency> <!--junit 单元测试-->
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.11</version>
 </dependency> <!-- 添加slf4j日志api -->
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.20</version>
 </dependency> <!-- 添加logback-classic依赖 -->
 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 <version>1.2.3</version>
 </dependency> <!-- 添加logback-core依赖 -->
 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-core</artifactId>
 <version>1.2.3</version>
 </dependency> <!-- servlet依赖 -->
 <dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>javax.servlet-api</artifactId>
 <version>3.1.0</version>
 <scope>provided</scope>
 </dependency> <!-- io工具类依赖 -->
 <dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>2.6</version>
 </dependency> </dependencies> <build>
 <plugins>
 <plugin>
 <groupId>org.apache.tomcat.maven</groupId>
 <artifactId>tomcat7-maven-plugin</artifactId>
 <version>2.2</version>
 <!-- <configuration>-->
 <!--<!– <path><!– 全局虚拟目录 –></path>–>-->
 <!-- <path>/day09RequestResponse</path>-->
 <!-- </configuration>-->
 </plugin>
 </plugins>
 </build>
 </project>
- 页面 - 注:代码中虚拟目录位置需要进行替换 - 登录 - <!DOCTYPE html>
 <html lang="en"> <head>
 <meta charset="UTF-8">
 <title>login</title>
 <link href="css/login.css" rel="stylesheet">
 </head> <body>
 <div id="loginDiv">
 <form action="/虚拟目录/login" method="post" id="form">
 <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>
 
- 注册 - <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>欢迎注册</title>
 <link href="css/register.css" rel="stylesheet">
 </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="/虚拟目录/register" 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>
 
 
- 数据库和实体类 - User表 - -- 创建用户表
 CREATE TABLE tb_user(
 id int primary key auto_increment,
 username varchar(20) unique,
 password varchar(32)
 ); -- 添加数据
 INSERT INTO tb_user(username,password) values('zhangsan','123'),('lisi','234'); SELECT * FROM tb_user;
- 实体类 - package priv.dandelion.entity; public class User {
 private Integer id;
 private String username;
 private String password; public User(Integer id, String username, String password) {
 this.id = id;
 this.username = username;
 this.password = password;
 } public User() {
 } 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 + '\'' +
 '}';
 }
 }
 
- MyBatis - 核心配置文件 - 注:代码中数据库名称需要进行替换 - <?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>
 <environments default="development">
 <environment id="development">
 <!-- 采用JDBC的事务管理方式 -->
 <transactionManager type="JDBC"/>
 <!-- 数据库连接信息 -->
 <dataSource type="POOLED">
 <property name="driver" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql:///数据库名称?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
 <property name="username" value="root"/>
 <property name="password" value="123456"/>
 </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:///数据库名称?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
 <property name="username" value="root"/>
 <property name="password" value="123456"/>
 </dataSource>
 </environment>
 </environments>
 <!-- 加载SQL映射文件 -->
 <mappers>
 <package name="priv.dandelion.mapper"/>
 </mappers>
 </configuration>
 
- UserMapper.xml映射文件 - 先完成接口,再由MyBatisX插件生成,或手动再resources目录下创建 - <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="priv.dandelion.mapper.UserMapper">
 </mapper>
 
- UserMapper接口 - public interface UserMapper { // 查询已存在用户数量,防止重复注册
 @Select("select * from tb_user where username = #{username} limit 0, 1")
 public User selectByUsername(@Param("username") String username); // 查询用户信息
 @Select("select * from tb_user where username = #{username} and password = #{password} limit 0, 1")
 public User selectAll(@Param("username") String username, @Param("password") String password); @Insert("insert into tb_user(username, password) VALUES (#{username}, #{password})")
 public void insertUser(@Param("username") String username, @Param("password") String password);
 }
 
4.1.3 代码实现
注:实现流程
- 接收用户名和密码
- 解决Request中文乱码
- 使用ISO-8859-1编码将乱码字符编回二进制码,得到其字节数组
- 将字节数组使用UTF-8重新编码
- 调用MyBatis完成查询
- 加载MyBatis核心配置文件,获取SqlSessionFactory
- 获取Session对象,设置自动提交事务
- 获取UserMapper
- 执行SQL
- 处理结果并返回数据
- 设置response编码并获取字符输出流
- 处理结果(注册时需要额外判断用户是否已经存在)
- 释放资源
- 登录Servlet - @WebServlet("/login")
 public class LoginServlet extends HttpServlet {
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("开始进行登录判断"); // 接收用户名和密码
 String username = request.getParameter("username");
 String password = request.getParameter("password"); // 解决Request中文乱码
 // 使用ISO-8859-1编码将乱码字符编回二进制码,得到其字节数组
 byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
 // 将字节数组使用UTF-8重新编码
 username = new String(bytes, StandardCharsets.UTF_8); // 调用MyBatis完成查询
 // 加载MyBatis核心配置文件,获取SqlSessionFactory
 String resource = "mybatis-config.xml";
 InputStream inputStream = Resources.getResourceAsStream(resource);
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 // 获取Session对象,设置自动提交事务
 SqlSession sqlSession = sqlSessionFactory.openSession(true);
 // 获取UserMapper
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 // 执行SQL
 User user = userMapper.selectAll(username, password); // 设置response编码并获取字符输出流
 response.setContentType("text/html;charset=utf-8");
 PrintWriter writer = response.getWriter(); // 处理结果
 if (user != null) {
 // 登录成功
 writer.write("login success" + user.getUsername() + "欢迎您");
 } else {
 // 登录失败
 writer.write("login fail 用户" + user.getUsername() + "不存在");
 }
 // 释放资源
 sqlSession.close();
 System.out.println("login end");
 } @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 this.doGet(request, response);
 }
 }
 
- 注册Servlet - @WebServlet("/register")
 public class RegisterServlet extends HttpServlet {
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 System.out.println("register start");
 // 接收用户名和密码
 String username = request.getParameter("username");
 String password = request.getParameter("password"); // 解决Request中文乱码
 // 使用ISO-8859-1编码将乱码字符编回二进制码,得到其字节数组
 byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
 // 将字节数组使用UTF-8重新编码
 username = new String(bytes, StandardCharsets.UTF_8); // 调用MyBatis完成查询
 // 加载MyBatis核心配置文件,获取SqlSessionFactory
 String resource = "mybatis-config.xml";
 InputStream inputStream = Resources.getResourceAsStream(resource);
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 // 获取Session对象,设置自动提交事务
 SqlSession sqlSession = sqlSessionFactory.openSession(true);
 // 获取UserMapper
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 // 执行SQL,处理结果
 User user = userMapper.selectByUsername(username); // 设置response编码并获取字符输出流
 response.setContentType("text/html;charset=UTF-8");
 PrintWriter writer = response.getWriter(); // 查重
 if (user == null){
 userMapper.insertUser(username, password);
 // 注册成功
 writer.write("register success 成功");
 } else {
 System.out.println(user.getUsername());
 // 注册失败
 writer.write("用户名已被占用");
 } // 释放资源
 sqlSession.close();
 System.out.println("register end"); } @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 this.doGet(request, response);
 }
 }
4.2 SQLSessionFactory工具抽取:改进登录案例
- 案例存在问题 - SqlSessionFactory创建部分存在代码冗余
- SqlSessionFactory内置连接池,多次创建资源消耗较大
 
- 改进方案 - 使用工具类解决代码重复问题
- 使用静态代码块实现仅创建一次SqlSessionFactory
 
- 代码实现 - 工具类 - public class SqlSessionFactoryUtils { // 提升作用域,用于返回值
 private static SqlSessionFactory sqlSessionFactory; // 静态代码块会随着类的加载自动执行且只执行一次
 static {
 String resource = "mybatis-config.xml";
 InputStream inputStream = null;
 try {
 inputStream = Resources.getResourceAsStream(resource);
 } catch (IOException e) {
 e.printStackTrace();
 }
 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 } // 返回工厂对象
 public static SqlSessionFactory getSqlSessionFactory() {
 return sqlSessionFactory;
 } }
 
- 改进后代码(以 - LoginServlet为例)- @WebServlet("/login")
 public class LoginServlet extends HttpServlet {
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("开始进行登录判断"); // 接收用户名和密码
 String username = request.getParameter("username");
 String password = request.getParameter("password"); // 解决Request中文乱码
 // 使用ISO-8859-1编码将乱码字符编回二进制码,得到其字节数组
 byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
 // 将字节数组使用UTF-8重新编码
 username = new String(bytes, StandardCharsets.UTF_8); // 调用MyBatis完成查询
 // 加载MyBatis核心配置文件,获取SqlSessionFactory,已通过工具类进行改进
 SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
 // 获取Session对象,设置自动提交事务
 SqlSession sqlSession = sqlSessionFactory.openSession(true);
 // 获取UserMapper
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 // 执行SQL
 User user = userMapper.selectAll(username, password); // 设置response编码并获取字符输出流
 response.setContentType("text/html;charset=utf-8");
 PrintWriter writer = response.getWriter(); // 处理结果
 if (user != null) {
 // 登录成功
 writer.write("login success" + user.getUsername() + "欢迎您");
 } else {
 // 登录失败
 writer.write("login fail 用户" + user.getUsername() + "不存在");
 }
 // 释放资源
 sqlSession.close();
 System.out.println("login end");
 } @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 this.doGet(request, response);
 }
 }
 
Servlet之Request和Response的快速上手的更多相关文章
- servlet中request和response
		一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ... 
- JSP Servlet中Request与Response所有成员方法的研究
		HttpServletRequest与HttpServletResponse作为Servlet中doGet.doPost等方法中传递的参数,承接了Http请求与响应中的大部分功能,请求的解析与响应的返 ... 
- servlet之request和response的使用区分
		有的时候在写servlet程序时,我总是被一个方法该用request去调用.还是用response去调用而困惑.从而造成编程时间的延长. 我在区分request和response的使用时,使用的方法是 ... 
- javaWeb核心技术第七篇之HTTP、Tomcat、Servlet、Request和Response
		- Web服务器 - 概念: - web资源: "英文直译"网"的意思 资源:一切数据文件 web资源:通过网络可以访问到的资源,通常指的是一切放在服务器上的文件&quo ... 
- Servlet之Request和Response 解析
		原理 tomcat服务器会根据请求url中的资源路径,创建对应的Servlet的对象 tomcat服务器.会创建request和response对象,request对象中封装请求消息数据. tomca ... 
- javaWeb中  servlet 、request 、response
		1.Servlet (1)Servlet是JavaEE的一个动态web资源开发技 术,就是在服务器上运行的小程序,这个小程序是由服务器调用的,服务器为了能调用这个小程序,就要求这样的程序必须实现一个S ... 
- Servlet的request和response
		SERVLET API中forward() 与redirect()的区别? 答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址:后者则是完全的跳转,浏览器将会得到跳转的地址 ... 
- servlet中Request与response使用
		服务器根据请求自动创建传入HttpServletRequest对象和HttpServletResponse对象 @Override protected void service(HttpServlet ... 
- JavaWeb(一)Servlet中的request与response
		一.HttpServletRequest概述 1.1.HttpServletRequest简介 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP ... 
- Servlet(四):request和response对象
		Request对象:问题: 浏览器发起请求到服务器,会遵循HTTP协议将请求数据发送给服务器. 那么服务器接受到请求的数据改怎么存储呢?不但要存,而且要保证完成性. 解决: 使用对象进行存储,服务器每 ... 
随机推荐
- 详解Python 中可视化数据分析工作流程
			本文分享自华为云社区<Python 可视化数据分析从数据获取到洞见发现的全面指南>,作者:柠檬味拥抱. 在数据科学和分析的领域中,可视化是一种强大的工具,能够帮助我们理解数据.发现模式,并 ... 
- postgresql数据库清理
			大量update或者delete后 磁盘空间会猛增.原理是postgresql并没有真正的删除 只是将删除数据的状态置为已删除,该空间不能记录被从新使用.若是删除的记录位于表的末端,其所占用的空间将会 ... 
- EAV模型(实体-属性-值)的设计和低代码的处理方案(1)
			一般我们在开发的时候,习惯上使用常规的关系型数据库来设计数据库表,对于一些业务表的字段比较固定的场景,是一种非常不错的选择,而且查询的时候,由于是基于固定的表字段进行查询,性能基本上是最优的.不过有一 ... 
- C语言:快速排序(详解)
			快速排序采用的是两头对比交换 http://t.csdn.cn/TXcAK 上面这个连接大家可以点进去看看博客李小白大大的图文解释,我觉得这个是对我启发比较大的,对刚接触快速排序的人来说非常友好,很快 ... 
- LOTO示波器软件PC缓存(波形录制与回放)功能
			当打开PC缓存功能后, 软件将采用先进先出的原则排队对示波器采集的每一帧数据, 进行帧缓存. 当发现屏幕中有感兴趣的波形掠过时, 鼠标点击软件的(暂停)按钮, 可以选择回看某一帧的波形.一帧数据的量 ... 
- AIRIOT物联网低代码平台如何配置三菱PLC驱动?
			三菱PLC驱动配置使用三菱Melsec协议(MC协议)从三菱PLC读取数据,仅支持以太网方式.三菱PLC都可以通过此协议访问,但是需要对PLC进行设置. AIRIOT物联网低代码平台如何配置三菱PLC ... 
- 鸿蒙HarmonyOS实战-Stage模型(服务卡片的模块和创建)
			一.服务卡片的模块和创建 在HarmonyOS中,服务卡片是一种提供即时信息和快速操作的小组件,类似于Android中的通知栏.服务卡片可以显示各种类型的信息,包括通知.天气.日历事件.音乐播放器.快 ... 
- Abp vNext 框架 文章
			http://www.vnfan.com/helinbin/tag/Abp%20vNext框架/ 
- Aspire项目发布到远程k8s集群
			前提 你必须会创建aspire项目,不会的请先看微服务新体验之Aspire初体验 Aspirate (Aspir8) Aspirate 是将aspire项目发布到k8s集群的工具 安装aspirate ... 
- python+k8s——基础练习
			列表 core_api = client.CoreV1Api() # 管理核心资源(Pod, Service, ConfigMap 等) apps_api = client.AppsV1Api() # ... 
