Java Web(2) 创建servlet

[toc]

1. 简易demo

Servlet开发流程:

  • 创建Servlet类,继承HttpServlet。
  • 重写service方法等,编写代码
  • 配置web.xml.绑定URL

1.1. 创建应用

使用IDEA创建web应用(File->new->project->Java Enterprise):

webapplication.png

生成如下项目结构:
项目结构.png

1.2. 创建Servlet

在src中创建继承HttpServlet类的FirstServlet(然后右键->generate->override Method,可以直接选择父类HttpServlet的方法)


public class FirstServlet extends HttpServlet {

//service为请求处理的核心方法,无论是get还是post都会被service方法处理
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接受请求发来的参数
        String name = req.getParameter("name");
        String html = "<h1 style='color:red'>hi," + name + "</h1><hr/>";
        PrintWriter out = resp.getWriter();
        out.println(html); //将htnl返回给浏览器
    }
}

1.3. 配置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_4_0.xsd"
         version="4.0">
    <display-name>FirstServlet</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <!-- 声明servlet -->
    <servlet>
        <!-- servlet的别名 -->
        <servlet-name>first</servlet-name>
        <!--servlet的包名-->
        <servlet-class>com.example.FirstServlet</servlet-class>
    </servlet>
    <!-- 将servlet与URL绑定-->
    <servlet-mapping>
        <servlet-name>first</servlet-name>
        <url-pattern>/hi</url-pattern>
    </servlet-mapping>
</web-app>

1.4. 启动应用

进行配置,然后点击run.


configurations.png

2. Tomcat部署

但是有一个问题,就是当项目部署后,我们打开tomcat的webapps目录下,并找不到生成的项目。如果在/tomcat/webapps找不到项目,tomcat怎么能启动项目的呢?这是因为我们使用的是idea
Tomcat部署有以下这些方式:

  • 利用Tomcat自动部署:项目放到webapps目录下,启动tomcat,就回自动部署。
  • 利用控制台进行部署:控制台不是说cmd,而是tomcat启动后进入root页面,有个manager管理部署项目。进入tomcat的manager控制台的deploy区域进行设置就可以部署。
  • 使用eclipse:一般自动放到/tomcat/webapps,也可以设置(略)。
  • 使用IDEA:可以增加自定义的Web部署文件(%Tomcat_Home%\conf\Catalina\localhost\platform-zwml-admin.xml)。也可以通过IDE设置。
    打开项目的Project Structure -> artifacts, 设置output directory:
    output.png

    可以发现默认output就是项目的out文件夹:
    默认output.png

3. Java Web目录

3.1 Java Web工程目录

以IDEA为例:


idea中Java Web目录.png
组织结构 描述
/src 写Java代码的地方,如Servlet、JavaBean等
/out 项目的生成目录,可以通过Project Structure设置成其他地方,放在 tomcat/webapps下可直接访问
/web 用来存放 JSP,JS,CSS,图片等文件,是项目访问的默认路径
/web/WEB-INF WEB应用的安全目录,用于存放配置文件
/web/WEB-INF/web.xml web.xml是Web项目核心配置文件
/web/WEB-INF/lib 用于存放web应用依赖的jar文件,一般将外部jar放到此处,刷新后就可以在/src中使用

3.2 Tomcat应用目录

tomcat部署应用的目录如下:

组织结构 描述
tomcat安装目录/webapps Tomcat应用根目录
/web应用目录 Java Web 应用目录
/web应用目录/index.html or index.jsp 默认首页(可以在web.xml指定首页)
/web应用目录/WEB-INF WEB应用的安全目录,外部不能访问 ,用于存放配置文件
/web应用目录/WEB-INF/web.xml web.xml是“部署描述符文件”,是该Web项目核心配置文件
/web应用目录/WEB-INF/classes 存放编译后的classes文件
/web应用目录/WEB-INF/lib 用于存放web应用依赖的jar文件
/web应用目录/META-INF/MANIFEST.MF 包含Web应用的版本等信息

3.1 Java Web工程目录转化为Tomcat应用目录

当我们在IDEA中点击运行时, Java Web工程目录会被转化为Tomcat能够运行的目录结构。


生成目录.png

我们会发现生成的应用目录LoginServlet和工程目录的/web大体一致,除了WEB-INF外的其他部分不变。
工程项目中的/src中的Java代码会被编译成class,存放到LoginServlet/WEB-INF/classes中。
/web中的内容会在应用目录LoginServlet/WEB-INF/classes/web中备份一份。

4. Get与Post请求

4.1 Get请求

  • Get请求是将数据通过在URL附加数据显性向服务器发送数据。http://localhost:8080/tryServlet/first?name=liming
    get.png

4.2 Pos请求

  • Post请求会将数据存放在“请求体”中隐性向服务器发送数据: http://localhost:8080/tryServlet/first,请求体:name=liming.
    post.png

4.3 处理Get和Post

两者到服务器获取的parameter没区别。
service为请求处理的核心方法,无论是get还是post都会被service方法处理。
如何分别处理getpost?

  • 所有请求:service
  • Get请求: doGet
  • Post请求:doPost
public class RequestMethodServlet extends HttpServlet {
    //处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        resp.getWriter().println("<h1 >" + name + "</h1>");
    }
    //处理post请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        resp.getWriter().println("<h1>" + name + "</h1>");
    }
}

5. Servlet生命周期

  • 装载 - 查看web.xml
  • 创建 - 构造函数
  • 初始化- 在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()
  • 提供服务 -service(),doGet(),doPost()
  • 销毁 - 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

与 CGI 的区别在于,Servlet 处于服务器进程中,它通过多线程方式运行其 service 方法,一个实例可以运行多个请求,并且其实例一般不会销毁,而 CGI 对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于 Servlet。


servlet生命周期.jpg

6.注解简化配置

随着项目的扩大,web.xml会越来越长,难以维护,每次修改Servlet都要修改相应的web.xml的内容。Servlet3.0之后引入了注解annotation来简化配置。
Servlet的核心注解为@WebServlet

package com.example;
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.io.PrintWriter;

@WebServlet("/first")
public class FirstServlet extends HttpServlet {
//service为请求处理的核心方法,无论是get还是post都会被service方法处理
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接受请求发来的参数
        String name = req.getParameter("name");
        String html = "<h1 style='color:red'>hi," + name + "</h1><hr/>";
        PrintWriter out = resp.getWriter();
        out.println(html); //将htnl返回给浏览器
    }
}

7.启动时加载Servlet

servlet一般在第一次请求后进行初始化,通过启动时加载 可以提前加载servlet。通常重写init()方法,进行项目的一些预处理。

7.1 web.xml

web.xml使用<load-on-startup>设置启动加载。启动时加载在工作中常用于系统的预处理。(预处理可以时实际工作时效率更高)

<!-- 0优先级最高-->
<load-on-startup>0~9999</load-on-startup>

7.2 annotition注解

@WebServlet(urlPatterns = "/unused", loadOnStartup = 2)
public class RequestMethodServlet extends HttpServlet { //...}

8.ServletContext和ServletConfig

8.1 .ServletConfig

在运行 Servlet 程序时,可能需要一些辅助信息,例如,文件使用的编码、使用 Servlet 程序的共享信息等,这些信息可以在 web.xml 文件中使用一个或多个 <init-param> 元素进行配置。当 Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息封装到 ServletConfig 对象中,此时可以通过调用 init(ServletConfig config)方法将 ServletConfig 对象传递servlet。

xml
<servlet>
  <servlet-name>Servlet1</servlet-name>
  <servlet-class>com.Servlet1</servlet-class>
  <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
  </init-param>
</servlet>
//ava
 ServletConfig config = this.getServletConfig();
 String param = config.getInitParameter("encoding");

8.2 .ServletContext

当 Tomcat 启动时,Tomcat 会为每个 Web 应用创建一个唯一的 ServletContext 对象代表当前的 Web 应用,该对象封装了当前 Web 应用的所有信息。可以利用该对象获取 Web 应用程序的初始化信息、读取资源文件等。

learn more

这里只是简要介绍以下Sevlet,具体可以参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343