代码改变世界

servlet入门

2019-01-21 17:33  缩酒  阅读(193)  评论(0编辑  收藏  举报

 什么是Servlet

  1. ServletSUN定义的一组接口,规范而SUN自己并没有去实现它
  2. Tomcat是一个JavaWeb服务器也是一个Servlet容器
  3. Servlet的创建、运行、销毁都有Servlet容器完成

servlet 功能

1.浏览器是客户端,服务器是服务端,浏览器要浏览页面的话需要发送请求到服务器,服务器响应后,浏览器方可浏览,浏览器地址里一般使用绝对路径,服务器一般使用相对路径

2.网页(web page),是网站中的一「页」,通常是HTML格式(文件扩展名为。html或。htm或。asp或。aspx或。php或。jsp等)。网页通常用图像档来提供图画。网页要使用网页浏览器来阅读。

浏览器:万维网(Web)服务的客户端浏览程序。可向万维网(Web)服务器发送各种请求,并对从服务器发来的超文本信息和各种多媒体数据格式进行解释、显示和播放。

服务器指一个管理资源并为用户提供服务的计算机软件,通常分为文件服务器、数据库服务器和应用程序服务器。运行以上软件的计算机或计算机系统也被称为服务器。

三者关系:网页是网站中的一页,整个网站的资源都是放在服务器上的。我们浏览某一网页时,是要通过浏览器,发送请求,然后服务器根据发送的请求,传回相应的这一网页的数据给浏览器,浏览器然后解释并显示和播放传回的数据,即我们平时能看到的资料。

接收请求参数        业务处理(查询数据)     页面跳转(把数据响应给浏览器)

第一个Servlet程序

 

  1. 创建一个Web项目   2.导入Servletjar包     3自定义Servlet类   4. web.xml中配置Servlet
  2. 启动访问

    http://localhost:80/xx/hehe

    http://ip地址:端口/上下文路径/我们自己的路径

     

 Servlet的生命周期

javax.servlet.Servlet接口中的方法:

--------------------------------------------------------------------

public void init(ServletConfig config):  初始化方法

public void service(ServletRequest req, ServletResponse res):服务方法

public void destroy():销毁方法

public ServletConfig getServletConfig():返回当前Servlet的配置信息对象.

public String getServletInfo():该方法返回Servlet的信息(作者,版权等).

 测试流程和步骤:

执行流程: 构造器-->init方法--> 循环[ service方法 ]--->destory方法(正常关闭Tomcat)

     1:构造器先执行,创建Servlet对象:init,service,destory方法,都是非static方法,都得使用对象调用.

     2:一个Servlet类在整个生命周期中最多只有一个对象.

     3:init在构造器执行之后,立马执行,只执行一次,为对象做初始化操作.

     4:service方法在每次请求都会执行.

     5:destroy方法只有在正常关闭Tomcat,才会执行,不要期望该方法一定执行,不要在该方法编写扫尾操作.

     6:Servlet类必须使用public修饰,Servlet的构造器,必须是公共无参数的.原因在下一个知识点.

 

 

 

 

Servlet的执行流程

 

  1. 从浏览器输入地址(发起请求)开始分析: http://localhost:80/xx/hello
    1. localhost   也可能是ip 或者域名  ---》定位服务器主机
    2. 80 定位到tomcat
    3. xx  上下文路径,tomcat/conf/server.xml  中的

 

<Context  docBase=”F:\workspace\day11-servlet\webapp” path=”xx” />  中的path  

 

            通过上面的步骤找到了 docBase后面的项目的真实路径

 

根据约定去找到项目中的配置文件 web.xml

 

  1. web.xml内容分析:
    1. 找到url-pattern的值为 /hello
    2. 通过上一步中对应servlet-name 找到对应的servlet标签
    3. 找到对应的Servlet的完全限定名 cn.itsource._01hello.HelloServlet

 

 仅仅是一个字符串而已,交给Tomcat进行处理

 

通过反射来创建对象并调用方法

 

  1. TomcatServlet的创建:
    1. 通过上获得 servlet的完全限定名为参数使用反射来创建一个对象

 

Class clz  =  Class.forName(“cn.itsource._01hello.HelloServlet”)

 

Clz.newInstance()  要求自己的Servlet类必须有公共的无参数的构造方法

 

  1. 如果是第一次访问,就会创建一个Servlet的对象,并缓存起来
  2. 2
  3. 。。。N 直接先从缓存中看有没有,有直接使用调用service方法

 

 filter 可以接受一些参数。  init-param 的param-name 就是参数名  param-value就是参数值, 支持多个参数
每一个 filter 都有一个 init 方法 ,可以再这个 方法中通过 getInitParamter("key"); key 就是 param-name的值,来获取对应的参数值
常用的 就是 设置编码过滤器 , 例如 : <init-param><param-name>encoding</param-name><parma-value>UTF-8</param-vaue></init-param>
init-param(初始化参数)

 我们一般只执行service方法,但是现在我们直接实现Servlet接口,所有的方法都需要实现,每个实现类都这样做感觉...

 

使用适配器模式

 

写一个父类MyGenericServlet,这个父类去实现Servlet接口

 

  之后我们的所有子类直接继承这个父类,只需要去完成service方法即可

 

请求和响应

 

HttpServlet

 

我们使用HttpServlet的三种方式:

 

1. GET里面调用POST        2. POST里面调用GET      

3.(推荐)不管什么请求,直接在service中执行就可以了

  HttpServlet继承了GenericServlet,而GenericServlet实现Servlet接口

        - 所以我们可以同构继承HttpServlet来创建一个Servlet。
        - HttpServlet重写service()方法:
            1.在该方法中先将ServletRequest和ServletResponse
                强转为了HttpServletRequest和HttpServletResponse。
            2.然调用重载的service()方法,并将刚刚强转得到对象传递到重载的方法中。
        - 重载service(HttpServletRequest request , HttpServletResponse response)
            1.在方法中获取请求的方式(get或post)
            2.在根据不同的请求方式去调用不同的方法:
                如果是GET请求,则调用doGet(HttpServletRequest request , HttpServletResponse response)
                如果是post请求,则调用doPost(HttpServletRequest request , HttpServletResponse response)
        - 结论:
            当通过继承HttpServlet来创建一个Servlet时,我们只需要根据要处理的请求的类型,来重写不同的方法。
                处理get请求,则重写doGet()
                处理post请求,则重写doPost()
 

HttpServletRequest

 

HttpServletRequestServletRequest接口的子接口,表示HTTP协议的请求对象.

既然HttpServletRequestHTTP的请求对象,那么该接口中包含了获取各自请求信息的方法.

 

 

 常用方法:

1.  String getContextPath():获取上下文路径,<Context path="上下文" ../>

 

2.  String getHeader(String headName):根据指定的请求头获取对应的请求头的值.

 

3.   String getRequestURI():返回当期请求的资源名称.  上下文路径/资源名

 

4.  StringBuffer getRequestURL():返回浏览器地址栏的内容

 

5.   String getRemoteAddr():返回请求服务器的客户端的IP      (remote;远程的)

 

通过注册示例说明:

 

 

 

(重要)获取请求参数的方法:

   String getParameter(String name):根据参数名称,获取对应参数的值.

   String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.

 request.getParameterValues(String   name)是获得如checkbox类(名字相同,但值有多个)的数据。   接收数组变量 ,如checkobx类型    
request.getParameter(String   name)是获得相应名的数据,如果有重复的名,则返回第一个的值 . 接收一般变量 ,如text类型

   Enumeration<String> getParameterNames():获取所有请求参数的名字

 

   Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.

 

       key:参数名称

 

       value:参数值,封装在String数组中.

 

ServletConfig:

   String getInitParameter(String name): 获取web.xml中配置初始化参数.

 

HttpServletRequest:

   String getParameter(String name):     获取用户在页面中填写的信息.

 

HttpServletResponse

HttpPServletResponseServletResponse的子接口,表示HTTP协议的响应对象.

该接口中包含了处理响应的方法.

  OutputStream getOutputStream():获取字节输出流.  :文件下载

   Writer getWriter():获取字符输出流.              :输出内容

 

上述两行代码,其实可以简写(合体):

 

 

 

 

 

设置输出的编码格式和内容类型:

 

 

 和写如下:

 

请求中文乱码问题

1. 第一种解决乱码的问题:

request.setCharacterEncoding("UTF-8");

只支持POST,不支持GET

2.第二种  

server.xml中修改编码:URIEncoding="UTF-8"

只支持GET,不支持POST

3.第三种

 

String name = req.getParameter("name");

 

//将原来的码给转成二进制

 

byte[] nameBytes = name.getBytes("ISO-8859-1");

 

//再通过UTF-8的编码把这个数据转成相应的字符串

 

String nameStr = new String(nameBytes,"UTF-8");

 

GETPOST都支持

 

注:第二种与第三种在GET的情况下是冲突的,不能同时存在

 

 

ServletConfig(初始信息)

首先javaee文档中找到此接口

 

Servlet的继承体系(理解,今天放在最后一个点去复习)

我们从下面的一系列问题来摸索Servlet的继承体系:

 

我们一般只执行service方法,但是现在我们直接实现Servlet接口,所有的方法都需要实现,每个实现类都这样做感觉...

 

 

 

解决办法: 使用适配器模式

 

写一个父类MyGenericServlet,这个父类去实现Servlet接口

 

  之后我们的所有子类直接继承这个父类,只需要去完成service方法即可

 

service(HttpServletRequest req, HttpServletResponse resp)

web.xml

<display-name>ss</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>hello.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/AA</url-pattern>
  </servlet-mapping>

 

HelloServlet.java

package hello;

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

/**
 * Servlet implementation class HelloServlet
 */
/*@WebServlet("/HelloServlet")*/
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("登陆成功");
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*System.out.println("你好吗");*/
    }

}

 

 

index.html

<form action="AA" method="get">
    用户名:<input type="text" name="username"  placeholder="username"/><br>
    密&nbsp码&nbsp&nbsp&nbsp:<input type="password" name="password"  placeholder="password"/><br>
<input type="submit" value="注册"/><br>
<input type="checkbox" name="hobby"/><br>
</form>