Servlet 快速入门详解

Servlet 快速入门

页面-4

简介

Servlet是由Sun公司基于Java开发的动态WEB技术

在Java中有个Servlet接口,该接口有两个实现类 HttpServletGenericServlet 其中GenericServlet是HttpServlet的父类

工作原理

当Web服务器接收到一个HTTP请求时,它会先判断请求内容——如果是静态网页数据,Web服务器将会自行处理,然后产生响应信息;如果牵涉到动态数据,Web服务器会将请求转交给Servlet容器。此时Servlet容器会找到对应的处理该请求的Servlet实例来处理,结果会送回Web服务器,再由Web服务器传回用户端。

针对同一个Servlet,Servlet容器会在第一次收到http请求时建立一个Servlet实例,然后启动一个线程。第二次收到http请求时,Servlet容器无须建立相同的Servlet实例,而是启动第二个线程来服务客户端请求。所以多线程方式不但可以提高Web应用程序的执行效率,也可以降低Web服务器的系统负担。

img

Servlet程序

Servlet 程序是普通的类继承HttpServlet 接口重写doGet / doPost方法,提供动态的WEB内容

public class HelloServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter printWriter =resp.getWriter();
        printWriter.write("Hello Servlet");
    }
}

HttpServletRequest

常用方法

1、getRequestURI() 获取请求的资源路径

2、getRequestURL() 获取请求的统一资源定位符(绝对路径)

3、获取客户端的ip地址 getRemoteHost()

4、getHeader() 获取请求头

5、getParameter() 获取请求的参数

6、getParameterValues() 获取请求的参数(多个值的时候使用)

7、getMethod() 获取请求的方式(GET或POST)

8、setAttribute(key,value) 设置域数据

9、getAttribute(key) 获取域数据

10、getRequestDispatcher() 获取请求转发对象

11、getSession() 获取一个Session

相关应用

重定向

req.getRequestDispatcher("/success.jsp").forward(req,resp);

HttpServletResponse

常用方法

向浏览器发送数据的常用方法

ServletOutputStream getOutputStream() throws IOException;		//普通输出流

PrintWriter getWriter() throws IOException;			//处理中

向浏览器发送响应头的方法

方法名方法描述
addDateHeader(String name ,long date)设置一个long类型的响应头
addHeader(String name,String value)该方法是设置有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值
addIntHeader(String name,int value)该方法是设置有多个值且值的类型为int类型的响应头
setHeader(String name,String value)该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值
setDateHeader(String name,long value)该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
setIntHeader(String name,int value)该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数

响应码和响应常量

setStatus(int value)设置临时定向响应码
SC_NOT_FOUND状态码404对应的常量
SC_OK状态码200对应的常量
SC_INIERNAL_SERVER_ERROR状态码500对应的常量

相关应用

  1. 向浏览器输出消息(getWriter,getOutputStream)

  2. 下载文件

    public class FileServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            System.out.println("=====================123131===========================");
            //获取下载文件的路径
            //String realPath = this.getServletContext().getRealPath("/1.png");//获取绝对路径
            String realPath = "/Users/b/Desktop/javacode/JavaWeb_Maven/javaweb-02-servlet/response/src/main/resources/1.png";
            System.out.println("下载文件的路径: " + realPath);
    
            //下载的文件名
            String fileName = realPath.substring(realPath.lastIndexOf("/") + 1);
            System.out.println(fileName);
    
            //让浏览器支持我们能下载的东西
            resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
    
            //获取下载文件的输入流
            FileInputStream fis = new FileInputStream(realPath);
    
            //创建缓冲区
            int len = 0;
            byte[] buffer = new byte[1024];
    
            //获取OutputStream对象
            ServletOutputStream servletOutputStream = resp.getOutputStream();
    
            //将FileOutputStream流写入到buffer缓冲区
            while ((len = fis.read(buffer)) != -1){
    
                // 使用OutputStream将buffer缓冲区的数据输出到客户端
                servletOutputStream.write(buffer, 0, len);
            }
    
            //释放资源
            servletOutputStream.close();
            fis.close();
    
        }
    
    1. 定时刷新

      response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次
      
    2. 重定向

      resp.sendRedirect(req.getContextPath() + "/index.jsp");
      

转发和重定向的区别

重定向与转发都会使用户访问其他资源,只是发生位置不同,请求转发放生在服务端,只能访问该项目内部资源。重定向是第一次收到用户请求后让客户端重新访问一个新的url地址,客户一共请求了两次。

ServletContext

Web容器在启动的时候会为每个Web程序创建一个ServletContext对象,代表当前的Web应用对象。这个ServletContext可以保存一些数据,也可以供Servlet从中读取数据。类似于Servlet之间的中介,实现Servlet直接的数据共享。

img

ServletContext又称Servlet上下文

可根据HttpServlet的实例化对象调用getServletContext获取

ServletContext servletContext = this.getServletContext();

共享数据

在一个servlet中创建的数据可以在另一个servlet中拿到

写入数据

 //获得ServletContext对象
 ServletContext servletContext = this.getServletContext()
 servletContext.setAttribute("username",username);   //将数据写入ServletContext中

读取数据

ServletContext servletContext = this.getServletContext();
String username = (String) servletContext.getAttribute("username");

请求转发

获取ServletContext上下文对象,调用requestDispatcherforward方法转发请求

//请求转发目标路径
ServletContext servletContext = this.getServletContext();
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp");   
requestDispatcher.forward(req,resp);    //调用forward方法转发请求

获取初始化参数

跟获取WEB.XML中的配置信息

<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");

读取资源文件

读取.properties 类型的配置文件

//返回InputStream流
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/zh1z3ven/servlet/test.properties");		

Properties properties = new Properties();//实例化Properties对象

properties.load(is);//loadInputStream流		

String username = properties.getProperty("username");
String password = properties.getProperty("password");

Servlet程序的映射

建立访问地址与类之间的映射关系

Servlet-MappingServlet相互配合,servlet 负责指代具体类,servlet-mapping 负责指定类的连接后

缀。映射信息存放在web.xml文件中

<!--注册servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
		<!--绑定servlet实现类-->
        <servlet-class>com.zh1z3ven.servlet.HelloServlet</servlet-class>
    </servlet>
<!--注册servlet路由-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
		<!--设置访问路由-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

指定通用映射路径

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

指定后缀或前缀

<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.do</url-pattern>
</servlet-mapping>

指定默认请求路径

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

代码实践:HelloServlet

servlet3.0版本后可以不用写web.xml文件,可以直接使用注解定义加载

@WebServlet(urlPatterns = "/demo")
public class Demo{...}

创建父项目

新建空白Maven项目,并删除项目中的src目录,这个空工程就是Maven父工程

添加Pom依赖

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
</dependency>

创建子项目

新建Module带有webapp模板Maven的子项目

(1)确定项目的子父关系

父项目Pom中会出现

<modules>
        <module>子项目名称</module>
</modules>

子项目Pom中会出现

<parent>
    <artifactId>...</artifactId>
    <groupId>...</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

完成配置后父项目中的Jar包子项目可以直接使用

如果子包不能直接使用:右键父项目名——Maven——Reload Project

有一种例外,如果<depndency>标签规定了使用范围为provided则子项目不能共用该依赖

image-20211224160741996

在Maven中依赖的域有:compile、provided、runtime、system、test、import,这里只单独介绍两个

compile(默认)

当依赖的scope为compile的时候,那么当前这个依赖的包,会在编译的时候被加入进来,并且在打包(mvn

package)的时候也会被加入进来。编译范围有效,在编译与打包时都会加入进去。

provided

当依赖的scope为provided的时候,在编译和测试的时候有效,在执行(mvn package)进行打包时不会加

入。比如, 我们开发一个web应用,在编译时我们需要依赖servlet-api.jar,但是在运行时我们不需要该 jar

包,因为这个jar 包已由web服务器提供,如果在打包时又被加入进去,那么就可能产生冲突。此时我们就可

以使用 provided 进行范围修饰。

(2)修改子项目Web.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

</web-app>

(3)创建Javaresources文件目录

在子项目的src->main目录下创建Javaresources文件夹并修改目录属性

image-20211224160510712

(4)创建Package编写Servlet程序

创建一个类继承HttpServlet 接口重写doGet / doPost方法

(5)注册Servlet,编写Servlet映射

<!--注册servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
		<!--绑定servlet实现类-->
        <servlet-class>com.zh1z3ven.servlet.HelloServlet</servlet-class>
    </servlet>
<!--注册servlet路由-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
		<!--设置访问路由-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

(6)配置Tomcat

在菜单栏找到 run=>Edit Configurations => 点击+号找Tomcat添加即可

具体细节在Maven笔记,这里就不作赘述

配置完成打开指定映射,出现内容即代表成功

URL地址的推荐写法

在JavaWeb开发中,只要是写URL地址,那么建议最好以/开头,也就是使用相对路径的方式,那么这个/到底代表什么呢?可以用如下的方式来记忆/如果"/“是给服务器用的,则代表当前的web工程,如果”/"是给浏览器用的,则代表webapps目录。

Java

response.sendRedirect(request.getContextPath()+"/index.jsp");

JSP页面

<a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>

参考

理解Servlet工作原理 - 简书 (jianshu.com)

JavaWeb–ServletContext - 简书 (jianshu.com)

Java之Servlet - CoLoo - 博客园 (cnblogs.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ABright.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值