Request和Response&案例

Request(请求)&Response(响应)

  • Resquest:获取请求数据
  • Response:设置响应数据

Request继承体系

在这里插入图片描述

  1. Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
  2. 使用request对象,查阅JavaEEAPI文档的HttpServletRequest接口

Request获取请求数据

请求数据分为三部分:

  1. 请求行:GET/request-demo/req1?username=zhangsan HTTP/1.1
    	//String getMethod():获取请求方式
        String method=req.getMethod();
        System.out.println(method);
        //String getContextPath():获取虚拟目录(项目访问路径)
        String contextPath=req.getContextPath();
        System.out.println(contextPath);
        //StringBuffer getRequestURL():获取URL(统一资源定位符)
        StringBuffer url=req.getRequestURL();
        System.out.println(url.toString());
        //String getRequestURI():获取URI(统一资源标识符)
        String uri=req.getRequestURI();
        System.out.println(uri);
        //String getQueryString():获取请求参数(GET方式)
        String queryString=req.getQueryString();
        System.out.println(queryString);
        /*
        	GET
    		/request-demo
    		http://localhost:8080/request-demo/req1
    		/request-demo/req1
    		username=zhangsan
    	*/
    
  2. 请求头
    //获取请求头:user-agent:浏览器的版本信息
        String agent=req.getHeader("user-agent");
        System.out.println(agent);
    
  3. 请求体
    //获取post 请求体:请求参数
    
        //1.获取字符输入流
        BufferedReader br=req.getReader();
        //2.读取数据
        String line=br.readLine();
        System.out.println(line);
    

Request通用方式获取请求参数

		//1.获取所有参数的Map集合
        Map<String,String[]> map=req.getParameterMap();
        for (String key:map.keySet()){
            //username:zhangsan...
            System.out.print(key+":");

            //获取值
            String[] values=map.get(key);
            for (String value:values){
                System.out.print(value+" ");
            }
            System.out.println();
        }
        //2.根据key获取参数值(数组)
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        //3.根据参数,获取单个参数值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        
        System.out.println(username);
        System.out.println(password);

Request请求参数中文乱码

在这里插入图片描述

  • Post解决方案

    	//设置字符输入流的编码
        request.setCharacterEncoding("UTF-8");
    
  • 通用方式(GET/POST):先编码,再解码

    //3.1先对乱码数据进行编码:转为字节数组
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //3.2 字节数组解码
        username=new String(bytes,StandardCharsets.UTF_8);
    
        System.out.println("解决乱码后:"+username);
    

URL编码

  1. 将字符串按照编码方式转为二进制
  2. 每个字节转为2个16进制数并在前边加上%

Tomcat 8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8

请求转发(forword)

  • 一种在服务器内部的资源跳转方式
    在这里插入图片描述
  • 实现方式
    req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用Request对象
    void setAtribule(Sting name, Object a): 存储数据到 request域中
    Object getAtribute(String name): 根据 key,获取值
    void.removeAttribute(String name): 根据 key,删除该键值对
  • 请求转发特点:
    浏览器地址栏路径不发生变化
    只能转发到当前服务器的内部资源
    一次请求,可以在转发的资源间使用reguest共享数据

Response设置响应数据功能

响应数据分为3部分:

  1. 响应行: HTTP/1.1 200 OK
    void setStatus(intsc) : 设置响应状态码
  2. 响应头: Content-Type: text/html
    void setHeader(String name, String value) : 设置响应头键值对
  3. 响应体: <html><head>head><body></body></html>
    • PrintWriter getWriter(): 获取字符输出流
    • ServletOutpytStream getOutputStream(): 获取字节输出流

Response完成重定向

  • 重定向:一种资源跳转方式
  • 实现方式:
    //重定向
        //1.设置响应状态码
        response.setStatus(302);
        //2.设置响应头 Location
        response.setHeader("Location","/request-demo/resp1");
    
        //简化方式
        response.sendRedirect("/request-demo/resp1");
    
  • 重定向特点:
    • 浏览器地址栏路径发生变化
    • 可以重定向到任意位置的资源 (服务器内部、外部均可)
    • 两次请求,不能在多个资源使用request共享数据

资源路径问题

明确路径给谁用

  • 浏览器使用:需要加虚拟目录(项目访问路径)
  • 服务端使用: 不需要加虚拟目录(如转发)

动态获取虚拟目录
String contextPath = request.getContextPath();

Response响应字符数据

  • 使用
    1. 通过Response对象获取字符输出流
      PrintWriter writer = resp.getWriter();
    2. 写数据
      writer.write("aaa");
  • 注意:
    • 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
    • 中文数据乱码:原因通过Response获取的字符输出流默认编码: ISO-8859-1
      resp.setContentType("text/html;charset=utfi-8");

Response响应字节数据

  • 使用:
    1. 通过Response对象获取字符输出流
      SerletOutputStream outputStream = resp.getOutputStream();
    2. 写数据
      outputStream.write(字节数据);
  • lOUtils工具类使用:
    1. 导入坐标
      <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
      </dependency>
      
    2. 使用:
      IOUtils.copy(输入流,输出流);

案例

用户登录

  • 流程说明
    1. 用户填写用户名密码,提交到LoginServlet
    2. 在 LoginServlet中使用 MyBatis查询数据库,验证用户名密码是否正确
    3. 如果正确,响应“登录成功”,如果错误,响应“登录失败”
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决post乱码
        request.setCharacterEncoding("UTF-8");
        //1.接收用户名和密码
        String username = request.getParameter("username");
        String password = request.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 userMapper=sqlSession.getMapper(UserMapper.class);
        //2.4调用方法
        User user=userMapper.select(username,password);
        //2.5释放资源
        sqlSession.close();

        //获取字符输出流,并设置content type
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //3.判断user是否为null
        if(user!=null){
            //登陆成功
            writer.write("登陆成功");

        }else {
            //登陆失败
            writer.write("登陆失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

用户注册

  • 流程说明
    1. 用户填写用户名、密码等信息,点击注册按钮,提交到 ReqisterServlet
    2. 在RegisterServlet 中使用 MyBatis 保存数据
    3. 保存前,需要判断用户名是否已经存在: 根据用户名查询数据库
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决post乱码
        request.setCharacterEncoding("UTF-8");
        //1.接收用户名和密码
        String username = request.getParameter("username");
        String password = request.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 userMapper=sqlSession.getMapper(UserMapper.class);
        //2.4调用方法
        User user1 = userMapper.selectByUsername(username);

        //3.判断用户对象是否为null
        if (user1==null){
            //用户不存在,添加用户
            userMapper.add(user);
            //提交事务
            sqlSession.commit();
            //释放资源
            sqlSession.close();

            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("注册成功");

        }else {
            //用户存在,给出提示信息
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("用户已存在");

        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

代码优化

配置SqlSessionFactory工具类

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

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

    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值