Servlet # servlet的入门概述

Posted LRcoding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet # servlet的入门概述相关的知识,希望对你有一定的参考价值。

1. Servlet

1.1 什么是Servlet?

是⼀个遵循Servlet开发的java类。Servlet是由服务器调⽤的,运⾏在服务器端。

1.2 HTTP协议

超⽂本传输协议(HTTP,HyperText Transfer Protocol)是互联⽹上应⽤最为⼴泛的⼀种⽹络协议。所有的WWW⽂件都必须遵守这个标准。它是TCP/IP协议的⼀个应⽤层协议

HTTP协议就是客户端和服务器交互的⼀种通迅的格式。

HTTP1.0和HTTP1.1的区别

  • HTTP1.0协议,客户端与web服务器建⽴连接后,只能获得⼀个web资源【短连接,获取资源后就断开】
  • HTTP1.1协议,允许客户端与web服务器建⽴连接后,在⼀个连接上获取多个web资源【保持连接】

1.3 HTTP请求

浏览器向服务器请求某个web资源时,称之为浏览器服务器发送了⼀个http请求。

http请求应该包含三个部分:

  1. 请求⾏【描述客户端的请求⽅式、请求的资源名称,以及使⽤的HTTP协议版本号】
  2. 多个消息头【描述客户端请求哪台主机,以及客户端的⼀些环境信息等】
  3. ⼀个空⾏

请求行

  • GET:⽤来查询数据,提交速度快,在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。

  • POST:⽤来提交数据,可以在请求的实体内容中向服务器发送数据,传送的数据量⽆限制。

请求头

Accept: text/html,image/* Accept-Encoding: gzip,compress Accept-Charset: ISO-8859-1

1.4 HTTP响应

⼀个HTTP响应代表着服务器浏览器回送数据

HTTP响应应该包含四个部分:

  1. ⼀个状态⾏【描述服务器对请求的处理结果。】
  2. 多个消息头【描述服务器的基本信息以及数据,通过描述信息,可以通知客户端如何处理服务器回送的数据】
  3. ⼀个空⾏
  4. 实体内容【服务器向客户端回送的数据】

状态⾏

HTTP版本号状态码原因叙述
HTTP/1.1200OK
404客户端的请求有错误
500服务器有错误

响应头

Server:apache tomcat Content-Encoding: gzip Content-Type: text/html; charset=GB2312

2. servlet生命周期

  1. 加载Servlet。当Tomcat第⼀次访问Servlet的时候,Tomcat会负责创建Servlet的实例
  2. 初始化。当Servlet被实例化后,Tomcat会调⽤init()⽅法初始化这个对象
  3. 处理服务。当浏览器访问Servlet的时候,Servlet 会调⽤service()⽅法处理请求
  4. 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会⾃动调⽤**destroy()**⽅法,让该
    实例释放掉所占的资源。⼀个Servlet如果⻓时间不被使⽤的话,也会被Tomcat⾃动销毁
  5. 卸载。当Servlet调⽤完destroy()⽅法后,等待垃圾回收。如果有需要再次使⽤这个Servlet,会重
    新调⽤init()⽅法进⾏初始化操作。
  • 只要访问Servlet,service()就会被调⽤。

  • init()只有第⼀次访问Servlet的时候才会被调⽤。

  • destroy()只有在Tomcat关闭的时候才会被调⽤。

3. servlet编写

  • 继承HttpServlet,重写service方法
public class MyServlet extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        String name = req.getParameter("name");
        // TODO
    }
}
  • 配置web.xml文件
    TIM截图20200430182222

4. 细节问题

4.1 servlet细节

4.1.1 ⼀个已经注册的Servlet可以被多次映射

<servlet>
    <servlet-name>Demo1</servlet-name>
    <servlet-class>lwclick.web.Demo1</servlet-class>
</servlet>

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

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

4.1.2 Servlet映射的URL可以使⽤通配符

通配符有两种格式:

  1. *. 扩展名
  2. 正斜杠(/)开头并以“/*”结尾。
<servlet-mapping>
    <servlet-name>Demo1</servlet-name>
    <url-pattern>/*</url-pattern>
    
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

4.1.3 Servlet是单例的

  • Servlet对象⼀旦创建了,就会驻留在内存中,为后续的请求做服务,直到服务器关闭。

  • 每次访问请求,都创建新的请求对象(HttpServletRequest)和响应对象(HttpServletResponse)

  • 多个⽤户访问Servlet的时候,服务器会为每个⽤户创建⼀个线程。当多个⽤户并发访问Servlet共享资源的时候就会出现线程安全问题。

    • 如果⼀个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制synchronized (对象){}
    • 如果⼀个变量不需要共享,则直接在service()中定义.这样不会存在线程安全问题

4.1.4 load-on-startup

如果在<servlet>元素中配置了⼀个<load-on-startup> 元素,那么WEB应⽤程序在启动时,就会装载并创建Servlet的实例对象、以及调⽤Servlet实例对象的init()⽅法。

TIM截图20200430183607

作用:

  1. 为web应⽤写⼀个InitServlet,这个servlet配置为启动时装载,为整个web应⽤创建必要的数据库表和数据
  2. 完成⼀些定时的任务【定时写⽇志,定时备份数据】

4.1.5 在web访问任何资源都是在访问servlet

⽆论在web中访问什么资源【包括JSP】,都是在访问Servlet。

没有⼿⼯配置缺省Servlet的时候,你访问静态图⽚,静态⽹⻚,缺省Servlet会在你web站点中寻找该图⽚或⽹⻚,如果有就返回给浏览器,没有就报404错误

4.2 ServletConfig对象

ServletConfig对象有什么⽤?

通过此对象可以读取web.xml中配置的初始化参数。能够让程序更加灵活【更换需求,更改配置⽂件web.xml即可,程序代码不⽤改】

<servlet>
    <servlet-name>Demo1</servlet-name>
    <servlet-class>zhongfucheng.web.Demo1</servlet-class>
    
    <init-param>
        <param-name>name</param-name>
        <param-value>zhongfucheng</param-value>
    </init-param>
</servlet>

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

TIM截图20200430203421

4.3 ServletContext对象

4.3.1 什么是ServletContext对象?

当Tomcat启动的时候,就会创建⼀个ServletContext对象。它代表着当前web站点

4.3.2 ServletContext有什么⽤?

  1. ServletContext既然代表着当前web站点,那么所有Servlet都共享着⼀个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯
  2. ServletConfig获取的是配置的是单个Servlet的参数信息ServletContext可以获取的是配置整个web站点的参数信息
  3. 利⽤ServletContext读取web站点的资源⽂件
  4. 实现Servlet的转发【不常用】

4.3.3 Servlet之间实现通讯

ServletContext对象可以被称之为域对象,可以简单理解成⼀个容器【类似于Map集合】

通过serAttribute实现通讯

//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();

String value = "lwclick";

//MyName作为关键字,value作为值存进 域对象【类型于Map集合】
servletContext.setAttribute("MyName", value);
//获取ServletContext对象
ServletContext servletContext = this.getServletContext();

//通过关键字获取存储在域对象的值
String value = (String) servletContext.getAttribute("MyName");

System.out.println(value);

4.3.4 获取web站点配置的信息

  • web.xml⽂件⽀持对整个站点进⾏配置参数信息【所有Servlet都可以取到该参数信息】
<context-param>
    <param-name>name</param-name>
    <param-value>lwclick</param-value>
</context-param>
//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();

//通过名称获取值
String value = servletContext.getInitParameter("name");
System.out.println(value);

4.3.5 读取资源文件

⽂件放在web⽬录下,直接通过⽂件名称就能获取(web --> WEB-INF --> 资源文件)

//获取到ServletContext对象
ServletContext servletContext = this.getServletContext();

//调⽤ServletContext⽅法获取到读取⽂件的流
InputStream inputStream = servletContext.getResourceAsStream("2.png");

5. Response对象

5.1. response、request对象

  • Tomcat收到客户端的http请求,针对每⼀次请求,分别创建⼀个代表请求的request对象代表响应的response对象

  • 获取浏览器提交过来的数据,找request对象

  • 向浏览器输出数据,找response对象

HttpServletResponse对象封装了http响应的信息。

5.2. HttpServletResponse的应⽤

5.2.1 调⽤getOutputStream()⽅法向浏览器输出数据

二进制数据

response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.getOutputStream().write("你好呀我是中国".getBytes("UTF-8"));

5.2.2 调⽤getWriter()⽅法向浏览器输出数据

字符数据,不能输出⼆进制数据

response.setContentType("text/html;charset=UTF-8");

//获取到printWriter对象
PrintWriter printWriter = response.getWriter();
printWriter.write("看完博客点赞!");

5.2.3 实现⽂件下载

在web站点下有⼀个图⽚等文件

//获取到资源的路径
String path = this.getServletContext().getRealPath("/download/1.png");

//读取资源
FileInputStream fis = new FileInputStream(path);

//获取到⽂件名,路径在电脑上保存是\\\\形式的。
String fileName = path.substring(path.lastIndexOf("\\\\") + 1);

//设置消息头,告诉浏览器,我要下载1.png这个图⽚
response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(fileName, "UTF-8")););

//把读取到的资源写给浏览器
int len = 0;
byte[] bytes = new byte[1024];
ServletOutputStream sos = response.getOutputStream();
while ((len = fis.read(bytes)) > 0) {
	sos.write(bytes, 0, len);
}

//关闭资源
servletOutputStream.close();
fileInputStream.close();

5.2.4 实现自动刷新

response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("3秒后跳转⻚⾯.....");

//三秒后跳转到index.jsp⻚⾯去,web应⽤的映射路径我设置成/,url没有写上应⽤名
response.setHeader("Refresh", "3;url='/index.jsp'");

5.2.5 设置缓存

【浏览器默认有缓存,对于需要实时更新的数据,取消缓存】
//浏览器有三消息头设置缓存,为了兼容性!将三个消息头都设置了
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");

5.2.6 实现数据压缩

GZIP类来对数据压缩,把压缩后的数据取出来,写给浏览器

5.2.7 生成随机图⽚

//在内存中⽣成⼀张图⽚,宽为80,⾼为20,类型是RGB
BufferedImage bImg = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);

//获取到这张图⽚
Graphics g = bImg.getGraphics();

//往图⽚设置颜⾊和字体
g.setColor(Color.white);
g.fillRect(0, 0, 80, 20);
g.setFont(new Font(null, Font.BOLD, 20));

//往图⽚上写数据,先写个12345,横坐标是0,纵坐标是20【⾼度】
graphics.drawString("12345", 0, 20);

//要往浏览器写⼀张图⽚,那要告诉浏览器回送的类型是⼀张图⽚
response.setHeader("ContentType", "jpeg");

//java提供了图⽚流给我们使⽤,这是⼀个⼯具类
//把图⽚传进去,类型是jpg,写给浏览器
ImageIO.write(bImg, "jpg", response.getOutputStream());
private String makeNum() {
    Random random = new Random();
    
    //这样就会⽣成0-7位的随机数,如果不够7位,我们加到7位就⾏了
    int anInt = random.nextInt(9999999);
    
    //将数字转成是字符串
    String num = String.valueOf(anInt);
    
    //判断位数有多少个,不够就加
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < 7 - num.length(); i++) {
    	stringBuffer.append("0");
    }
    
    return stringBuffer.append(num).toString();
}

5.2.8 重定向跳转

点击⼀个超链接,通知浏览器跳转到另外的⼀个⻚⾯就叫重定向跳转。

//重定向到index.jsp⻚⾯
response.sendRedirect("/lwclick/index.jsp");

重定向是通过302状态码和跳转地址实现的


6. Request对象

6.1. 什么是HttpServletRequest

客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发⼈员通过这个对象的⽅法,可以获得客户这些信息。

6.2. 常用方法

  • getRequestURL 返回客户端发出请求时的完整URL
  • getQueryString 返回请求⾏中的参数部分
  • getRemoteAddr 返回发出请求的客户机的IP地址
  • getLocalAddr 返回WEB服务器的IP地址
  • getHeader 获得客户机请求头
  • getParameter 获得客户机请求参数(客户端提交的数据)

6.3. 应用

6.3.1 防盗链

不能使用复制粘贴网址,拿走网站上的资源

//获取到⽹⻚是从哪⾥来的
String referer = request.getHeader("Referer");

//如果不是从我的⾸⻚来或者从地址栏直接访问的,
if ( referer == null || !referer.contains("localhost:8080/lwclick/index.jsp") ) {
    //回到⾸⻚去
    response.sendRedirect("/lwclick/index.jsp");
    return;
}

//能执⾏下⾯的语句,说明是从我的⾸⻚点击进来的,那没问题,照常显示
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("路⻜做了xx");

6.3.2 表单提交数据【通过post⽅式提交数据】

点击提交按钮的时候,数据封装进了FormData中

http请求中把实体主体带过去了【传输的数据称之为实体主体】

既然request对象封装了http请求,所以request对象可以解析到发送过来的数据

于是只要把编码设置成UTF-8就可以解决乱码问题了。

<form action="/lwclick/formServlet" method="post">
    <table>
        <tr><td>⽤户名</td>
            <td><input type="text" name="username"></td></tr>
        
        <tr><td>密码</td>
            <td><input type="password" name="password"></td></tr>
        
        <tr><td>性别</td>
            <td>
                <input type="radio" name="gender" value=""><input type="radio" name="gender" value=""></td></tr>
        
        <tr><td>爱好</td>
            <td>
                <input type="checkbox" name="hobbies" value="游泳">游泳
                <input type="checkbox" name="hobbies" value="跑步">跑步
                <input type="checkbox" name="hobbies" value="⻜翔">⻜翔
            </td></tr>
        
        <input type="hidden" name="aaa" value="my name is lwclick">
        
        <tr><td>你的来⾃于哪⾥</td>
            <td>
                <select name="address">
                    <option value="⼴州">⼴州</option>
                    <option value="深圳">深圳</option>
                    <option value="北京">北京</option>
                </select>
            </td></tr>
        
        <tr><td>详细说明:</td>
            <td>
            	<textarea cols="30" rows="2" name="textarea"></textarea>
            </td></tr>
        
        <tr>
            <td><input type="submit" value="提交"></td>
            <td><input type="reset" value="重置"></td>
        </tr>
    </table>
</form>

在formServlet获取值

//设置request字符编码的格式
request.setCharacterEncoding("UTF-8");

//通过html的name属性,获取到值
String username = request.getParameter("username");
String password = request.getParameter("password");
String gender = request.getParameter("gender");

//复选框和下拉框有多个值,获取到多个值
String[] hobbies = request.getParameterValues("hobbies");
String[] address = request.getParameterValues("address");

//获取到⽂本域的值
String description = request.getParameter("textarea");

//得到隐藏域的值
String hiddenValue = request.getParameter("aaa");

....各种System.out.println().......

6.3.3 超链接⽅式提交数据(get方式) – 不推荐

get⽅式不同,它的数据是从消息⾏带过去的,没有封装到request对象⾥⾯

<a href="/lwclick/formServlet?username=xxx">使⽤超链接将数据带给浏览器</a

以上是关于Servlet # servlet的入门概述的主要内容,如果未能解决你的问题,请参考以下文章

Servlet 入门介绍(学Servlet必看)

[JavaWeb-Servlet]概述与快速入门

JSP # JSP入门及简单概述

Servlet入门

Servlet快速入门

Servlet的概述