详解JavaWeb中Servlet和Request、Response

(一)Servlet概念

Servlet:处理请求和响应的过程是由Servlet来进行的,Servlet是为了解决动态页面而衍生的;

(二)Servlet体系结构

Servlet下有GenericServlet和HttpServlet两个抽象类;
**(1)GenericServlet:**将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象;
定义Servlet类时,可以继承GenericServlet,实现service()方法即可;

@WebServlet("/ServletDemo2")
public class ServletDemo2 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("ServletDemo2");
    }
}

**(2)HttpServlet:**对http协议的一种封装,简化操作;
1. 定义类继承HttpServlet
2. 复写doGet/doPost方法

@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

(三)Servlet路径配置

Servlet路径配置一般在继承类的最上面,格式为:
单个路径格式:@WebServlet(“/x x x”)
多层路径格式:@WebServlet({“/x x x”,"/x x x","/x x x","/x x x"})

(四)Request请求

 设置request编码:request.setCharacterEncoding("utf-8");

(1)概念:request对象是来获取请求消息;
(2)request对象继承体系结构:
ServletRequest–继承–>HttpServletRequest
–实现–>org.apache.catalina.connector.RequestFacade 类(tomcat)
(3)request功能:

1. 获取(网页)请求行数据
	* GET /web_Servlet/RequestDemo2?name=zhangsan HTTP/1.1
  • 方法:
    1.1. 获取请求方式 :GET
    * String getMethod()
    1.2. ()获取虚拟目录:/web_Servlet
    * String getContextPath()
    1.3. 获取Servlet路径: /RequestDemo2
    * String getServletPath()
    1.4.获取get方式请求参数:name=zhangsan
    * String getQueryString()
    1.5. (
    )获取请求URI:
    * String getRequestURI(): /web_Servlet/Servletdemo
    * StringBuffer getRequestURL() :http://localhost:8080/web_Servlet/RequestDemo2
  • URL:统一资源定位符 : http://localhost:8080/web_Servlet/RequestDemo2中华人民共和国
  • URI:统一资源标识符 :web_Servlet/RequestDemo2 共和国

1.6. 获取协议及版本:HTTP/1.1
* String getProtocol()
1.7. 获取客户机的IP地址:0:0:0:0:0:0:0:1
* String getRemoteAddr()

@WebServlet("/RequestDemo2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//        1.1. 获取请求方式 :GET
        String method = req.getMethod();
        System.out.println(method);
//        1.2. (*)获取虚拟目录:/web_Servlet
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
//        1.3. 获取Servlet路径: /RequestDemo2
        String servletPath = req.getServletPath();
        System.out.println(servletPath);
//        1.4.获取get方式请求参数:name=zhangsan
        String queryString = req.getQueryString();
        System.out.println(queryString);
//        1.5. (*)获取请求URI:http://localhost:8080/web_Servlet/RequestDemo2
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);
//        1.6. 获取协议及版本:HTTP/1.1
        String protocol = req.getProtocol();
        System.out.println(protocol);
//        1.7. 获取客户机的IP地址:0:0:0:0:0:0:0:1
        String remoteAddr = req.getRemoteAddr();
        System.out.println(remoteAddr);
    }
}
2.获取请求头名字和参数

(1)获取请求头参数:request.getHeader(String name)
(2)获取请求头名字:request.getHeaderNames()
注:获取请求头名字会返回一个Enumeration集合,需要哈希遍历获取请求头名字,然后才能获取每个请求头参数值;
如下:

@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取所有请求头名字
        Enumeration<String> headerNames = req.getHeaderNames();
//        遍历获取所有请求头参数
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
//            根据每次遍历得到的请求头名称获取请求头参数
            String values = req.getHeader(name);
            System.out.println(name+"--->"+values);
        }
    }
}

3.获取请求体数据:

请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

@WebServlet("/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //        获取请求体参数
//        通过字符流获取
        BufferedReader reader = req.getReader();
        String line = null;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }

//        通过字节流获取
        ServletInputStream inputStream = req.getInputStream();
        byte[] b = new byte[1024];
        int len;
        while ((len = inputStream.read(b)) != -1) {
            System.out.println(len);
        }
    }

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

4.获取请求参数

(1)根据请求名称获取请求参数:request.getParameter(String name);
(2)获取所有请求参数名称:request.getParameterNames();返回Enumeration集合,需要遍历打印;
(3)获取所有参数和值的Map集合:request.getParameterMap();
返回一个Map集合,遍历获取;

如下:(1和2)注意:servlet路径和html路径应该一致
1.功能Java代码

@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        根据参数名称获取请求参数
        String username = req.getParameter("username");
        System.out.println(username);
        String password = req.getParameter("password");
        System.out.println(password);
        System.out.println("--------------");
//        获取所有请求的参数名称
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String s = parameterNames.nextElement();
            System.out.println(s);
        }
        System.out.println("--------------");
//        获取所有请求参数的map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for (String name : strings) {
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }
        }
        //        根据参数名称获取参数值的数组
       /* String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("--------------");*/
    }

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

2.Html文件(通过网页访问html文件,录入请求参数,再执行上面的1.功能Java代码,就可以在控制台看到打印信息)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>request4</title>
</head>
<body>
<form action="/web_Servlet/RequestDemo4" method="post">
    <input type="text" placeholder="请输入用户名:" name="username">
    <input type="password" placeholder="请输入密码" name="password">
    <input type="submit" value="注册">
</form>
</body>
</html>
5.web项目中会遇到的中文乱码问题
  • 中文乱码问题:
    • get方式:tomcat 8 已经将get方式乱码问题解决了
    • post方式:会乱码
    • 解决:在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”);
@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置request的编码
        req.setCharacterEncoding("utf-8");

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
6.共享数据+请求转发

(1)存储共享数据:request.setAttribute(String s,Object o);
(2)获取共享数据:request.getAttibute(String s);
(3)获取转发器对象:request.getRequestDispatcher(String Path);
(4)使用RequestDispatcher对象进行转发:forward(request,response);

如下:由RequestDemo6设置共享数据并转发到RequestDemo7;

@WebServlet("/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置共享数据(键值对存储方式)
        req.setAttribute("name","zhangsan");
//        请求转发
        req.getRequestDispatcher("/RequestDemo7").forward(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
@WebServlet("/RequestDemo7")
public class RequestDemo7 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        根据键获取共享数据值
        Object name = req.getAttribute("name");
        System.out.println(name);
        System.out.println("RequestDemo7被访问");

    }

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

(五)Response响应

设置response的编码:response.setContextType("text/html;charset=utf-8")

基本知识了解:

  1. 响应行
    1. 组成:协议/版本 响应状态码 状态码描述
    2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
    1. 状态码都是3位数字
    2. 分类:
    1⃣️1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
    2⃣️2xx:成功。代表:200
    3⃣️3xx:重定向。代表:302(重定向),304(访问缓存)
    4⃣️4xx:客户端错误。
    * 代表:
    404(请求路径没有对应的资源)
    405:请求方式没有对应的doXxx方法
    5⃣️5xx:服务器端错误。代表:500(服务器内部出现异常)
(1)设置响应体步骤:
		1. 获取输出流
			字符输出流:PrintWriter getWriter()
			字节输出流:ServletOutputStream getOutputStream()
		2. 使用输出流,将数据输出到客户端浏览器
@WebServlet("/responseDemo1")
public class responseDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置响应编码
        resp.setContentType("text/html;charset=utf-8");
//				* 字符输出流:PrintWriter getWriter()
        PrintWriter writer = resp.getWriter();
//        		 使用输出流,将数据输出到客户端浏览器
        writer.write("字符输出流");
//				* 字节输出流:ServletOutputStream getOutputStream()
        ServletOutputStream outputStream = resp.getOutputStream();
//        		 使用输出流,将数据输出到客户端浏览器
        outputStream.write("字节输出流".getBytes());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doPost(req, resp);
    }
}
(2)重定向(302)

概念:资源跳转的方式;
步骤:
1.设置重定向:response.setStatus(302);
2.设置响应头(即将跳转到的路径):response.setHeader(“location”,“虚拟路径+servlet路径”);

如下:

@WebServlet("/responseDemo2")
public class responseDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置响应编码
//        resp.setContentType("text/html;charset=utf-8");
//        设置响应状态码
        resp.setStatus(302);
//        设置响应头
        resp.setHeader("location","/webdemo05_war_exploded/responseDemo3");
//        简单的重定向跳转方法
//        resp.sendRedirect("/webdemo05_war_exploded/responseDemo3");

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doPost(req, resp);
    }
}

3.重定向和转发的区别:
重定向(302):
1⃣️地址栏会发生变化;
2⃣️重定向可以访问其他站点的资源;
3⃣️重定向是两次请求,不能使用request对象来共享数据;
转发(forword)
1⃣️地址栏不发生变化;
2⃣️转发只能访问当前服务站下的资源;
3⃣️转发是一次请求,可以使用request来共享数据;

(3)ServletContext对象

1.ServletContext是代表整个web项目和服务器联系
2.获取ServletContext有两个方法:
1⃣️request获取:request.getServletContext();
2⃣️HttpServlet获取:this.getServletContext();
3.ServletContext对象功能:
1⃣️获取MimeType(在互联网通信中定义的一种文件数据类型)
由ServletContext对象getMimeType(String file)获取;
2⃣️域对象:共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)

	* ServletContext对象范围:所有用户所有请求的数据

3⃣️ 获取文件的真实(服务器)路径
1. 方法:String getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println©;
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);

@WebServlet("/servletContextDemo1")
public class servletContextDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取servletContext对象
//        request方法获取
        ServletContext servletContext = req.getServletContext();
//        HttpServlet方法获取
//        ServletContext servletContext1 = this.getServletContext();
//        获取文件名称
      String name="2.jpg";
//        获取MimeType
        String mimeType = servletContext.getMimeType(name);
        System.out.println(mimeType);
//        共享数据
        servletContext.setAttribute("name","jack");
//        获取真实路径
        servletContext.getRealPath("2.jpg");
        servletContext.getRealPath("3.jpg");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        this.doPost(req, resp);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值