Servlet 详解

怀旧网个人博客网站地址:

1、 什么是Servlet

  • Servlet就是sun公司开发动态web的一门技术
  • Sun公司在这些API提供一个接口叫做:Servlet,如果要开发一个Servlet程序,只需要完成两个小步骤
    • 编写一个类,实现Servlet接口
    • 把开发好的java类部署到web服务器中。

把实现Servlet接口的Java程序叫做Servlet

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

2、怎么运行第一个Servlet程序

直接访问上次博客内容:网页链接

3、Servlet 原理

Servlet是由Web服务器调用,web服务器在收到浏览器请求后:

4、Mapping 问题

  1. 一个servlet可指定一个映射路径

    hello /hello
  2. 一个servlet指定多个映射路径

    hello /hello hello /hello1 hello /hello2

都可以访问到

  1. 一个servlet可以指定通用映射路径

    hello /hello/*
  1. 默认请求路径

注意:当设置为这样

复制代码
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

到底访问目录下的index.jsp还是配置的映射路径呢?

由结果得知,映射路径会覆盖掉首页的默认访问路径(强烈建议不要这样写)

  1. 指定后缀或者前缀

注意:*.前面不能加映射的路径

复制代码
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.huaijiu</url-pattern>
</servlet-mapping>

默认访问的是index.jsp界面

只要带.huaijiu后缀就可以访问当映射的请求

在前面继续加路径同样可以

  1. 优先级问题

​ 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

案例:自定义404端口

编写404界面Servlet

复制代码
public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");

        PrintWriter writer = resp.getWriter();

        writer.println("<h1>404 当前界面找不到</h1>");
    }

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

使用通配符,匹配所以请求,

复制代码
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.ErrorServlet</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>error</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>

当访问存在的路径的时候,就会默认去找到存在的映射地址,当没有在配置文件找到的时候,就会默认访问到/*的配置中,就会默认进入404界面

首页也找不到,原因是上面说过了,/* 会覆盖掉默认的首页

配置过的就可以访问,不会访问到404去

后面的不论怎么访问,都是找不到。

5、ServletConte

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

1、共享数据

我在这个servlet中保存的数据,可以在另一个servlet中拿到;

复制代码
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.HelloServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/huaijiu</url-pattern>
</servlet-mapping>


<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.ErrorServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

这边有两个映射

复制代码
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        PrintWriter writer = resp.getWriter();
        writer.println("aadsad");

        ServletContext context = this.getServletContext();
        context.setAttribute("userName", "怀旧");
    }
}

在 huaijiu 路径 设置全局属性userName

复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html;charset=utf-8");

    PrintWriter writer = resp.getWriter();

    ServletContext context = this.getServletContext();
    String userName = (String) context.getAttribute("userName");

    writer.println("userName = " + userName + " 你好!");
    writer.println("<h1>404 当前界面找不到</h1>");
}

在随便一个404页面进行访问读取全局属性

直接访问,数据还没放进去,值为null

访问一次huaijiu这个路径

然后再次访问404界面

值成功呗404这个servlet拿到了。

当换一个浏览器,依然可以访问到数据

  • 当前的Context是全局的,能够呗所有人,和所有用户进行访问

2、获取初始化参数

首先配置好初始化参数数据

复制代码
<context-param>
    <param-name>userData</param-name>
    <param-value>怀旧是真滴帅啊!!!</param-value>
</context-param>

直接在servlet中去拿 直接调用 getInitParameter 方法

复制代码
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");

        ServletContext context = this.getServletContext();
        String userData = context.getInitParameter("userData");

        resp.getWriter().println(userData);
    }
}

直接访问 /huaijiu 路径

第一次访问就直接拿到了

3、请求转发

重新创建一个servlet

复制代码
public class RequestDispatcherTestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        System.out.println("RequestDispatcherTestServlet来过");

        ServletContext context = this.getServletContext();
        // 转发到 /huaijiu 这个请求
        context.getRequestDispatcher("/huaijiu").forward(req, resp);
    }
}

编写访问测试的映射

复制代码
<servlet>
    <servlet-name>/testRequestDispatcher</servlet-name>
    <servlet-class>com.huaijiuwang.servlet.RequestDispatcherTestServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>/testRequestDispatcher</servlet-name>
    <url-pattern>/testRequestDispatcher</url-pattern>
</servlet-mapping>

访问测试:

访问 /testRequestDispatcher 路径

访问路径是 testRequestDispatcher 但是界面内容是 / huaijiu 这个路径的

控制台输出了。说明确实访问过 /testRequestDispatcher 路径

执行流程:

4、读取资源文件

Properties

  • 在java目录下创建properties
  • 在resources目录下新建properties

创建一个资源文件

在rescources目录下创建一个user.properties文件内容如下:

复制代码
userName=huaijiu
passWord=123456

启动项目发现user.properties已经在目录中了,并且是在classes目录下俗称:classpath目录

我们重新创建一个user1.properties文件在java的包目录下

重新加载

发现user1.properties并没有被加载

原因是maven项目在打包资源文件的时候需要进行配置

复制代码
<build>
    <resources>
        <resource>
            <!-- 配置java目录下需要被加载的文件类型 -->
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <!-- 配置resources目录下需要被加载的文件类型 -->
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

配置完成,重新启动项目

成功加载user1.properties文件

测试在servlet中读取配置文件数据,

复制代码
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");

        // 获取文件对象了流
        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/user.properties");

        // 创建properties读取对象
        Properties properties = new Properties();
        // 加载文件流到对象中
        properties.load(is);

        // 获取数据
        String userName = properties.getProperty("userName");
        String passWord = properties.getProperty("passWord");

        // 输出数据
        resp.getWriter().println(userName + " : " + passWord);
    }
}	

读取数据完成。

相关推荐
霸道流氓气质2 分钟前
Spring AI 技术细节:RAG QuestionAnswerAdvisor 设计与实现
java·人工智能·spring
平头哥AI25 分钟前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
斑马13931 分钟前
Linux软件编程学习笔记(十二)——TCP并发服务器模型
java·服务器·网络
冬栈程序设计35 分钟前
Springboot宿舍管理系统【670099】 -附源码(开箱即用)
java·毕业设计·springboot·课程设计·程序设计·大作业
2601_9622845044 分钟前
北京Java全栈开发培训 Web前端开发 软件测试就业培训班
java·软件测试·web前端·全栈开发·就业培训
葡萄城技术团队1 小时前
工业数据可视化:使用活字格 AIcoding + Three.js 构建轻量化三维设备监控大屏
开发语言·javascript·信息可视化
qiaosaifei1 小时前
JAVA老项目中有大量的类名_编译时报找不到符号错误
java·开发语言
聪明蛋子哟1 小时前
MCP协议深度落地:如何用Python/Java双语言实现统一的工具调用网关?
java·开发语言·python
文子越来越强1 小时前
【双因子认证】拦截注解@MFACheck 接入指南(其他微服务如何用)
java
一晌小贪欢2 小时前
python-第27天:Python面向对象详解
开发语言·python·数据可视化·面向对象·python办公