【web基础】servlet初识

1.简单servlet程序示例

1)创建一个servlet,重写service()方法,会自动调用doGet()方法或者doPost()方法

package com.huawei.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class HelloServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        String name = req.getParameter("name");
        PrintWriter out = res.getWriter();
        out.println("<span style='color:red;font-size:30px;'>你好 "+name+"</span>");
    }
}

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_3_1.xsd"
         version="3.1">
    <!--配置Servlet,tomcat服务器会读取其中的内容-->
    <servlet>
        <!--Servlet内部名称,可以自定义,但是最好不要乱写,尽量保证有意义-->
        <servlet-name>helloServlet</servlet-name>
        <!--Servlet类全名,包名+简单类名-->
        <servlet-class>com.huawei.servlet.HelloServlet</servlet-class>
    </servlet>

    <!--Servlet映射配置-->
    <servlet-mapping>
        <!--Servlet内部名称,可以自定义,但是最好不要乱写,尽量保证有意义,一定要和上面的servlet-name保持一致-->
        <servlet-name>helloServlet</servlet-name>
        <!--Servlet映射路径,也称为访问Servlet的名称-->
        <url-pattern>/test</url-pattern>
    </servlet-mapping> 
</web-app>

3)注解方式实现上面的内容——免于web.xml中servlet配置

package com.huawei.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "helloServlet", urlPatterns = "/test2")
public class HelloServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        String name = req.getParameter("name");
        PrintWriter out = res.getWriter();
        out.println("<span style='color:red;font-size:30px;'>你好 "+name+"</span>");
    }
}

4)IntelliJ IDEA 2017部署普通web项目(非maven)

1
2
3)启动Tomcat
3

5)@WebServlet注解

//具体可以按住Ctrl单击注解查看所有参数
@WebServlet(name = "helloServlet", //对应servletname
        urlPatterns = "/test2", //对应url-pattern
        loadOnStartup = 1) //对应load-on-startup
public class HelloServlet extends HttpServlet {
    //省略一千字
}

如果希望应用程序启动时,就先将Servlet类载入、实例化并做好初始化动作,则可以使用loadOnStartup设置。设置大于0的值(默认值为-1),表示启动应用程序后就要初始化Servlet(而不是实例化几个Servlet)。数字代表了Servlet的初始顺序,容器必须保证有较小数字的Servlet先初始化,在使用标注的情况下,如果有多个Servlet在设置loadOnStartup时使用了相同的数字,则容器实现厂商可以自行决定要如何载入哪个Servlet。

2.servlet执行流程

  • 按上述方法启动服务器
  • 在浏览器输入http://localhost:8080/start/test?name=亚索
  • 根据ip:端口号与服务器建立连接
  • 根据应用名(idea可以自己随便写,如start,eclipse则只能是工程名)去服务器上查找对应的应用(HelloJavaEE),每一个应用都有一个web.xml文件
  • 根据/test去web.xml文件中查找对应的url-pattern, 找到之后,根据servlet-name查找到对应的HelloServlet
  • 调用HelloServlet的service方法处理数据

3.servlet映射路径

Servlet的映射路径由<servlet-mapping>中的<url-pattern>(注意<url-pattern>要么要以/开头,要么要以*开头)决定,那么<url-pattern>究竟怎么写,怎么去匹配呢?有两种匹配方案:

  • 精确匹配
    <url-pattern>/test/login</url-pattern>
    精确匹配的要点是:<url-pattern>以/开始,并且必须将<url-pattern>中的内容精确的写上。在精确匹配时要注意坚决不能漏掉/,否则会报错,一定要带有/
  • 模糊匹配,下面三种方式,但是在一个url-pattern中不能组合下面的模糊匹配方式
    • <url-pattern>/*</url-pattern>
    • <url-pattern>/test/*</url-pattern>
    • <url-pattern>*.do</url-pattern>
      注意模糊匹配不能组合起来用,只能单个使用
  • 如果在浏览器中输入的url有多个Servlet同时被匹配,也就是说模糊匹配和精确匹配都能找到对应的Servlet资源,精确匹配的优先级高(长得最像的优先被匹配),但是要尽量避免这种情况的发生。当以后缀名结尾的模糊匹配,优先级最低。

4.servlet运行原理

1)建立连接
    浏览器根据ip地址及端口号与服务器建立连接
2)打包
    浏览器根据http协议将数据打包
    数据包中包含请求资源路径(/start/test)
3)发送请求
    浏览器向服务器发送请求
4)拆包
    服务器根据http协议拆包,获取浏览器发送过来的请求数据
5)创建Request
    可以通过请求对象获取请求数据
6)创建Response
    可以通过响应对象获取输出流,向页面输出数据
7)创建HelloServlet
    服务器通过反射实例化HelloServlet
8)调用service方法
    在service方法中处理数据
9)服务器端的通讯模块将数据打包
10)服务器向浏览器发送响应
11)浏览器拆包,获取服务器响应回来的数据
12)浏览器生成新的页面,响应给用户

5.servlet映射练习

  • Servlet1 映射到/abc/*
  • Servlet2 映射到/*
  • Servlet3 映射到/abc
  • Servlet4 映射到*.do

Question
    ①/abc/a.html:Servlet1
    ②/abc:Servlet3
    ③/abc/a.do:Servlet1
    ④/a.do:Servlet2
    ⑤/xxx/yyy/a.do:Servlet4



解析URL的顺序:当输入一个URL时,首先会到web.xml文件中查找是否与偶匹配的url-pattern,如果能匹配到url-pattern,则处理,如果不能匹配到,则交给tomcat的default-servlet处理,也就是会去加载静态资源文件。

结论:先找动态资源,后找静态资源。

6.get请求与post请求

  • get请求:
    ☆在浏览器地址栏直接传参
    ☆超链接
    ☆表单默认提交方式
  • post请求:
    ☆将表单的默认提交方式改成post, <form method = “post”></form>

7.HTTP协议简述

  1. 什么是http协议
    hypertext transport protocal 超文本传输协议
    是一种应用协议,包含了浏览器与服务器的通讯过程及数据格式。
  2. 通讯过程
    step1.建立连接,浏览器根据ip及端口号与服务器建立连接
    step2.打包,发送请求,浏览器将数据打包向服务器发送请求
    step3.打包,发送响应,服务器将数据打包向浏览器发送响应
    step4.服务器关闭连接
    特点:一次请求,一次连接
    优点:效率高,可以用有限的资源为更多的用户服务
  3. 数据格式
    ●请求数据包
         请求行
              请求方式(get/post)
              请求资源路径(/应用名/….)
              协议类型及版本
         若干消息头
              是一些键值对,由w3c制定,具有特定的含义。
              规定了浏览器与服务器之间,可以通过发送消息头的方式来传递一些信息。
              比如user-agent,它包含了浏览器的相关信息,比如类型及版本号。
          实体内容
              如果是post请求,浏览器会将参数名=参数值放在该处。
              如果是get请求,参数名=参数值跟在请求资源路径后面。
    ● 响应数据包
         响应行
               协议类型及版本号
              响应的状态码
              状态码描述信息
         若干消息头
              由w3c制定的一些键值对,比如
              content-type:告诉浏览器,服务器返回的数据类型及编码格式
         实体内容
              服务器处理之后的数据
  4. get请求与post请求区别
    1)如果是get请求,请求参数是放在请求资源路径后面,不能够提交大量的数据(不同的浏览器对数据量大小的限制不一样, 一般是2k-8k,为了保证浏览器的兼容性,最好不要超过2k), 而post请求的请求参数是放在实体内容里面,理论上没有限制。
    2)post相对于get更安全。post也不是绝对的安全,因为服务器不会对数据加密,可以通过代理服务抓取数据包,所以对于敏感的数据建议加密。

8.servlet获取请求参数

  • 参数名唯一
    String request.getParameter(参数名);
    注:
        a.如果参数名写错,返回的是null
        b.如果用户在输入框没有输入数据,返回的是 “”
  • 参数名有多个相同
        String[] request.getParameterValues(参数名);

9.转发与重定向

  • 重定向
    • 服务器向浏览器发送一个302的状态码以及一个location消息头(值就是一个url地址),当浏览器检测到302状态码之后,会立即向location的地址发送请求
    • 如何重定向
      response.sendRedirect(String url);
    • 重定向的特点
      • 重定向之后,浏览器地址栏的地址会发生改变
      • 重定向的地址是任意的
  • 转发
    • 一个web组件(servlet/jsp)将未完成的事情交给另外一个组件继续完成。通常情况是servlet将未做完的事情交给jsp继续处理。比如:servlet负责取数据,jsp负责展示数据
    • 如何转发
      • step1.绑定数据
        //name:绑定名 obj:绑定值
        request.setAttribute(String name,Object obj);
        //根据绑定名获取绑定值
        Object request.getAttribute(String name)
      • step2.获得转发器
        //url:转发的目的地
        RequestDispatcher dispatcher = request.getRequestDispatcher(String url);
      • step3.转发
        dispatcher.forward(req,res);
    • 转发的特点
      • 转发之后,浏览器地址的地址不会发生改变
      • 转发的地址只能是同一应用内部的地址
      • 转发之间的组件共享同一个request和response

10.servlet 生命周期

1)为什么要学习Servlet生命周期

Servlet程序由tomcat服务器调用,所以有必要去知道究竟怎么去调用,Servlet生命周期就是要去搞明白Servlet对象什么时候去创建?调用什么方法?什么时候Servlet对象被销毁?销毁调用什么方法做了什么事情?Servlet程序的生命周期是由tomcat服务器去控制的。

2)servlet分为几个阶段

  • 阶段一:实例化
    • 情况一(默认):
      • 当请求到达容器时,容器会先检查是否有该对象,如果没有,创建该servlet对象,servlet生命周期整个过程当中,只会被实例化一次。
    • 情况二:
      • 当容器启动时创建servlet对象因为有一些servlet实例化之后需要做大量的初始化工作,比如读取配置文件信息,这些操作需要花费 一定的时间,如果当请求到达容器时才实例化,那么服务器响应的时间会较长,影响用户体验度。
      • 方式:
        在web.xml文件中配置<load-on-startup>1</load-on-startup>配置的参数>=0的整数,数值越小,优先级越高
  • 阶段二:初始化
    • 容器为servlet分配资源,调用init(ServletConfig)方法,ServletConfig对象由容器在调用init方法之前创建好,可以通过getServetConfig()方法获取到config对象,config.getInitParameter(key)通过该方法可以获取初始化参数值
      可以在web.xml中配置初始化参数,或者通过注解方式
      <init-param>
          <param-name>city</param-name>
          <param-value>南京</param-value>
      </init-param>
      String value = getServletConfig().getInitParameter(“key”);
    • 注:可以重写init方法,建议重写无参的init()
  • 阶段三:就绪
    • 在servlet对象实例化完,并且初始化工作已结束,容器会调用service方法,会根据请求方式决定调用doGet()还是doPost();可以重写service()方法 (建议),也可以重写doGet()或者doPost()方法
    • 注:service方法在请求到达容器时被调用,而且每发送一次请求,就会被调用一次
  • 阶段四:销毁
    • 容器会根据自身的算法,调用destroy方法
  • 总结:在servlet生命周期的整个过程中,实例化/初始化/销毁只会被执行一次,而就绪会被调用多次。

3)servlet相关的接口与类

  • servlet接口
    init(ServletConfig config);
        ServletConfig是一个接口
    service(ServletRequest req,ServletResponse res);
        ServletRequest接口
        ServletResponse接口
    destroy();
  • GenericServlet抽象类实现了servlet接口
    init();
    destroy();
  • HttpServlet抽象类继承了GenericeServlet
    service()方法
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java Web开发中,通过Servlet可以实现Web上传功能。以下是一个简单的示例代码: 首先,需要在web.xml中配置一个Servlet,如下所示: ``` <servlet> <servlet-name>uploadServlet</servlet-name> <servlet-class>com.example.UploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>uploadServlet</servlet-name> <url-pattern>/upload</url-pattern> </servlet-mapping> ``` 然后,编写一个UploadServlet类,实现doPost方法来处理上传请求: ``` public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取上传文件 Part filePart = request.getPart("file"); String fileName = filePart.getSubmittedFileName(); InputStream fileContent = filePart.getInputStream(); // 保存文件到服务器 File file = new File("/path/to/upload/directory/" + fileName); OutputStream out = new FileOutputStream(file); byte[] buffer = new byte[1024]; int length; while ((length = fileContent.read(buffer)) > 0) { out.write(buffer, 0, length); } out.close(); fileContent.close(); // 返回上传成功信息 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head><title>Upload Result</title></head>"); out.println("<body>"); out.println("<h1>文件上传成功!</h1>"); out.println("</body>"); out.println("</html>"); out.close(); } } ``` 在上面的代码中,通过request.getPart("file")方法获取上传的文件,然后可以将文件保存到服务器的指定目录中。保存完文件后,通过response.getWriter()方法获取响应输出流,输出上传成功的信息。 最后,在上传文件的表单中,设置enctype为multipart/form-data,action为上传Servlet的URL,如下所示: ``` <form method="post" enctype="multipart/form-data" action="/upload"> <input type="file" name="file"><br> <input type="submit" value="上传"> </form> ``` 这样就可以实现简单的文件上传功能了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值