【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现

这篇具有很好参考价值的文章主要介绍了【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

思考

在解析请求之前我们要思考一个问题,我们解析的是其中的哪些内容?

对于最基本的实现,当然是请求类型请求的url以及请求参数,我们可以根据请求的类型作出对应的处理,通过url在我们的mapstore中找到servlet,那么请求的参数我们是不是还没有储存的地方呢?

所以我们要先定义一个类来存储参数

HttpServletRequest

当然你也可以通过接口的形式来规范方法,我在这里进行的是最基本的仿写,就不做复杂的设计了,下面这个类是存储请求信息的类,我们在后续还会进行扩展,因我们还要实现cookie、session等功能

package com.tomcatServer.domain;

import java.util.HashMap;
import java.util.Map;

/**
 * http servlet请求
 *
 * @author ez4sterben
 * @date 2023/08/15
 */
public class HttpServletRequest {

    private final Map<String,String> params = new HashMap<>();

    private String requestBody;

    public String getRequestBody() {
        return requestBody;
    }

    public void setRequestBody(String requestBody) {
        this.requestBody = requestBody;
    }

    public Map<String, String> getParams() {
        return params;
    }

    public String getParam(String paramName){
        return params.get(paramName);
    }
}


http请求解析,HttpServletRequest

我们再给服务器发一个带参数的请求看看http信息是什么样子的
http://localhost:8080/test?aaa=aaa
【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现,源码仿写,tomcat,http,java,反射,代理
这个信息的第一行就是请求的类型、url和参数,那么我们直接对这里进行解析就行了

// 解析request param
String url = requestData.split(" ")[1];
String[] urlContent = url.split("\\?");
// ?前的是请求地址
String requestPath = urlContent[0];
// 问号后的是参数
String params = urlContent[1];
// 参数按照=分割
String[] paramsKeyValue = params.split("=");

存入map

// 设置请求参数
        HttpServletRequest request = new HttpServletRequest();
        Map<String, String> paramsMap = request.getParams();
        for (int i = 0; i < paramsKeyValue.length; i += 2) {
            paramsMap.put(paramsKeyValue[i],paramsKeyValue[i+1]);
        }

响应类HttpServletResponse

这个类中要注意的是我们要给返回的信息拼上一个头部信息代表着成功编号和信息类型

package com.tomcatServer.domain;

import java.io.PrintWriter;

/**
 * http servlet响应
 *
 * @author ez4sterben
 * @date 2023/08/15
 */
public class HttpServletResponse {

    private final PrintWriter out;

    private static final String response;

    public HttpServletResponse(PrintWriter out) {
        this.out = out;
    }

    static {
        response = "HTTP/1.1 200 OK\r\n" +
                "Content-Type: text/plain\r\n" +
                "\r\n";
    }

    /**
     * 写
     *
     * @param content 内容
     */
    public void write(String content) {
        out.println(response + content);
    }

}


代理

既然实现到这里了,自然会想到,执行谁的响应呢?

没错,当然是servlet中的,那就需要我们使用代理来调用其中的方法了

package com.tomcatServer.utils;

import com.tomcatServer.annotation.WebServlet;
import com.tomcatServer.domain.HttpServletRequest;
import com.tomcatServer.domain.HttpServletResponse;
import com.tomcatServer.servlet.MapStore;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * servlet工具类
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
public class ServletUtil {

    /**
     * 是web servlet
     *
     * @param className 类名
     * @return {@link Boolean}
     */
    public static Boolean isWebServlet(String className){
        try {
            Class<?> aClass = Class.forName(className);
            WebServlet annotation = aClass.getAnnotation(WebServlet.class);
            if (annotation == null){
                return Boolean.FALSE;
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return Boolean.TRUE;
    }


    /**
     * 初始化servlet
     *
     * @param className 类名
     */
    public static void initServlet(String className){
        try {
            Class<?> aClass = Class.forName(className);
            String url = aClass.getAnnotation(WebServlet.class).value();
            if (url.startsWith("/")) {
                MapStore.servletMap.put(url,aClass);
            }else {
                MapStore.servletMap.put("/" + url,aClass);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 调用get方法
     *
     * @param url     url
     * @param request
     */
    public static void invokeGet(String url, HttpServletRequest request, HttpServletResponse response){
        Class<?> aClass = MapStore.servletMap.get(url);
        try {
            Method doGet = aClass.getDeclaredMethod("doGet", HttpServletRequest.class, HttpServletResponse.class);
            Object instance = aClass.newInstance();
            doGet.invoke(instance, request, response);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 调用后
     *
     * @param url      url
     * @param request  请求
     * @param response 响应
     */
    public static void invokePost(String url, HttpServletRequest request, HttpServletResponse response){
        Class<?> aClass = MapStore.servletMap.get(url);
        try {
            Method doPost = aClass.getDeclaredMethod("doPost", HttpServletRequest.class, HttpServletResponse.class);
            Object instance = aClass.newInstance();
            doPost.invoke(instance, request, response);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}

HttpServlet规范

接下来定义一个抽象类来规范servlet类

package com.tomcatServer.domain;

import java.io.IOException;

/**
 * http servlet
 *
 * @author ez4sterben
 * @date 2023/08/15
 */
public abstract class HttpServlet {

    /**
     * 做得到
     *
     * @param request  请求
     * @param response 响应
     * @throws IOException ioexception
     */
    public abstract void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException;

    /**
     * 做帖子
     *
     * @param request  请求
     * @param response 响应
     * @throws IOException ioexception
     */
    public abstract void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException;



}

然后在项目中创建一个测试的servlet类
【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现,源码仿写,tomcat,http,java,反射,代理

package tomcatProject.com.ez4sterben.servlet;

import com.tomcatServer.annotation.WebServlet;
import com.tomcatServer.domain.HttpServlet;
import com.tomcatServer.domain.HttpServletRequest;
import com.tomcatServer.domain.HttpServletResponse;


/**
 * 登录servlet
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
@WebServlet("/test")
public class TestServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        response.write(request.getParam("aaa"));
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) {

    }
}

请求测试

package com.tomcatServer.socket;

import com.tomcatServer.domain.HttpServletRequest;
import com.tomcatServer.domain.HttpServletResponse;
import com.tomcatServer.utils.ScanUtil;
import com.tomcatServer.utils.ServletUtil;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;

/**
 * 套接字存储
 *
 * @author ez4sterben
 * @date 2023/08/15
 */
public class SocketStore {

    private static ServerSocket socket;

    public static void connect(Integer port) throws IOException {
        socket = new ServerSocket(port);
    }

    public static void close() throws IOException {
        socket.close();
    }

    public static ServerSocket getSocket() {
        return socket;
    }


    /**
     * 处理请求
     *
     * @throws IOException ioexception
     */
    public static void handleRequest(Socket accept) throws IOException {
        // 获取输入输出流
        BufferedReader in = new BufferedReader(new InputStreamReader(accept.getInputStream()));
        PrintWriter out = new PrintWriter(accept.getOutputStream(), true);
        // 定义字符串接收Http协议内容
        String inputLine;
        StringBuilder requestData = new StringBuilder();
        // 读取数据
        while ((inputLine = in.readLine()) != null && !inputLine.isEmpty()) {
            requestData.append(inputLine).append("\r\n");
        }
        System.out.println(requestData);
        
        if (!requestData.toString().trim().equals("")){
                handleGetAndPostReuqest(in, out, String.valueOf(requestData));
            }
        // 关闭资源
        accept.close();
    }

    /**
     * 处理post请求
     *
     * @param in          在
     * @param requestData 请求数据
     * @throws IOException ioexception
     */
    private static void handleGetAndPostReuqest(BufferedReader in,PrintWriter out, String requestData) throws IOException {
        // 解析request param
        String url = requestData.split(" ")[1];
        String[] urlContent = url.split("\\?");
        String requestPath = urlContent[0];
        String params = urlContent[1];
        String[] paramsKeyValue = params.split("=");

        // 设置请求参数
        HttpServletRequest request = new HttpServletRequest();
        Map<String, String> paramsMap = request.getParams();
        for (int i = 0; i < paramsKeyValue.length; i += 2) {
            paramsMap.put(paramsKeyValue[i],paramsKeyValue[i+1]);
        }
        if (requestData.contains("GET")){
            // 设置响应内容
            HttpServletResponse response = new HttpServletResponse(out);
            ServletUtil.invokeGet(requestPath,request,response);
        }
    }

}

访问http://localhost:8080/test?aaa=123
因为servlet中的操作是返回参数,所以结果应该为123

response.write(request.getParam("aaa"));

【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现,源码仿写,tomcat,http,java,反射,代理
下一篇将会实现对html页面的解析

【仿写tomcat】五、响应静态资源(访问html页面)、路由支持以及多线程改进文章来源地址https://www.toymoban.com/news/detail-654846.html

到了这里,关于【仿写tomcat】四、解析http请求信息,响应给前端,HttpServletRequest、HttpServletResponse的简单实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaWeb:vue、AJax、ELement、maven、SpringBoot、、Http、Tomcat、请求响应、分层解耦

    VUE是前端框架,基于MVVM,实现数据双向绑定 框架是半基础软件,可重用的代码模型  Vue-cli 是Vue官方提供的一个脚手架,用于快速生成一个 Vue 的项目模板 1 统一的目录结构 2 本地调试 3 热部署:代码变动,不需要重新运行,就可以加载最新的程序 4 单元测试 5 集成打包

    2024年04月14日
    浏览(51)
  • 网站建设入门教程||HTTP 请求方法||HTTP 响应头信息

    根据 HTTP 标准,HTTP 请求可以使用多种请求方法。 HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。 HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 序号 方法 描述 1 GET 请求指定的页面信息,并返回实体主体。 2 HEAD 类似于 GET 请求,只不过返回的

    2024年02月12日
    浏览(66)
  • 【仿写tomcat】五、响应静态资源(访问html页面)、路由支持以及多线程改进

    如果我们想访问html页面其实就是将本地的html文件以流的方式响应给前端即可,下面我们对HttpResponseServlet这个类做一些改造 writeHtml这个方法将会读取webApp下面的html文件,注意只读取下面一级文件中的html文件,然后将这个文件以二进制流的形式转换成字符串拼接到上面定义的

    2024年02月12日
    浏览(41)
  • HTTP响应状态码大全:从100到511,全面解析HTTP请求的各种情况

    为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。 (博客的参考源码可以在我主页的资源里找到,如果在学习的

    2024年02月12日
    浏览(50)
  • 【仿写tomcat】六、解析xml文件配置端口、线程池核心参数

    上一篇文章中我们用了Excutors创建了线程,这里我们将它改造成包含所有线程池核心参数的形式。 主方法中对多线程操作部分改为使用CompletableFuture执行 现在我们有一个server.xml文件,我想解析其中的端口号以及线程池参数 如果想完成这个功能可以直接使用java本身自带的工具

    2024年02月12日
    浏览(30)
  • Tomcat:org.apache.coyote.http11.Http11Processor.service 解析 HTTP 请求 header 错误

    注意其中:HTTP请求解析错误 将 https 改成 http 即:http://localhost:8080/ (其中8080根据自己配置来更改,tomcat默认是8080) 修改后: 成功!! 具体原因俺也不造,欢迎友友们指教,多谢!! Tomcat与http有协议

    2024年02月11日
    浏览(39)
  • 使用charles(fildder ,Wire shark)对安卓模拟器(手机)进行抓包,获取http请求响应信息

    主要将Charles抓包的配置,和遇到问题进行了一个整理, 本教程,主要解决,按照Charles抓包配置之后,还是无法成功进行抓包。并且网络无法访问通的问题 https://www.52pojie.cn/thread-1600964-1-1.html charles的配置和安卓系统的配置,需要参照这个来。 win版 https://blog.csdn.net/qq_45564088

    2024年02月14日
    浏览(46)
  • 关于降版本Tomcat10降到Tomcat9或者Tomcat8,提示找不到jakarta.servlet.http.HttpServletRequest包的解决方法

    Tomcat10相较于Tomcat9和8,在Servlet方面,对于javax.servlet包名改为了jakarta.servlet。 当你目前的项目是使用Tomcat10进行部署的,然后页面提示没有找到javax.servlet.http.HttpServletRequest包时,只有两种方法: 1、就是在Tomcat10的包下找到lib下的servlet-api.jar包 ,详情请看我上一篇文章:关于

    2024年01月25日
    浏览(39)
  • 运行tomcat时,解析 HTTP 请求 header 错误 Note: further occurrences of HTTP 在方法名称中发现无效的字符串, HTTP 方法名必须是有效的符号

    启动成功后报错 org.apache.coyote.http11.Http11Processor.service 解析 HTTP 请求 header 错误 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level. java.lang.IllegalArgumentException: 在方法名称中发现无效的字符串, HTTP 方法名必须是有效的符号. 解决tomcat -- conf– server.xml 编辑 你看你

    2024年02月12日
    浏览(116)
  • web入门---tomcat&请求响应

    Web 服务器是一个软件程序,对 HTTP协议的操作进行封装,使得不必直接对协议进行操作,让 web 开发更加便捷。主要功能是“提供网上信息浏览服务”。 下载 tomcat 这里有一个示例 直接双击打开 index.html 但是这个“打开”是再本地浏览器打开的,不是通过服务器打开的 接下来

    2024年02月07日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包