zoukankan      html  css  js  c++  java
  • Java开发工程师(Web方向)

    第1章--Servlet

    Servlet简介

    Servlet应用于?

    浏览器发出HTTP请求,服务器接收请求后返回响应给浏览器。

    接收请求后到返回响应之间:

    服务器将请求对象转交给Servlet容器

    Servlet容器根据HTTP请求的具体路径将请求转交给具体的Servlet

    Servlet在收到请求后进行相应的处理逻辑后,将处理返回给服务器

    服务器将HTTP响应返回给浏览器

    Servlet是什么?

    Servlet = Server + Applet -- 运行于Server的Applet

    Applet (在web环境下运行与客户端的Java组件):没有main method,不能独立运行于JVM,需要特殊的容器装载运行,由容器管理生成销毁

    Servlet:一个Servlet就是一个Java类,并提供基于请求-响应模式的Web服务

    Servlet容器:装载和管理Servlet;为一个服务端程序,用于转交请求给Servlet

    Eclipse中的Servlet配置:

    prerequisite: Tomcat, Eclipse, Eclipse Maven插件

    配置tomcat用户:

    tomcat/conf/tomcat-users.xml文件

    将文件中所有内容删除,加入以下内容并保存;

    <?xml version='1.0' encoding='utf-8'?>
      <tomcat-users>
      <role rolename="manager-gui"/>
      <role rolename="manager-script"/>
      <user username="admin" password="123456" roles="manager-gui,manager-script"/>
    </tomcat-users>

    保存后启动tomcat,范围localhost:8080

    点击右侧Manager App按钮,登陆,表明tomcat管理员配置成功

    Maven中配置Tomcat服务器:

    修改maven的配置文件~/.m2/settings.xml (different from maven/conf/settings.xml)

    增加tomcat服务器:在<servers></servers>直接增加子元素

    <server>
        <id>tomcat</id>
        <username>admin</username>
        <password>123456</password>
    </server>

    Tomcat Maven插件配置:

    在 web app的pom.xml 文件中的<plugins></plugins>直接增加子元素,增加代码:

    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <url>http://localhost:8080/manager/text</url>
            <path>/web_project_template</path>
            <uriEncoding>UTF-8</uriEncoding>  
            <finalName>web_project_template</finalName>
            <server>tomcat</server>
        </configuration>
    </plugin>

    Servlet Hello World:

    在web.controller包下New Class -- Superclass: HttpServlet

    Override methods: doGet(HttpServletRequest, HttpServletResponse); service(HttpServletRequest, HttpServletResponse);

    在service()中:syso.println("service method");

    重写doGet():

    System.out.println("doGet method");
    PrintWriter pw = resp.getWriter();
    pw.print("hello world");
    pw.close();

    src->main->webapp->WEB-INF->web.xml 配置对应的Servlet 

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.netease.server.example.web.controller.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    运行:

    Eclipse中对应项目,右键Run As--Run Configuration--双击左侧菜单Maven Build 以创建新的maven build--Name: maven deploy; Browser Workspace: 所要部署的项目; Goals: tomcat7:deploy

    启动tomcat,点击run即可进行部署。

    // Eclipse内置Tomcat-plugin:http://www.jianshu.com/p/8da9ca8c0667

    Eclipse internal web browser:Window->Show View->Other->Internal Web Browser.

    路径:http://localhost:8080/$project-path/$page-path

    project-path: pom.xml中配置的<plugin>tomcat7-maven-plugin的path: /web_project_template

    page-path: web.xml中配置的<servlet-mapping>url-pattern: /hello

    Error:

    [INFO] tomcatManager status code:200, ReasonPhrase:

    [INFO] FAIL - Application already exists at path [/web_project_template]

    solution: https://stackoverflow.com/questions/22671420/how-to-redeploy-a-war-on-remote-tomcat-7-using-maven-tomcat-plugin --> http://tomcat.apache.org/maven-plugin-2.2/tomcat7-maven-plugin/deploy-mojo.html#update

    Now--it works. -- http://localhost:8080/web_project_template/hello

    Servlet处理流程:

    浏览器中输入地址 http://localhost:8080/web_project_template/hello

    Servlet容器根据地址和配置文件web.xml找到对应的servlet: TestServlet.java

    同时将请求传递给对应servlet的service方法

    service方法是servlet的核心,每当客户端请求一个servlet对象时,会调用该对象的service方法,并传递给service方法一个HttpServletRequest对象和一个HttpServletResponse对象作为参数。

    使用HTTP的get方法访问的servlet,则service方法会将相应的请求传递给doGet()处理,post同理

    在doGet()方法中通过HttpServletResponse对象将"Hello World"返回给客户端

     

    Servlet接口与实现类

    Servlet生命周期:初始化、请求处理、销毁

    初始化:init():客户端第一次请求servlet时,servlet容器会创建servlet对象的实例,此时servlet容器会调用servlet的init();如果在配置文件中配置了loadOnSetup元素,则servlet会在容器启动时做相应的加载。

    请求处理:service():将不同的http请求转发给不同的servlet方法,常用doGet()/diPost()。

    销毁:destroy():由servlet容器对servlet进行资源回收和清理

    进入tomcat主页右边点击app manager,会看到所有部署的引用,点击web-project-template的stop,会执行destroy();

    想要在servlet进行逻辑处理之前做一些准备工作,或在servlet实例销毁之前进行资源回收或清理的工作:

    i.e. override method: init(); destroy();

    init(); or init(ServletConfig config); ? 一般情况选择init();

    init()中:syso.println("init method");

    destroy()中:syso.println("destroy method");

    get与post的区别:

    get:传输方式-HTTP header;url可见;设计目的:获取数据;安全性低

    post:传输方式-HTTP body;url不可见;设计目的:发送数据;安全性高

    i.e.

    /src/main/webapp下有静态页面getPostTest.html,

    包含两个表单form,分别使用get和post方法,action="servlet/GetPostServlet"

    对应有servlet对象GetPostServlet.java 

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String name1 = request.getParameter("name1");
        String pw1 = request.getParameter("pw1");
    
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");
        out.print("   调用doGet 方法 ");
        out.println("<br></br>");
        out.println("用户名:" + name1);
        out.println("<br></br>");
        out.println("密码:" + pw1);
        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }
    
    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String name2 = request.getParameter("name2");
        String pw2 = request.getParameter("pw2");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");
        out.print("    调用doPost 方法 ");
        out.println("<br></br>");
        out.println("用户名:" + name2);
        out.println("<br></br>");
        out.println("密码:" + pw2);
        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    } 

    在web.xml对应servlet元素 

    <servlet>
        <servlet-name>GetPostServlet</servlet-name>
        <servlet-class>com.netease.server.example.web.controller.GetPostServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetPostServlet</servlet-name>
        <url-pattern>/servlet/GetPostServlet</url-pattern>
    </servlet-mapping>

    部署后,地址栏 http://localhost:8080/web-project-template/getPostTest.html

    点击按钮会跳转到 web_project_template/servlet/GetPostServlet

    不同的是,get提交后的url为http://localhost:8080/web_project_template/servlet/GetPostServlet?name1=admin1&pw1=nopass.a1

    而post提交后的url为http://localhost:8080/web_project_template/servlet/GetPostServlet

    Servlet配置参数:

    将配置信息以硬编码方式固定,是不好的习惯--代码维护成本高

    那么如何配置呢?:ServletConfig

    特点:

    在Servlet初始化过程中,<init-param>参数将被封装到ServletConfig中

    每个Servlet支持设置一个或者多个<init-param>

    以Servlet为单位,不是全局共享

    web.xml中,在<servlet>子元素中添加

    <servlet>
        <init-param>
            <param-name>data1</param-name>
            <param-value>value1</param-value>
        </init-param>
        <init-param>
            <param-name>data2</param-name>
            <param-value>value2</param-value>
        </init-param>
        <servlet-name>ServletConfigServlet</servlet-name>
        <servlet-class>com.netease.server.example.web.controller.ServletConfigServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletConfigServlet</servlet-name>
        <url-pattern>/servlet/ServletConfig</url-pattern>
    </servlet-mapping>

    从Servlet中获取对应的参数:

    首先,拿到ServletConfig对象

    然后配置对应的参数值即可 

    @Override
    public void init() throws ServletException {
        ServletConfig config = this.getServletConfig();
        String v1 = config.getInitParameter(data1);
        System.out.println("v1 = " + v1);
        String v2 = config.getInitParameter(data2);
        System.out.println("v2 = " + v2);
    }

    NB: DO NOT FORGET TO ADD A DOGET() METHOD TO HANDLE THE RESPONSE STUFF. 

     

    不同Servlet共享的配置信息:ServletContext

    Servlet容器在启动的时候,会对每个web应用创建一个对应的ServletContext对象(全局只有一个)

    在web.xml中进行ServletContext的配置:

    <context-param>
        <param-name>globalData1</param-name>
        <param-value>123</param-value>
    </context-param>
    <!-- could be several pairs -->
    <!-- no mapping to servlet -->

    在任意Servlet中获取配置即可:

    ServletContext ctx = this.getServletContext();
    String globalValue1 = ctx.getInitParameter("globalData1");
    String globalValue2 = ctx.getInitParameter("globalData2");
    System.out.println("global value1: " + globalValue1 + "; global value2: " + globalValue2);

      

    如果这些配置是事先不知道的呢?--ServletContext也支持动态信息-Attribute(Key-Value)

    i.e. 通过ServletContext的动态属性,来完成信息的共享

    在servlet a中:ctx.setAttribute("attribute" ,"111");    // set key-value pair

    在servlet b中:String attribute1 = (String) ctx.getAttribute("attribute");    // get the value of attribute1

     

    如果想要从外部资源里而不是web.xml中读取配置信息呢?

    getResource();

    getResourceAsStream();

    getRealPath();

    i.e. 使用ServletContext读取log4j的配置信息:

    1. getResource();

    URL url = ctx.getResource("/WEB-INF/classes/log4j.properties"); --import java.net;

    --try catch: MalformedURLException

    InputStream in = url.openStream(); --import java.io;

    --try catch: IOException

    写方法String getProperty(String, InputStream);

    public static String getPropery(String key, InputStream in) {
        Properties props = new Properties();
        try {
            props.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String value = props.getProperty(key);
        return value;
    }

    调用该方法获取对应value

    String propertyValue = GeneralUtil.getProperty("log4j.rootLogger", in);

    即可。

    完整代码:

    try {
        URL url = ctx.getResource("/WEB-INF/classes/log4j.properties");
        InputStream in = url.openStream();
        String propertyValue = GeneralUtil.getPropery("log4j.rootLogger", in);
        System.out.println("property value: " + propertyValue);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

      

    2. getResourceAsStream();

    InputStream in = ctx.getResourceAsStream("/WEB-INF/classes/log4j.properties");

    String p = GeneralUtil.getProperty("log4j.rootLogger", in);

     

    3. getRealPath();

    String path = ctx.getRealPath("/WEB-INF/classes/log4j.properties");

    System.out.println("real path:" + path);

    File file = new File(path);

    InputStream in = new FileInputStream(file);

    // try catch FileNotFoundException

    String p = GeneralUtil.getProperty("log4j.rootLogger", in);

     

    Servlet配置 

    Web应用程序的基本结构:

    webapp:

    1. 公共资源:通过url可以访问到的静态资源,如css, js, images, html,不同类型资源分类于不同目录

    2. META-INF目录:定义了jar包的源信息,定义了包拓展属性、类加载路径、自定义属性等

    3. WEB-INF目录:不提供给用户,无法通过浏览器访问。放置类文件和类所依赖的库。

    包括两个子目录:classes和lib 和一个web.xml文件。classes放置编写的代码和编译后的类文件。lib放置web依赖的jar包。

    web.xml部署描述服务,用于描述一个web应用。

    web.xml文件:

    用于设置web应用程序的组件部署信息。

    Servlet容器需要支持部署描述符的所有元素。

    web.xml文件中的配置:

    1. Servlet声明

    <servlet>

    <servlet-name>servlet类的名称</servlet-name>

    <servlet-class>servlet类的实际路径</servlet-class>

    </servlet>

    <servlet-mapping> 

    <servlet-name>和上面对应的servlet类名</servlet-name>

    <url-pattern>servlet对外映射的相对路径(一般以/开头)</url-pattern>

    <url-pattern>可有多个mapping路径 & "*"可做模糊匹配</url-pattern>

    </servlet-mapping>

    Servlet-Mapping匹配规则:

    若两个servlet的url-pattern重复了,则

    a. 精确路径匹配,完全匹配;

    b. 最长路径匹配,最长前缀匹配(路径匹配最多的);

    c. 扩展名匹配;

    d. default servlet;

    e. 如果没有default servlet,则放弃匹配返回报错。

    规则从上往下按优先级顺序

    i.e.  

    /hello --a--> Servlet1

    /hello/world/index --b--> Servlet3

    /admin.jsp --c--> Servlet4

    /world --d--> Servlet5

    /hello.jsp --c--> Servlet4

    /hello/world/hello.jsp --b--> Servlet3

     

    2. ServletConfig配置--位于Servlet元素

    <servlet>

    <init-param> 可有多个

    <param-name> key </param-name>

    <param-value> value </param-value>

    </init-param>

    <servlet-name>

    ...

    3. ServletContext配置--全局

    <context-param>

    <param-name> key </param-name>

    <param-value> value </param-value>

    </context-param>

    4. 若需要在Servlet容器启动时执行操作(init()为找Servlet第一次收到请求时的操作)

    "load-on-startup"改变Servlet默认初始化时间--负数/无设置:第一次请求时加载

    <servlet>

    <load-on-startup>0</load-on-startup>

    <servlet-name>...

    ...

    5. 配置自定义错误页面 <error-page>

    <error-page>

    <error-code>404</error-code>

    <location>/404.html</location>

    </error-page>

    更高级的做法:添加exception-type元素捕获一个Java异常类型

    6. 若用户在地址栏输入web app路径的url,如:http://localhost:8080/web_project_template/

    会出现一个登录页面--index.html页面(首页/欢迎页面)

    对应在部署描述中为<welcome-file-list>可包含一个或多个<welcome-file>子元素

    指定多个欢迎页面的加载顺序:<welcome-file>在<welcome-file-list>中的顺序

    7. 对于静态资源 打开文件 or 下载文件?

    MIME(Multi-purpose Internet Mail Extensions)多用途互联网邮件扩展类型--发展为描述消息内容类型的互联网标准。

    --设置某种扩展名文件的打开方式

    <mime-mapping>定义扩展文件名映射类型

    <extension>

    <mime-type>

    </mime-mapping>

    下章预告:

    Servlet session配置

    Servlet filter配置

    Servlet listener配置

     

    Servlet单元测验

    本次得分为:46.00/46.00, 本次测试的提交时间为:2017-08-06, 如果你认为本次测试成绩不理想,你可以选择再做一次。
    1单选(2分)

    Servlet有什么特征?

    • A.其它选项都是正确�2.00/2.00
    • B.运行在Servlet容器里的程序
    • C.Web服务
    • D.一个Java类
    2单选(2分)

    Servlet容器是什么?

    • A.装载和管理Servlet的服务端程序�2.00/2.00
    • B.保存Servlet的程序
    • C.Tomcat
    • D.其它选项都不对
    3单选(2分)

    以下哪种关系跟Servlet与Servlet容器关系最接近?

    • A.遥控器和电视机
    • B.螺丝和螺丝刀
    • C.子弹和枪�2.00/2.00
    • D.CD与CD机
    4单选(2分)

    下面哪些内容不是部署描述符中的配置?

    • A.<servlet>
    • B.<list>�2.00/2.00
    • C.<welcome-file-list>
    • D.<error-page>
    5单选(2分)

    下面哪些是标准web应用程序包括的内容?

    • A.web.xml
    • B.公共资源
    • C.WEB-INF
    • D.其它选项都是�2.00/2.00
    6
    单选(2分)

    如果现在有以下7个servlet,且其url-pattern与对应的servlet的关系如下: 

    url-pattern

    servlet

    /abc

    Servlet1

    /abcd

    Servlet2

    /abc/*

    Servlet3

    /abc/def

    Servlet4

    /abc/def/*

    Servlet5

    *.jsp

    Servlet6

    /

    Servlet7

    如果现在请求的相对路径是/abc/def/gh,请求将发到哪个servlet?

    • A.Servlet4
    • B.Servlet3
    • C.Servlet1
    • D.Servlet5�2.00/2.00
    7单选(2分)

    如果现在请求的相对路径是/abcd.jsp,请求将会发到哪个Servlet?

    • A.Servlet6�2.00/2.00
    • B.Servlet7
    • C.Servlet3
    • D.Servlet2
    8单选(2分)

    如果现在请求的相对路径是/abc/def/gh.jsp,请求将会发到哪个Servlet?

    • A.Servlet4
    • B.Servlet3
    • C.Servlet6
    • D.Servlet5�2.00/2.00
    9单选(2分)

    下面的描述中哪项是ServletContext的作用?

    • A.其它选项都是�2.00/2.00
    • B.读取外部资源文件信息
    • C.通过配置文件共享全局信息
    • D.Servlet转发
    10单选(2分)

    下面哪项描述是正确的?

    • A.http get方法,需要传输的数据是在http协议的header里,http post方法,需要传输的数据是在http协议的body里
    • B.其它选项都是�2.00/2.00
    • C.从设计目的上看,http get方法是获取数据,post方法是发送数据
    • D.一般而言,http post方法比get方法更安全
    11多选(3分)

    Servlet生命周期包括哪些回调方法?

    • A.init�1.00/3.00
    • B.service�1.00/3.00
    • C.destroy�1.00/3.00
    • D.main
    12多选(3分)

    ServletContext读取外部配置文件的方法有哪些?

    • A.getResource�1.00/3.00
    • B.getPath
    • C.getResourceAsStream�1.00/3.00
    • D.getRealPath�1.00/3.00
    13判断(2分)

    部署描述符一定是xml文件,且命名必须是web.xml

    • A.×
    • B.√�2.00/2.00
    14判断(2分)

    Servlet-mapping中支持多个url-pattern对应同一个servlet

    • A.×
    • B.√�2.00/2.00
    15判断(2分)

    Servlet-mapping中的url-pattern支持模糊匹配

    • A.√�2.00/2.00
    • B.×
    16判断(2分)

    load-on-startup设置的值越小,servlet启动越晚

    • A.×�2.00/2.00
    • B.√
    17判断(2分)

    部署描述符中可以设置多个欢迎页面

    • A.×
    • B.√�2.00/2.00
    18判断(2分)

    ServletConfig对象只能在init方法中获取

    • A.√
    • B.×�2.00/2.00
    19判断(2分)

    ServletConfig只能配置一对init-param参数

    • A.√
    • B.×�2.00/2.00
    20判断(2分)

    Servlet init方法在其生命周期中只会被调用一次

    • A.√�2.00/2.00
    • B.×
    21判断(2分)

    Servlet destroy方法在请求结束后会被调用

    • A.×�2.00/2.00
    • B.√
    22判断(2分)

    ServletConfig中配置的参数可以在其它Servlet中获取

    • A.√
    • B.×�2.00/2.00
  • 相关阅读:
    Java知识15 Number&Math类【多测师】
    python callable()方法实例
    高级super实例
    高级any、for组合用法
    python 字典update、setdefault、pop方法案例
    一个经典的python字典生成式案例
    一个发挥到极致的yield案例
    python map使用
    Python yield详解
    django __path__使用
  • 原文地址:https://www.cnblogs.com/FudgeBear/p/7289221.html
Copyright © 2011-2022 走看看