Java学习路线-48:Servlet学习

课时1 Servlet是什么

Servlet作用是处理请求
接收请求
处理请求
完成响应

课时2 实现Servlet方式

依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

实现方式

// 实现接口:
javax.servlet.Servlet

// 继承类:
javax.servlet.GenericServlet

// 继承类:
javax.servlet.HttpServlet

继承示例
AServlet.java

import javax.servlet.*;
import java.io.IOException;

public class AServlet implements Servlet{

    // 创建时执行
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    // 获取配置信息
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    // 处理请求
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    // 获取servlet信息
    @Override
    public String getServletInfo() {
        return null;
    }

    // 销毁前调用
    @Override
    public void destroy() {

    }
}

课时3 Servlet的生命周期

生命周期

init    实例化调用
service 每次处理请求都调用
destroy 销毁调用

特性
(1)单例,每个类只有一个对象
(2)线程不安全,效率最高

Servlet类由用户自定义,对象由服务器来创建,并有服务器调用对应的方法

浏览器访问Servlet
给Servlet配置一个路径
web.xml

<?xml version="1.0" encoding="utf-8" ?>

<web-app>
    <!-- 注册 Servlet,帮助web服务器反射该类 -->
    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>AServlet</servlet-class>
    </servlet>
    
    <!-- 映射 Servlet 资源,用url-pattern元素标示 URL -->
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>demo</url-pattern>
    </servlet-mapping>
</web-app>

目录结构

webapp
    └── WEB-INF
        ├── classes
        │   └── AServlet.class
        └── web.xml

课时4 ServletConfig介绍


interface ServletConfig{
    // 获取servlet-name中的内容
    String getServletName() 

    // 获取Servlet上下文对象
    ServletContext getServletContext() 

    // 获取指定初始化参数值
    String getInitParameter(String name) 

    // 获取所有初始化参数值
    Enumeration<String> getInitParameterNames() 

}
<servlet> 
    <init-param>
        <param-name>name</param-name>
        <param-value>Tom</param-value>
    </init-param>
</servlet>

获取参数

@Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println(servletConfig.getInitParameter("name"));
    }

课时5 ServletRequest和Servletresponse对象

interface ServletRequest;

interface ServletResponse;

课时6 GenericServlet介绍

GenericServlet可以只覆写service方法,不用全写

基本原理

import javax.servlet.*;
import java.io.IOException;

public class AServlet implements Servlet {
    private ServletConfig config = null;

    @Override
    public void init(ServletConfig servletConfig) {
        this.config = servletConfig;
        this.init();
    }

    // 实现此方法,初始化后可以调用
    public void init() {

    }

    @Override
    public ServletConfig getServletConfig() {
        return this.config;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

使用示例

import javax.servlet.*;
import java.io.IOException;

public class AServlet extends GenericServlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
        servletResponse.getWriter().write("<h2>hello<h2>");
    }
}

课时7 HttpServlet介绍

源码


package javax.servlet.http;


public abstract class HttpServlet extends GenericServlet {
    // 重写
    protected void doGet(HttpServletRequest req, HttpServletResponse resp);
    
    // 重写
    protected void doPost(HttpServletRequest req, HttpServletResponse resp);

    protected void service(HttpServletRequest req, HttpServletResponse resp);

    public void service(ServletRequest req, ServletResponse res){
        if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)res;
            this.service(request, response);
        } else {
            throw new ServletException("non-HTTP request or response");
        }
    }
}

使用示例: 接收GET请求

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

public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("<h2>hello</h2>");
    }
}

课时8 Servlet的细节

1、非线程安全
一个Servlet类只有一个实例对象,不是线程安全的,工作效率高

(1)不要在Servlet中创建成员,创建局部变量即可
(2)可以创建无状态成员
(3)可以创建有状态的成员,但是状态必须为只读

2、创建时启动
默认情况下,服务器会在第一次访问Servlet时创建实例对象

给load-on-startup设置一个非负整数
正数的值越小,启动该servlet的优先级越高

可以配置创建时启动

<servlet>
    <servlet-name>servletName</servlet-name>
    <load-on-startup>0</load-on-startup>
</servlet>

3、url-pattern
可以有多个访问路径
可以使用前缀或者后缀通配符*

<servlet>
    <servlet-name>servletName</servlet-name>
    <!-- 后缀匹配 -->
    <url-pattern>/demo/*</url-pattern>
    <!-- 前缀匹配 -->
    <url-pattern>*.do</url-pattern>
    <!-- 匹配所有url -->
    <url-pattern>/*</url-pattern>
</servlet>

课时9 在conf下的web.xml文件内容介绍

${CATALINA_HOME}/conf/web.xml

<!-- 优先级最低 -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 过期时间30分钟 -->
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

<!-- 类型映射 -->
<mime-mapping>
    <extension>xml</extension>
    <mime-type>application/xml</mime-type>
</mime-mapping>

课时10 Servlet与反射

Servlet通过反射,获取配置文件的类名,进行实例化和方法调用

课时11 ServletContext概述

一个项目只有一个ServletContext对象
可以在多个Servlet中传递对象

Tomcat启动时创建,关闭时销毁

课时12 获取ServletContext对象

获取ServletContext


class ServeletConfig{
    ServletContext getServletContext();
}

class GenericServlet{
    ServletContext getServletContext();
}

课时13 演示ServletContext

域对象: 在多个Servlet中传递数据

class ServletContext{
    // 设置 多次调用会覆盖
    void setAttribute(String name, Object vlaue);
    // 获取
    Object getAttribute(String name);
    // 移除
    void removeAttribute(String name);
    // 获取全部属性名称
    Enumeration getAttributeNames();
}

例如: AServlet的数据可以传递到BServlet
AServlet.java

package com.pengshiyu;

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

public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        ServletContext context = getServletContext();
        context.setAttribute("name", name);
        response.getWriter().write("<h2>" + name +"</h2>");
    }

}

BServlet.java

package com.pengshiyu;

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

public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletContext context = getServletContext();
        String name = (String)context.getAttribute("name");
        response.getWriter().println(name);
    }
}

课时14 ServletContext获取公共的初始化参数

Servlet只能获取自己的初始化参数
ServletContext获取公共的初始化参数

<web-app>
    <context-param>
        <param-name>key</param-name>
        <param-value>value</param-value>
    </context-param>
</web-app>
package com.pengshiyu;

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

public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletContext context = getServletContext();
        String name = context.getInitParameter("key");
        response.getWriter().println(name);
    }
}

课时15 ServletContext获取资源相关方法

以webapp文根目录

ServletContext context = getServletContext();

// 获取绝对路径
String path = context.getRealPath("/index.html");

// 获取文件后转为输入流
InputStream in = context.getResourceAsStream("/index.html");

// 获取目录下的文件
Set<String> set = context.getResourcePaths("/");
// [/hello.html, /WEB-INF/]

课时16 网站访问量统计小案例

使用ServletContext对象共享统计数据

package com.pengshiyu;

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

public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletContext context = getServletContext();
        Integer count = (Integer) context.getAttribute("count");

        if (count == null) {
            count = 1; // 第一次访问
        } else {
            count++;
        }

        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().println("<h2>第"+count+"次访问</h2>");
        context.setAttribute("count", count);
    }
}

课时17 获取类路径下的资源

依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

代码实例

package com.pengshiyu;

import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

public class Demo {

    public static void main(String[] args) throws IOException {

        Class<Demo> clazz = Demo.class;

        // 1、相对于.class所在目录
        InputStream input1 = clazz.getResourceAsStream("1.txt");
        System.out.println(IOUtils.toString(input1, StandardCharsets.UTF_8));

        // 2、相对于/classes
        InputStream input2 = clazz.getResourceAsStream("/2.txt");
        System.out.println(IOUtils.toString(input2, StandardCharsets.UTF_8));

        ClassLoader loader = clazz.getClassLoader();

        // 3、相对于/classes
        InputStream input3 = loader.getResourceAsStream("3.txt");
        System.out.println(IOUtils.toString(input3, StandardCharsets.UTF_8));

    }
}

课时18 BaseServlet

一个Servlet中可以有多个请求处理方法

BaseServlet.java

package com.pengshiyu;

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.lang.reflect.Method;

public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String methodName = req.getParameter("method");

        if(methodName == null || methodName.trim().isEmpty()){
            throw new RuntimeException("method is null or empty");
        }
        System.out.println(methodName);

        // 通过参数获取方法
        Class clazz = this.getClass();

        Method method = null;
        try {
            method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("方法获取失败");
        }

        // 调用方法
        try {
            method.invoke(this, req, resp);
        } catch (Exception e) {
            throw new RuntimeException("调用失败");
        }

    }
}

AServlet.java

package com.pengshiyu;

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

public class AServlet extends BaseServlet {

    public void getAge(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().print("getAge");
    }

    public void getName(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().print("getName");
    }

}

调用时传入查询参数
http://localhost:8080/demo/hello?method=getAge

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值