servlet常用API、请求及响应的处理

HttpSerlvet类:

核心方法:

方法名调用时机
init在 HttpServlet 实例化之后被调用一次(类似懒汉模式;实例化再创建、调用.)
destory在 HttpServlet 实例不再使用的时候调用一次
service收到 HTTP 请求的时候调用
doGet收到 GET 请求的时候调用(由 service 方法调用)
doPost收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/…收到其他请求的时候调用(由 service 方法调用)

init方法

init方法:tomcat在收到我们的注解里写的路径请求时;就会调用hello_Servlet进行实例化(实例化只进行一次;后续继续收到这样的路径请求就直接利用之前实例化的即可)。也可以让服务器启动时就执行;修改web.xml配置;让tomcat立即实例化servlet;但是当前我们无所谓的。
在这里插入图片描述
我们将这个方法重写;增加一些我们相关逻辑测试一下:只要服务器tomcat不重新启动;init就不会再执行、
在这里插入图片描述

destory

当我们结束这个服务器时;就会执行这个方法里的内容;有时候destory未必能被执行到。取决于你停止服务器的姿势。
smart tomcat的停止按钮:这个操作本质上是通过tomcat的8005端口主动停止;能够触发destroy
直接杀进程:可能来不及执行destroy就没了;所以这个方法并不太靠谱;都不一定能执行到

service

收到http请求就触发;这个方法会根据你的请求是get还是post等等;决定调用哪个。doget方法t等就是在service中调用的。

servlet生命周期

虽然这三个方法我们不太直接会用到;但是它们却是依然无比的重要。
servlet生命周期:什么时候创建;什么时候消失(一个servlet程序可以有很多个servlet;单个servlet的生死不影响整个servlet程序)
1:开始时;执行init
2:每次收到请求;执行service
3:销毁之前执行destroy

演示(构建一个POST请求示例)

两种方式:postman;ajax。

在这里插入图片描述

在这里插入图片描述

ajax:
首先我们在webapp目录下创建一个html页面:然后使用vscode打开。idea这个html下右击Open In选择Explore
1:写标签
2:引入jquery ;进入官网http://releases.jquery.com/;现在3.x版本;选择minified右击;复制链接。
将此链接复制粘贴入src ;https://code.jquery.com/jquery-3.6.4.min.js
3:编写我们的请求
在这里插入图片描述

在这里插入图片描述
这个URL得写小写的url。上述写URL是不行的。
完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.6.4.min.js">

</script>

<script>
$.ajax({
type:'post',
// 相对路径;相当于在http://127.0.0.1:8080/servlet_2基础上拼上一个hello
// 还可以写绝对路径;'/servlet_2/hello'  前面带/是绝对路径;不带/相对路径。http的url是网络路径和盘符无关;文件系统的绝对路径带盘符
// 访问的是hello这个servlet构成的动态页面。
url:'hello' ,
success:function(body,status) {
    console.log(body);
}

}
)

</script>
</body>
</html>
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("/hello")
public class hello_servlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        //super.init();
        System.out.println("init");
    }

    //servlet api提供现成的类;写servlet代码一般继承这个类
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//我们写这个doGet方法不需要我们去调用;而是自动由tomcat在收到get请求时调用
        //super.doGet(req, resp);
        resp.getWriter().write("hello world");
        System.out.println("doget");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // super.doPost(req, resp);
        resp.getWriter().write("哈哈 world");
        System.out.println("dopst");
    }
}

效果:
在这里插入图片描述
启动方式:
先梳理一下几个路径:
http://127.0.0.1:8080/servlet_2/hello 这个servlet程序对应的servlet资源;
C:\mayun\javase_review\servlet_2\src\main\webapp\test.html 这个是我们在webapp上的前端代码;构造POST请求的地方。
因为第一次学习ajax构造POST请求;写的是搜狗的服务器;还没有学习tomcat;所以是双击页面启动就能成功发送请求(看你要请求的资源在哪;像我们写的.html的资源是放在tomcat服务器上的;我们虽然URL本质是发一个get请求获取这个html资源;然后通过这个html里面的代码发其它自定义请求和响应处理。)
这种ajax构造请求确实也是双击浏览器打开就能发送请求。虽然可以写完整的路径 http://127.0.0.1:8080/servlet_2/hello ;这样子我们就不需要通过tomcat启动test.html 也能发送成功。但是违背我们的初衷跨主机交互。如果我把程序打包给别人使用;别人依然没法使用;因为我们得把test.html带上;别人才可以访问。所以干脆把它们放一起;使用tomcat启动。
因为我们这里写的是相对路径 url:‘hello’ 。如果我使用C:\mayun\javase_review\servlet_2\src\main\webapp\test.html启动发送请求;发现我们tomcat服务器收不到请求;这里的基准路径变化了;服务器就不是tomcat的。所以需要用tomcat来启动。(总结;这里URL写绝对路径也是能通过双击的方式成功把请求发送)
localhost:8080/项目名/xxx.html
需要注意:ajax相对路径就不需要带/;绝对路径需要带/。后端注解则必须要带/;servlet要求

HttpServletRequest 请求处理

tomcat自动构造的;tomcat会实现监听、接收连接、读取请求、解析请求、构造请求等一系列操作

在这里插入图片描述

前端给后端三种传参方式解析(GET,query string;POST,form;POST,json)

GET,query string:req.getQueryString();

直接获取到a=b这个字符串;要具体内容你得自己拆分。如果多个;获取到字符串a=b&c=d。或者通过下面的方法获取对应的值
在这里插入图片描述

示例1:通过url请求;响应的结果是将这些属性拼接显示浏览器上

//测试三种数据格式的读取响应

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("/ServletTest")
public class ServletTest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);
        //返回的结果是字符串;我们把它拼接起来;最后写到浏览器
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
         //这个方法是将stringBuilder.toString()写在浏览器的body部分;所以我们使用br才是显示换行
        resp.getWriter().write(stringBuilder.toString());
        //告诉浏览器;响应body的格式是什么样的;得按照html格式解析
        resp.setContentType("text/html");
    }
}

效果:
在这里插入图片描述

POST,form:getParameter/

2:form表单:如果是form表单post请求;里面的格式数据也是键值对;只是这部分内容在body里。
getParameter即可获取query string的键值对;还能获取到form表单构造body中键值对。整体过程:前端from提交到tomcat服务器;tomcat构造req和resp对象;我们通过req对象获取其中内容;通过resp编写响应;tomcat发送响应给浏览器。

使用枚举方式返回处理;获取里边的键值对;跟迭代器很相似:
form请求的构建:
在这里插入图片描述


  //测试三种数据格式的读取响应

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.util.Enumeration;

@WebServlet("/ServletTest")
public class ServletTest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);
        //返回的结果是字符串;我们把它拼接起来;最后写到浏览器
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
         //这个方法是将stringBuilder.toString()写在浏览器的body部分;所以我们使用br才是显示换行
        resp.getWriter().write(stringBuilder.toString());
        //告诉浏览器;响应body的格式是什么样的;得按照html格式解析
        resp.setContentType("text/html");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doPost(req, resp);
        StringBuilder stringBuilder2=new StringBuilder();
//        返回请求的所有头名;我们把这个头名打印到浏览器。

        Enumeration<String> headerNames=req.getHeaderNames();
        while (headerNames.hasMoreElements()){
        stringBuilder2.append(headerNames.nextElement());
        stringBuilder2.append("<br>");


        }
//        通过key获取value;req.getParameter能获取query string和form表单value;key不存在就返回null
        stringBuilder2.append(req.getParameter("liao"));
        resp.getWriter().write(stringBuilder2.toString());
        //告诉浏览器;响应body的格式是什么样的;得按照html格式解析
        resp.setContentType("text/html");//注意别写成test;test是测试;text才是文本;
        System.out.println("123");

    }
}

效果:
在这里插入图片描述

在这里插入图片描述

POST,json:getInputStream()

3:json:键值对格式;可以把body按照这个格式来组织;比如在postman里构建
在这里插入图片描述
InputStream getInputStream()返回一个输入流对象;对这个对象read就把body读出来。

import javax.servlet.ServletException;
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.util.Enumeration;
//处理body为json格式
public class Postman extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doPost(req, resp);
        //流对象里面长度是多少;我们是可以获取的;Content-Length
        int length=req.getContentLength();
        byte[]buffer=new byte[length];
        //把读到的东西填充到这个数组里
        InputStream inputStream= req.getInputStream();
        inputStream.read(buffer);

        //然后我们再构造成String;打印出来
        String body=new String(buffer,0,length,"utf8");
        System.out.println("body:"+body);
        //写入浏览器页面去
        resp.getWriter().write(body);
    }
}

三种方法是等价的;目前使用json格式做法更多。但是json我们只是把整个body读出来;并没有按照键值对方式处理;也就是不能根据key获取value(form表单可以根据key获取value;getParameter支持)
我们可以使用第三方库解析json格式;后面学到的spring mvc支持json格式;内置jackson这个库解析json格式。

jackson(解析json格式的库)

前面说过;maven是管理依赖的;我们创建的是maven项目;就不必像最初的JDBC导入第三方库一样;下载再拖进来。
找到官网:https://mvnrepository.com/search?q=jackson
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意放的位置:刚复制粘贴后;会标红;等待依赖下载完就不会了;如果还是标红就右边maven刷新一下
在这里插入图片描述
使用:

import com.fasterxml.jackson.databind.ObjectMapper;

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;

//处理body为json格式
@WebServlet("/Postman_json1")
public class Postman_json1 extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper=new ObjectMapper();
        // readValue 就是把一个 json 格式的字符串转成 Java 对象.注意这两个参数分别是啥;转成学生类的对象
        //先从body读出json格式字符串;再看转成什么对象;会把json格式解析成键值对方式
        //遍历键值对;看键的名字和Student的实例中哪个属性的名字匹配;就把这个值赋予该属性。最后返回这个对象

        Student student = objectMapper.readValue(req.getInputStream(), Student.class);
        System.out.println(student.studentId + ", " + student.classId);


    }
}
class Student {
    public int studentId;
    public int classId;
}

如果没有请求参数Student没有的字段会怎么样;或者Student的字段比json的参数多出来的会怎么样???

writeValue:把java对象转成json格式字符串;

HttpServletResponse 响应处理

核心方法:
在这里插入图片描述

状态码

状态码的效果;就什么效果也没有;并不会产生我们对应响应效果;只是一个标识规定而已。比如我们在做统一功能处理的时候;我可以统一给你返回的都是状态码200;但是你响应内容得提示用户是不是出错;还是正常响应页面。需要自己在响应里做出相应的处理。

header

针对响应进行操作:
set:设置一个header;如果name存在就替换
add:增加一个header;如果name存在就增加一个新的;而不是覆盖。所以应该http响应中的报头key是可以存在多个重复的

编码与ContentType

设置编码: resp.setCharacterEncoding(“utf8”)
如果不设置;浏览器对中文不知道是哪种编码理解;浏览器是胡乱猜的编码理解(浏览器每次猜的都是一样;就是错也会一直错下去);我们得告诉浏览器响应的编码格式。
设置ContentType: resp.setContentType(“text/html”);
注意:设置字符集和ContentType得在write上面;写在write下面是不会生效的。两个一起设置也行resp.setContentType(“text/html”;“utf8”);

构造重定向响应

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Response extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      resp.setStatus(302);
      resp.sendRedirect("https://www.sogou.com");
      //resp.sendError(404);//返回tomcat自带错误页面;我们也可以设置状态码;然后自己写错误信息返回写入到body显示浏览器的页面
      
    }
}

抓包效果:这里的时区是美国的;跟我们这里是不一样的。状态码的描述不是必须的。loaction代表的是我们要定向到那个路径。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Servlet APIJava Web开发的核心,它提供了一系列的接口和类来处理HTTP请求响应。下面是Servlet API编程常用的接口类: 1. Servlet接口 Servlet接口定义了一个服务方法service(),用于处理客户端的请求。开发者只需要继承该接口,实现service()方法即可编写Servlet组件。 2. HttpServletRequest接口 HttpServletRequest接口封装了HTTP请求的所有信息,包括请求头、请求参数、请求方法、请求URL等。开发者可以通过该接口提供的方法获取这些信息。 3. HttpServletResponse接口 HttpServletResponse接口封装了HTTP响应的所有信息,包括响应头、响应状态码、响应内容等。开发者可以通过该接口提供的方法设置这些信息。 4. HttpSession接口 HttpSession接口封装了一个会话的所有信息,包括会话ID、创建时间、最后访问时间等。开发者可以通过该接口提供的方法读写会话中的数据。 5. ServletConfig接口 ServletConfig接口封装了Servlet组件的配置信息,包括Servlet名称、初始化参数等。开发者可以通过该接口提供的方法获取这些信息。 6. ServletContext接口 ServletContext接口封装了整个Web应用程序的上下文信息,包括应用程序的全局参数、资源路径、Servlet组件等。开发者可以通过该接口提供的方法获取这些信息。 7. RequestDispatcher类 RequestDispatcher类用于在Servlet组件之间进行请求转发,即将请求转发给另一个Servlet或JSP页面进行处理。 8. Cookie类 Cookie类封装了HTTP请求响应中的Cookie信息,开发者可以通过该类提供的方法读写Cookie信息。 9. HttpServlet类 HttpServlet类是Servlet接口的抽象实现类,开发者可以继承该类编写Servlet组件。该类提供了一些常用的方法,如doGet()、doPost()等,用于处理HTTP请求响应。 以上就是Servlet API编程常用的接口和类。在Java Web开发中,开发者需要熟练掌握这些接口和类的使用,才能编写出高效、可靠的Web应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

while(true)energy++;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值