Servlet之Request&Reponse 学习笔记

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">&nbsp;&nbsp;&nbsp;
            <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中不存在此用户名时,即可注册成功

@RequestBody 和 @ResponseBody 是 Spring MVC 中用于处理请求和响应的注解。 @RequestBody 注解用于将 HTTP 请求的请求体中的数据绑定到方法参数上。它将请求体中的数据解析为一个对象,可以是 JSON、XML 或其他格式。这样可以方便地将请求数据转化为 Java 对象进行处理。需要注意的是,当直接通过浏览器输入 URL 时,@RequestBody 无法获取到请求体中的数据,需要使用 Java 编程或基于 AJAX 的方法请求,并设置 Content-Type 为 application/json。 例如,可以将返回的对象通过适合的 HttpMessageConverter 写入响应体中。 举个例子,如果有一个登录的后台代码,并且使用了 @RequestBody 和 @ResponseBody 注解,可以这样处理请求: ```java @RequestMapping("/login") @ResponseBody public Object login(@RequestBody User loginUser, HttpSession session) { User user = userService.checkLogin(loginUser); session.setAttribute("user", user); return new JsonResult(user); } ``` 这个方法接收一个包含用户名和密码的 JSON 对象作为请求体,并将其转化为 User 对象进行登录验证。然后将验证结果封装为 JSON 数据返回给前端。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SpringMVC注解之@RequestBody、@ResponseBody](https://blog.csdn.net/weixin_43740680/article/details/92838046)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [@RequestBody 和 @ResponseBody 详解](https://blog.csdn.net/demo_yo/article/details/125792965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值