request&response



request


什么是request

在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求头和请求体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法.


在这里插入图片描述



Web服务器【tomcat】收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。(request对象和response对象是由Web服务器tomcat 创建的)

Request:封装请求信息,获取请求信息

Request体系结构:request–>RequstFacade-实现->HttpServletRequest-继承->ServletRequest


request作用(处理请求信息)

  • 操作请求信息
  • 请求转发【资源跳转
  • 共享数据

操作请求行和请求头


获取客户机信息(操作请求行)

请求方式 请求路径(URI) 协议版本

GET /day22/login.html?username=admin&password=123 HTTP/1.1

  • getmethod();获取请求方式

  • getRemoteAddr() ;获取客户机的IP地址(知道是谁请求的)

  • getcontextpath();获得当前应用工程名(部署的路径 虚拟路径);

  • getRequestURI();获得请求地址,不带主机名和端口号

  • getRequestURL();获得请求地址,带主机名

  • getServerPort();获得服务端的端口

  • getQueryString();获得请求参数(get请求的,URL的?后面的. eg:username=zs&password=123456)

package com.execise.web.request;

import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/request02")
public class RequestServlet02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet02...");
        // GET  /day24/request02?username=admin&password=123   HTTP/1.1
        //1.获取请求方式get|post              String   getmethod()
        String method = request.getmethod();
        System.out.println("method = " + method);
        //2.获取资源地址uri                   String   getRequestURI()  不包含协议、ip地址、端口号
        String requestURI = request.getRequestURI();
        System.out.println("requestURI = " + requestURI);
        //3.获取请求请求路径url StringBuffer getRequestURL()   包含协议、ip地址、端口号一个完整的地址
        StringBuffer requestURL = request.getRequestURL();
        System.out.println("requestURL = " + requestURL);
        //4.获取项目虚拟路径                  getcontextpath()
        String contextpath = request.getcontextpath();
        System.out.println("contextpath = " + contextpath);
        //5.获取参数                         getQueryString()
        String queryString = request.getQueryString();
        System.out.println("queryString = " + queryString);
        //6.获取客户端ip地址                  getRemoteAddr()
        String remoteAddr = request.getRemoteAddr();
        System.out.println("remoteAddr = " + remoteAddr);
    }

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

获得请求头信息(操作请求头)

请求头: 浏览器告诉服务器自己的属性,配置的, 以key value存在, 可能一个key对应多个value


在这里插入图片描述


getHeader(String name);

  • User-Agent: 客户端浏览器信息

  • Referer:来自哪个网站(防盗链)

@WebServlet("/request03")
public class RequestServlet03 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet03...");
        //user-agent:获取客户端浏览器信息  方便根据浏览器的版本,解决浏览器的兼容性问题
        //referer:获取从哪里进来的  方便做防盗链处理
        String userAgent = request.getHeader("user-agent");
        System.out.println("userAgent = " + userAgent);
        String referer = request.getHeader("referer");
        System.out.println("referer = " + referer);

    }

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

小结

  1. 操作请求行

    1. getmethod():获取请求方式 get|post
    2. getcontextpath():获取项目发布的虚拟路径
    3. getRequestURI():获取请求地址(不带协议、ip地址、端口号)

  1. 操作请求头

    1. user-agent:获取客户端浏览器的版本信息
    2. referer:获取客户端从哪一个地址进来

操作请求体(获得请求参数)


获得请求参数【通用】


@H_502_834@
@WebServlet("/request05")
public class RequestServlet05 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet05...");
        //get方式请求:不乱码  tomcat8以后已经处理好了
        //post方式请求:乱码  需要添加一句代码解决 设置服务器解析请求信息使用的字符集
        request.setCharacterEncoding("UTF-8");

        //获取请求参数   通用方法【无论是get请求还是post方式请求都可以使用】
        //getParameter():获取单个值
        //getParameterValues():获取多个值 指的是获取复选框的值
        //getRequestMap():获取所有参数封装到map集合中 参数名称作为key,参数值作为value
        String username = request.getParameter("username");
        System.out.println("username = " + username);
        String password = request.getParameter("password");
        System.out.println("password = " + password);

        String[] hobbies = request.getParameterValues("hobby");
        System.out.println("hobby----");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }

        System.out.println("--------------------------------------------------");
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> keys = parameterMap.keySet();
        for (String key : keys) {
            System.out.println(key);
            String[] values = parameterMap.get(key);
            for (String value : values) {
                System.out.println(value);
            }
        }
    }

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

请求参数乱码处理

我们在输入一些中文数据提交给服务器的时候,服务器解析显示出来的一堆无意义的字符,就是乱码。

那么这个乱码是如何出现的呢?如下图所示:


在这里插入图片描述


  1. get方式, 我们现在使用的tomcat>=8.0了, 乱码tomcat已经处理好了

  2. post方式, 就需要自己处理


void setCharacterEncoding(String env); //设置请求体的编码
//处理post请求中文乱码
request.setCharacterEncoding("UTF-8");

乱码处理:保证编码和解码所使用的字符集一致,即可解决乱码。


使用BeanUtils封装

现在我们已经可以使用request对象来获取请求参数,但是,如果参数过多,我们就需要将数据封装到对象。

以前封装数据的时候,实体类有多少个字段,我们就需要手动编码调用多少次setXXX方法,因此,我们需要BeanUtils来解决这个问题。

BeanUtils是Apache Commons组件的成员之一,主要用于简化JavaBean封装数据的操作。


使用步骤:

  1. 导入jar
  2. 使用BeanUtils.populate(user,map)

表单 reg.html


<form action="request06" method="post">
    username:<input type="text" name="username"><br>
    password:<input type="password" name="password"><br>
    hobby:<input type="checkBox" name="hobby" value="sing">唱歌
            <input type="checkBox" name="hobby" value="dance">跳舞
            <input type="checkBox" name="hobby" value="code">代码
    <input type="submit" value="注册">
</form>

RequestServlet06



@WebServlet("/request06")
public class RequestServlet06 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet06...");

        //解决请求中文乱码
        request.setCharacterEncoding("UTF-8");

        try {
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user = new User();
            //注意:map的key要和java对象属性一致
            BeanUtils.populate(user,parameterMap);
            System.out.println("user = " + user);
        } catch (Exception e) {
            e.printstacktrace();
        }
    }

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

小结

  1. 获取请求参数【通用】

    1. getParameter(String name):根据参数名称获取单个值
    2. getParameterValues(String name):根据参数名称获取多个值 用于复选框
    3. getParameterMap():获取所有请求参数封装到Map集合中
  2. 请求参数中文乱码处理

    1. get方式:没有中文乱码 无需处理 tomcat8.0版本以后已经处理了
    2. post方式:需要处理 request.setCharacterEncoding(“UTF-8”);
  3. 使用BeanUtils将所有请求参数map集合中的数据封装到javabean对象

    1. 导入jar包

    2. BeanUtils.populate(Object bean,Map map);

      注意:Map集合的key一定要和javabean的属性一致。


知识点-请求转发


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

html:a标签、form表单action

js:location.href=“…”


在这里插入图片描述


//转发:就是将客户端的请求交给另外一个Servlet处理

//1.获取转发对象
request.getRequestdispatcher("转发地址"); 
//2.跳转
forward(request,response);

//经常就一步完成
request.getRequestdispatcher("转发地址").forward(request,response);

RequestServlet07.java



@WebServlet("/request07")
public class RequestServlet07 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet07...");

        //共享数据
        request.setAttribute("rkey","rrr");

        //转发实现 相对路径
        request.getRequestdispatcher("request08").forward(request,response);

        //转发实现 绝对路径   服务器端使用/:表示http://localhost:8080/虚拟路径
        //request.getRequestdispatcher("/request08").forward(request,response);

        //转发不能访问到外部资源
        //request.getRequestdispatcher("https://www.baidu.com").forward(request,response);
        //转发可以访问到WEB-INF下的资源
        //request.getRequestdispatcher("WEB-INF/haha.html").forward(request,response);
    }

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

RequestServlet08.java


package com.execise.web.request;

import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/request08")
public class RequestServlet08 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("RequestServlet08...");
        //转发一次请求  可以使用Request对象共享数据
        Object rkey = request.getAttribute("rkey");
        System.out.println(rkey);
    }

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

特点:

  1. 转发发生在服务器内部,不能请求外部资源

  2. 转发地址栏不发生改变

  3. 转发发送一次请求

  4. 转发一般使用相对路径

  5. 转发请求数据不会丢失

  6. 转发可以访问到WEB-INF下的资源


小结

  • 转发 :指的是将客户端的请求,服务端接收之后再交给第三方处理,是一种服务器内部资源跳转方式。

  • 实现:request.getRequestdispacther(“转发地址”).forward(request,response);


作为域对象存取值


ServletContext:域对象 代表的是整个应用

域对象:一个有作用范围的对象 ,在它的作用范围中可以实现数据共享

request域对象:一次请求,因此一般只能在转发中使用数据共享

域对象是一个容器,这种容器主要用于Servlet与Servlet/JSP之间的数据传输使用的。

  • Object getAttribute(String name) ;

  • void setAttribute(String name,Object object) ;

  • void removeAttribute(String name) ;


小结

  1. request域对象:在一次请求中共享数据,只能用在转发中

  2. API

    • setAttribute(String name,Object value);

    • getAtrribute(String name);

    • removeAttribute(String name);



Response


HttpServletResponse概述

​Response:封装响应信息,响应给客户端浏览器

体系结构:response–>RequestFacade-实现->HttpServletResponse-继承->ServletResponse

在Servlet API中,定义了一个HttpServletResponse接口(doGet,doPost方法的参数),它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为响应行、响应头、响应体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应头、响应体的方法


作用

设置响应的三部分(响应行,响应头,响应体)


小结

  1. Response:封装响应信息,设置响应信息 响应给客户端浏览器

  2. 体系结构:ServletResponse–继承–>HttpServletResponse–实现–>ResponseFacade

  3. tomcat创建了request和response对象,开发中只需要使用这两个对象即可,使用request对象获取请求信息,使用response对象设置响应信息。

  4. 作用:设置响应内容


知识点-操作响应行


响应行
HTTP/1.1  200
响应头
响应体

在这里插入图片描述


常用的状态码:

200:请求成功

404:请求资源不存在 【请求地址写错】

500:服务器内部错误 【java代码报错】

302:重定向

304:读取缓存数据

403:请求禁止 没有权限访问

406:请求和响应的内容不一致


小结

  1. 设置的API: response.setStatus(int code);

  2. http状态码

    1. 200:成功
    2. 404:请求资源不存在
    3. 500:服务器内部错误

知识点-操作响应头


响应头: 是服务器指示浏览器去做什么

一个key对应一个value


操作响应头的API


在这里插入图片描述


一个key对应多个value


在这里插入图片描述


关注的方法: setHeader(String name,String value);

常用的响应头:

  1. Refresh:定时跳转 (eg:服务器告诉浏览器5s之后跳转百度)

  2. Location:重定向地址(eg: 服务器告诉浏览器跳转到xxx)

  3. Content-disposition: 告诉浏览器下载

  4. Content-Type:设置响应内容的MIME类型(服务器告诉浏览器内容的类型)


定时刷新

response.setHeader("refresh","秒数;url=跳转的路径"); //几秒之后跳转到指定的路径上

response.setHeader("refresh","5; url=http://www.baidu.com");

重定向


@H_404_2679@


在这里插入图片描述


response.sendRedirect("demo09");
package com.execise.web.response;

import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/response02")
public class ResponseServlet02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("ResponseServlet02...");
        //重定向实现方式一:
        //设置响应码
        //response.setStatus(302);
        //设置响应头
        //response.setHeader("location","response03");

        //重定向实现方式二: response.sendRedirect("新的地址");
        //response.sendRedirect("response03");

        //重定向访问外部资源
        //response.sendRedirect("http://www.baidu.com");

        //使用绝对路径重定向
        response.sendRedirect("/day23/response03");

    }

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

重定向


 response.sendRedirect("重定向的路径");

特点:

  1. 重定向地址栏发送改变

  2. 重定向发生了两次请求

  3. 重定向不能访问WEB-INF下的资料,并且请求数据会丢失

  4. 重定向可以访问外部资源

  5. 重定向一般使用绝对路径,如果是同一个项目内的资源,可以使用相对路径。


小结

操作响应头

response.setHeader(String name,String value)

重定向

重定向 :服务端让客户端重新发送一次请求

实现:response.sendRedirect(“重定向地址”);

转发和重定向的区别 【forward和redirect的区别?】:

  1. 转发发送一次请求,地址栏不发生改变;重定向发送两次请求,地址栏发送改变

  2. 转发请求信息不会丢失重定向请求信息会丢失

  3. 转发只能请求服务器内部资源;重定向既可以请求服务器内部资源,又可以请求外部资源

  4. 转发可以访问WEB-INF下的资源;重定向不行

  5. 转发一般使用相对路径,重定向使用一般使用绝对路径


相对路径和绝对路径


相对路径:有参照物,根据当前位置进行参照选择资源

./ :当前位置

../:上一级目录

eg:
index.html:<a href="request05">转发</a><br>         :相对的就是当前页面 【静态资源】
ResponseDemo01:response.sendRedirect("response02"); :相对的是当前Servlet地址  【动态资源】

绝对路径:直接通过地址定位唯一资源

1. 以盘符开头的:D:\czbk\java119\day24-request&response

2. 以Http开头的:http://localhost:8080/day24/WEB-INF/a.html

相对路径

   index.html:http://localhost:8080/day24/index.html
   
   response01:http://localhost:8080/day24/response01
   
   所以:这里 我从index.html页面跳转到response01的Servlet  使用相对路径 直接写response01就可以了

路径跳转//表示的是绝对路径

    前端加//加在前端代表的是服务器的地址:http://localhost:8080
    
    后台/: 注意这个地址给谁用:
    
    		 如果是服务器使用【转发】,表示的就是当前应用地址:http://localhost:8080/day24
    		 
             如果是给客户端用【重定向】,表示的就是服务器的地址:http://localhost:8080

一般情况下,项目中建议使用相对路径。


操作响应体


操作响应体的API


在这里插入图片描述


页面输出只能使用其中的一个流实现,两个流是互斥的.


响应乱码处理

解决字符流输出中文乱码问题


response.setContentType("text/html;charset=utf-8");

使用字节输出输出中文乱码问题


//设置浏览器打开方式
response.setHeader("Content-type", "text/html;charset=utf-8");
//得到字节输出
ServletoutputStream outputStream = response.getoutputStream();
outputStream.write("你好".getBytes("utf-8"));// 使用平台的认字符(utf-8)集将此 String 编码为 byte 序列
package com.execise.web.response;

import javax.servlet.servletexception;
import javax.servlet.ServletoutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/response04")
public class ResponseServlet04 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        System.out.println("ResponseServlet04...");
        //设置响应内容的字符编码集
        //response.setCharacterEncoding("UTF-8");

        //服务器直接告诉浏览器我给你响应的内容 你应该使用什么字符集编码解析
        response.setContentType("text/html;charset=UTF-8");

        //以字符流的方式向客户端浏览器输出内容
        //response.getWriter().print("Hello SZ118");
        //response.getWriter().print("中国威武!");

        //以字节流的方式向客户端浏览器输出内容
        ServletoutputStream outputStream = response.getoutputStream();
        //outputStream.write("Hello World!".getBytes());
        outputStream.write("打倒小日本!".getBytes("UTF-8"));
    }

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

小结

  1. 操作响应体

    1. 字符流输出:response.getWriter().print(“…”);

    2. 字节流输出:response.getoutPutStream.write(byte[]);

  2. 响应中文乱码

    1. 原因:内容在编码和解码时使用的字符编码集不一致导致。

    2. 解决:response.setContentType(“text/html;charset=UTF-8”);


案例-完成文件下载


创建文件下载的列表的页面,点击列表中的某些链接,下载文件.


在这里插入图片描述


文件下载分析

将服务器上已有的文件拷贝到本地(客户端)

IO流操作 response.getoutputStream()向客户端写入流


文件下载的方式

  • 第一种:超链接方式(不推荐)

链接的方式:直接将服务器上的文件的路径写到href属性中.如果浏览器不支持该格式文件,那么就会提示进行下载保存, 如果浏览器支持这个格式(eg: png, jpg…)的文件,那么直接打开,不再下载了


  • 第二种:手动编码方式(推荐)

手动编写代码实现下载.无论浏览器是否识别该格式的文件,都会下载.


链接方式

  1. 准备下载资源

  2. 编写下载页面 编写a标签

  3. 浏览器访问下载


编码方式

手动编码方式要求

  • 设置两个头和一个

  • 设置的两个头:

    Content-dispostion: 服务器告诉浏览器去下载

    Content-Type: 告诉浏览器文件类型.(MIME的类型)



思路

  1. 处理请求响应中文乱码

  2. 获取要下载的文件名称

  3. 使用ServletContext对象获取要下载文件的字节输入流

  4. 设置响应头,告诉浏览器执行下载操作

  5. 设置响应头,告诉浏览器要下载的文件类型

  6. 使用response以字节流的方式将下载文件内容输出到客户端浏览器


代码实现

package com.execise.web.response;

import sun.misc.BASE64Encoder;

import javax.servlet.servletexception;
import javax.servlet.ServletoutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Base64;


@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        //0.处理请求响应中文乱码 
        request.setCharacterEncoding("UTF-8");
        //response.setContentType("text/html;charset=UTF-8");
        //1.获取要下载的文件
        String filename = request.getParameter("filename");
        System.out.println("下载的原文件名:filename = " + filename);

        //2.根据文件名找到要下载的文件,得到文件输入流对象         
        InputStream is = getServletContext().getResourceAsstream("download/" + filename);

        //3.获取文件的MIME类型
        String mimeType = getServletContext().getMimeType(filename);

        //4.设置服务器响应浏览器的内容类型 当前用户下载的是什么类型文件 你就设置该文件的MIME类型 告诉浏览器
        response.setContentType(mimeType);

        /*==================对文件名进行使用UTF-8编码  防止中文乱码================*/
        //高版本的Firefox和google以及其他的浏览器对下载的文件名进行编码都是使用url的UTF-8
        //低版本的Firefox使用的base64编码
        String userAgent = request.getHeader("user-agent");
        if(userAgent.contains("Firefox")){
            filename = base64EncodeFileName(filename);
        }else{
            filename = URLEncoder.encode(filename,"UTF-8");  //编码后的文件
        }

        System.out.println("编码后的文件名:filename = " + filename);

        //5.告诉浏览器下载文件,不要直接打开 
        response.setHeader("Content-disposition","attachment;filename="+filename);

        //6.将要写在的文件写给客户端浏览器【文件复制】 使用response.getoutputStream获取字节输出流对象  向浏览器写入要下载的文件数据
        ServletoutputStream os = response.getoutputStream();
        int length = 0;
        byte[] bytes = new byte[8192];
        while((length=is.read(bytes))!=-1){
            os.write(bytes,0,length);
        }
        is.close();
        os.close();
    }

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

    //火狐浏览器专门编码
    public static String base64EncodeFileName(String fileName) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        try {
            return "=?UTF-8?B?"
                    + new String(base64Encoder.encode(fileName
                    .getBytes("UTF-8"))) + "?=";
        } catch (UnsupportedEncodingException e) {
            e.printstacktrace();
            throw new RuntimeException(e);
        }
    }
}

细节处理

告诉浏览器设置的响应头里面不支持中文的, 抓包来看:


在这里插入图片描述


解决方案: 手动进行编码再设置进去就ok了

filename = URLEncoder.encode(filename,“UTF-8”);



综合案例-注册


在这里插入图片描述


说白了:就是向数据库中插入一条用户记录


数据库

create database day24;

use day24;

-- 创建用户
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;

JavaBean


package com.execise.bean;

import java.io.Serializable;

public class User implements Serializable {

    private Integer id;
    private String username;
    private String password;

    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 + '\'' +
                '}';
    }
}

导入依赖


<!--设置JDK的编译版本为1.8-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--依赖管理-->
  <dependencies>

    <!--servlet-api-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!--BeanUtils-->
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.9.3</version>
    </dependency>

    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!--mybatis jar-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>

    <!--MysqL驱动jar包-->
    <dependency>
      <groupId>MysqL</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>

    <!-- log start -->
    <!-- 日志的具体实现  -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <!--  接口  -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
    </dependency>
    <!-- log end -->
  </dependencies>

  <build>
      <plugins>
        <!--Tomcat插件-->
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.2</version>
          <!--Tomcat插件配置-->
          <!--项目首页访问地址:http://localhost:8080/-->
          <configuration>
            <!--设置字符编码-->
            <uriEncoding>UTF-8</uriEncoding>
            <!--访问端口号-->
            <port>8080</port>
            <!--项目访问路径-->
            <path>/</path>
          </configuration>
        </plugin>
      </plugins>
  </build>

工具类和配置文件


db.properties
mybatis-config.xml
log4j.properties

register.html


注册案例思路


在这里插入图片描述


UserDao.java

package com.execise.dao;

import com.execise.bean.User;

public interface UserDao {
    User selectByUsername(String username);

    int add(User user);
}

UserDao.xml

<?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="com.execise.dao.UserDao">
    <!--根据用户名查询用户 返回user对象-->
    <select id="selectByUsername" resultType="user" parameterType="string">
        select * from tb_user where username=#{username}
    </select>

    <!--保存注册用户信息到数据库-->
    <insert id="add" parameterType="user">
        insert into tb_user values(null,#{username},#{password})
    </insert>
</mapper>

RegisterServlet.java

package com.execise.web;

import com.execise.bean.User;
import com.execise.dao.UserDao;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.sqlSession;
import org.apache.ibatis.session.sqlSessionFactory;
import org.apache.ibatis.session.sqlSessionFactoryBuilder;

import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        sqlSession sqlSession = null;
        try {
            //0.处理请求响应中文乱码
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            //1.获取注册用户信息
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user = new User();
            BeanUtils.populate(user,parameterMap);

            //2.根据用户名查询数据库 返回user对象 判断用户名是否存在
            //2.1:加载MyBatis配置文件
            InputStream is = Resources.getResourceAsstream("mybatis-config.xml");
            //2.2:获取sqlSessionFactory对象
            sqlSessionFactory sqlSessionFactory = new sqlSessionFactoryBuilder().build(is);
            //2.3:获取sqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            //2.4:获取dao接口代理对象
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            //2.5:调用方法
            User user1 = userDao.selectByUsername(user.getUsername());

            //3.1:user1==null:用户名不存在,执行注册操作
            if(user1==null){
                userDao.add(user);
                //增删改操作 手动提交事务
                sqlSession.commit();
                response.getWriter().print("用户注册成功!");
            }else{
                //3.2:user1!=null:用户名已存在  进行提示
                response.getWriter().print("用户名已存在!");
            }
        } catch (Exception e) {
            //新增失败 回滚
            sqlSession.rollback();

            e.printstacktrace();
            response.getWriter().print("服务器异常!");
        }finally {
            //2.6:关闭sqlSession对象
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
    }

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

小结

  1. 注册:本质就是向数据库中插入一条数据

  2. 思路:

    1. 获取请求参数

    2. 注册信息插入数据库

    3. 根据处理结果进行响应




案例-登录


在这里插入图片描述



在这里插入图片描述


页面的准备 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<center>
    <h1>用户登录</h1>
    <form action="login" method="post">
        姓名:<input type="text" name="username"/><br/>
        密码<input type="password" name="password"/><br/>
        <input type="submit" value="登录"/>
    </form>
</center>
</body>
</html>

代码实现

UserDao.java

package com.execise.dao;

import com.execise.bean.User;

public interface UserDao {

    User select(User user);
}

UserDao.xml

<?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="com.execise.dao.UserDao">
	<!--根据用户名密码查询用户 返回user对象-->
    <select id="select" resultType="user" parameterType="user">
        select * from tb_user where username=#{username} and password=#{password}
    </select>
</mapper>

LoginServlet.java

package com.execise.web;

import com.execise.bean.User;
import com.execise.dao.UserDao;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.sqlSession;
import org.apache.ibatis.session.sqlSessionFactory;
import org.apache.ibatis.session.sqlSessionFactoryBuilder;

import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;


@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        sqlSession sqlSession = null;
        try {
            //*  0.处理请求响应中文乱码
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");

            //*  1.获取请求参数【用户名密码
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user = new User();
            BeanUtils.populate(user,parameterMap);

            //*  2.根据用户名密码使用MyBatis查询数据库tb_user表 返回user对象
            //2.1:加载MyBatis配置文件
            InputStream is = Resources.getResourceAsstream("mybatis-config.xml");
            //2.2:获取sqlSessionFactory对象
            sqlSessionFactory sqlSessionFactory = new sqlSessionFactoryBuilder().build(is);
            //2.3:获取sqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            //2.4:获取dao接口代理对象
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            //2.5:调用方法
            User loginUser = userDao.select(user);

            //*  3.判断loginUser对象是否为null
            if(loginUser==null){
                //*  3.1:loginUser==null:登录失败
                response.getWriter().print("登录失败!");
            }else{
                //*  3.2:loginUser!=null:登录成功
                response.getWriter().print("登录成功!");
            }


        } catch (Exception e) {
            e.printstacktrace();
            response.getWriter().print("服务器异常!");
        }finally {
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
    }

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

小结

  1. 登录:根据用户名密码查询数据库 看是否存在一条用户记录

  2. 思路:

    1. 获取请求参数

    2. 根据用户名密码查询数据库

    3. 根据返回的user对象 user==null 表示登录失败 user!=null 表示登录成功



总结


1. request

  1. 概念:request用来封装请求信息

  2. 体系结构:HttpServletRequest-继承->ServletRequest

  3. request对象来源:由服务器tomcat创建并传入Servlet

  4. 作用:操作请求信息、请求转发、作为域对象存储数据

  5. 操作请求行

    // 获取请求方式  get|post
    request.getmethod();
    // 获取请求地址URI(不包含主机ip地址和端口号)
    request.getRequestURI();
    // 获取项目的虚拟路径  eg:/day24
    request.getcontextpath();
    
  6. 操作请求头

    // 获取客户端浏览器信息  为了解决浏览器兼容性
    request.getHeader("User-Agent");
    // 获取进入当前资源的上一个地址  作用:防盗链
    request.getHeader("Referer");
    
  7. 操作请求体【获取请求参数】

    // 获取单个值
    request.getParameter("name属性值");
    // 获取多个值
    request.getParameterValues("name属性值");
    // 获取全部请求参数 并封装到Map集合  参数名称作为key 参数值作为value
    request.getParameterMap();
    
    // 请求中文乱码处理
    request.setCharacterEncoding("UTF-8");
    // 使用BeanUtils封装请求信息到javabean
    BeanUtils.populate(javabean名称,参数map集合);
    
  8. 请求转发

    request.getRequestdispatcher("转发的地址").forward(request,response);
    
  9. 作为域对象存储数据

    // request域对象存储数据有效范围:一次请求中
    // 使用场景:转发中使用
    //存
    request.setAttribute(String key,Object value);
    //取
    request.getAttribute(String key);
    //删
    request.removeAttribute(String key);
    

2. response

  1. response:封装响应信息

  2. 体系结构:HttpServletResponse-继承->ServletResponse

  3. response来源:由服务器tomcat创建 并传入到Servlet中

  4. 作用:操作响应信息

  5. 操作响应行 setStatus(int statusCode);

  6. 操作响应头

    // 定时刷新
    response.setHeader("Refresh","5; url=http://www.baidu.com");
    // 重定向
    response.sendRedirect("重定向的地址");
    // 告诉浏览器下载
    response.setHeader("Content-disposition","attachment;filename="+filename);
    // 告诉浏览器下载的文件类型
    response.setHeader("content-type",mimeType);
    
  7. 操作响应体

    // 处理响应中文乱码
    response.setContentType("text/html;charset=UTF-8");
    
    // 输出字符流到客户端浏览器
    response.getWriter.print("输出内容");
    // 输出字节流到客户端浏览器
    response.getoutputStream.write("输出内容");
    

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...
法名 描述
String getParameter(String name) 获得指定参数名对应的值。如果没有则返回null,如果有多个获得第一个。 例如:username=jack
String[] getParameterValues(String name) 获得指定参数名对应的所有的值。此方法专业为复选框提供的。 例如:hobby=抽烟&hobby=喝酒&hobby=敲代码
Map<String,String[]> getParameterMap() 获得所有的请求参数。key为参数名,value为key对应的所有的值。