Request和Response

243 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

Request和Response

Request:获取请求数据

Response:设置相应数据

@WebServlet({"/demo03","/demo04"})
public class demo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用req对象 获取请求数据
        String name = req.getParameter("name");
        //使用resp对象 设置相应数据
        resp.setHeader("content-type","text/html;charset=utf-8");
        resp.getWriter().write("<h1>"+name+",欢迎你!</h1>");
    }

Request继承体系

image.png 1.Tomcat需要解析请求数据,封装为request对象, 并且创建request对象传递到service方法中

2.使用request对象,查阅JavaEE API文档的 HttpServletRequest接口

请求数据分为三部分

image.png

post:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取post请求体:请求参数
    //1.获取字符输入流
    BufferedReader reader = req.getReader();
    //2.读取数据
    String line = reader.readLine();
    System.out.println(line);
}
<form action="/tomcat1/demo04" method="post">
  <input name="username"><input type="submit">
</form>

通用方式获取请求参数

为了简化代码,将2者获取请求参数的方式统一起来

Request通用方式获取请求参数

image.png Map<String,String[]>getParameterMap()的代码演示

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("get...");
    //1.获取所有参数的map集合
    Map<String, String[]> map = req.getParameterMap();
    for (String key:map.keySet()) {
        //username:zhangsan
        System.out.println(key+":");
        //获取值
        String[] values = map.get(key);
        for(String value:values){
            System.out.print(value+" ");
        }
        System.out.println();
    }

String[ ] getParameterValues(String name)的代码演示

//2.根据key获取参数值,数组
String[] hobbies = req.getParameterValues("hobby");
for(String hobby:hobbies){
    System.out.println(hobby);
}

String getParameter(String name)的代码演示

//3.根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);

既然通用,那么在doPost使用上述代码也可以完成相应业务

请求参数中文乱码处理

Post的解决方法

image.png

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //post解决中文乱码的问题
    req.setCharacterEncoding("UTF-8");
    String username = req.getParameter("username");
    System.out.println(username);
}

get的解决方法

//get解决中文乱码的问题:编码:1.转换为字节数据
//2.把字节数组转为字符串,解码
String s = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
System.out.println(s);

该方法也可以解决post的乱码问题

Request请求转发

请求转发(forward):一种在服务器内部的资源跳转方式

实现方式

image.png 请求转发资源间共享数据:使用Request对象

image.png 请求转发特点:

浏览器地址栏路径不发生变化

能转发到当前服务器的内部资源

一次请求,可以在转发的资源间使用request共享数据

Response

相应数据分为三部分

image.png

Response完成重定向

重定向:

一种资源跳转方式

重定向的图解

image.png 重定向方式1:

//重定向
//1.设置相应状态码302
resp.setStatus(302);
//2.设置相应头
resp.setHeader("Location","resp2");
System.out.println("resp1...");

重定向方式2:

resp.sendRedirect("resp2");

重定向特点:

image.png 与请求转发的特点几乎相反,因此需要具体场景具体分析使用哪种方法

路径问题

路径给浏览器使用:需要加虚拟目录

服务端使用:不需要加虚拟目录

response响应字符数据

//1.获取字符输出流
    PrintWriter writer = resp.getWriter();
    //content-type
    resp.setHeader("content-type","text/html");
    writer.write("<h1>aaa</h1>");
}

上述代码可以解析html代码

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html;charset=utf-8");
    //1.获取字符输出流
    PrintWriter writer = resp.getWriter();
    //content-type

    writer.write("<h1>aaa</h1>");
}

上述代码是上上述代码的优化,可以解决中文乱码问题

PS:该流不需要关闭

response响应字节数据

//1.读取文件
FileInputStream fis = new FileInputStream("d://小哀.jpg");
//2.获取response字节输出流
ServletOutputStream os = resp.getOutputStream();
//3.完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while((len=fis.read(buff))!=-1){
    os.write(buff,0,len);
}
    fis.close();

也能导入坐标使用

image.png

案例:用户登录

流程说明: 1.用户填写用户名密码,提交到LoginServlet

2.在LoginServlet中使用MyBatis查询数据库,验证用户名密码是否正确

3.如果正确,响应“登录成功”,如果错误,响应“登录失败”

image.png

准备环境:

1.复制资料中的静态页面到项目的webapp目录下

2.创建db1数据库,创建tb_user表,创建User实体类

3.导入MyBatis坐标,MySQL驱动坐标

4.创建mybatis-config.xml核心配置文件,UserMapper.xml映射文件,UserMapper接口

5.在UserMapper中

//根据用户名和密码查询用户对象
@Select("select * from tb_user where username = #{username} and password = #{password}")
User select(@Param("username") String username, @Param("password")String password);

6.最关键的在servlet中重写doGet方法

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.接收用户名和密码
    String username = req.getParameter("username");
    String password = req.getParameter("password");

    //2.调用Mybatis完成查询
    //2.1获取sqlSessionFactory对象
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2.2获取sqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //2.3获取Mapper
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //2.4调用方法
    User user = mapper.select(username, password);
    //2.5释放资源
    sqlSession.close();

    //3.判断user是否为null
    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 {
    this.doGet(req, resp);
}

用户注册

流程说明: 1.用户填写用户名、密码等信息,点击注册按钮,提交到RegisterServlet

2.在RegisterServlet中使用MyBatis 保存数据

3.保存前,需要判断用户名是否已经存在:根据用户名查询数据库

image.png

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.接收用户数据
    String username = req.getParameter("username");
    String password = req.getParameter("password");

    //封装用户对象
    User user = new User();
    user.setUsername(username);
    user.setPassword(password);

    //2.调用mapper根据用户名查询用户对象
    //2.1获取sqlSessionFactory对象
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2.2获取sqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //2.3获取Mapper
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //2.4调用方法
    User u = mapper.selectByUsername(username);

    //3.判断用户对象是否为null
    if(u==null){
        //用户名不存在,添加用户
        mapper.add(user);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }else {
        //用户名存在,不能添加
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("用户名已存在");
    }
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    this.doGet(req, resp);
}
//根据用户名查询对象
    @Select("select * from tb_user where username = #{username}")
    User selectByUsername(String username);

    //添加用户
    @Insert("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
}

代码优化

创建SqlSessionFactory代码优化

image.png 上述方式存在问题:

1.代码重复:解决方法:工具类

2.SqlSessionFactory工厂只创建一次,不要重复创建:解决方法:静态方法

public class SqlSessionFactoryUtils {

    private static SqlSessionFactory sqlSessionFactory;
    static {
        //静态代码块会随着类的加载而自动执行,且只执行一次
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

上述在servlet中的代码改成下述代码即可

SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();