Java开发工程师(Web方向) - 02.Servlet技术 - 第1章.Servlet
第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单元测验
Servlet有什么特征?
- A.其它选项都是正确2.00/2.00
- B.运行在Servlet容器里的程序
- C.Web服务
- D.一个Java类
Servlet容器是什么?
- A.装载和管理Servlet的服务端程序2.00/2.00
- B.保存Servlet的程序
- C.Tomcat
- D.其它选项都不对
以下哪种关系跟Servlet与Servlet容器关系最接近?
- A.遥控器和电视机
- B.螺丝和螺丝刀
- C.子弹和枪2.00/2.00
- D.CD与CD机
下面哪些内容不是部署描述符中的配置?
- A.<servlet>
- B.<list>2.00/2.00
- C.<welcome-file-list>
- D.<error-page>
下面哪些是标准web应用程序包括的内容?
- A.web.xml
- B.公共资源
- C.WEB-INF
- D.其它选项都是2.00/2.00
如果现在有以下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.Servlet52.00/2.00
如果现在请求的相对路径是/abcd.jsp,请求将会发到哪个Servlet?
- A.Servlet62.00/2.00
- B.Servlet7
- C.Servlet3
- D.Servlet2
如果现在请求的相对路径是/abc/def/gh.jsp,请求将会发到哪个Servlet?
- A.Servlet4
- B.Servlet3
- C.Servlet6
- D.Servlet52.00/2.00
下面的描述中哪项是ServletContext的作用?
- A.其它选项都是2.00/2.00
- B.读取外部资源文件信息
- C.通过配置文件共享全局信息
- D.Servlet转发
下面哪项描述是正确的?
- A.http get方法,需要传输的数据是在http协议的header里,http post方法,需要传输的数据是在http协议的body里
- B.其它选项都是2.00/2.00
- C.从设计目的上看,http get方法是获取数据,post方法是发送数据
- D.一般而言,http post方法比get方法更安全
Servlet生命周期包括哪些回调方法?
- A.init1.00/3.00
- B.service1.00/3.00
- C.destroy1.00/3.00
- D.main
ServletContext读取外部配置文件的方法有哪些?
- A.getResource1.00/3.00
- B.getPath
- C.getResourceAsStream1.00/3.00
- D.getRealPath1.00/3.00
部署描述符一定是xml文件,且命名必须是web.xml
- A.×
- B.√2.00/2.00
Servlet-mapping中支持多个url-pattern对应同一个servlet
- A.×
- B.√2.00/2.00
Servlet-mapping中的url-pattern支持模糊匹配
- A.√2.00/2.00
- B.×
load-on-startup设置的值越小,servlet启动越晚
- A.×2.00/2.00
- B.√
部署描述符中可以设置多个欢迎页面
- A.×
- B.√2.00/2.00
ServletConfig对象只能在init方法中获取
- A.√
- B.×2.00/2.00
ServletConfig只能配置一对init-param参数
- A.√
- B.×2.00/2.00
Servlet init方法在其生命周期中只会被调用一次
- A.√2.00/2.00
- B.×
Servlet destroy方法在请求结束后会被调用
- A.×2.00/2.00
- B.√
ServletConfig中配置的参数可以在其它Servlet中获取
- A.√
- B.×2.00/2.00
Java开发工程师(Web方向) - 02.Servlet技术 - 第1章.Servlet的更多相关文章
- Java开发工程师(Web方向) - 02.Servlet技术 - 第3章.Servlet应用
第3章.Servlet应用 转发与重定向 转发:浏览器发送资源请求到ServletA后,ServletA传递请求给ServletB,ServletB生成响应后返回给浏览器. 请求转发:forward: ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第4章.JSP
第4章--JSP JSP JSP(Java Server Pages) - 中文名:Java服务器页面 动态网页技术标准 JSP = Html + Java + JSP tags 在服务器端执行,返回 ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 期末考试
Servlet课程考试 Servlet课程考试 Servlet课程考试 总分:55分 限定时间:120分钟 进入考试 答案已成功提交!请耐心等待成绩公布 Servlet课程考试: 1(12分) 简单谈 ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第1章.Spring概述
第1章.Spring概述 Spring概述 The Spring Framework is a lightweight solution and a potential one-stop-shop f ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第2章.Cookie与Session
第2章--Cookie与Session Cookie与Session 浏览器输入地址--HTTP请求--Servlet--HTTP响应--浏览器接收 会话(session):打开浏览器,打开一系列页面 ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第3章.AOP技术
第3章--AOP技术 Spring框架 - AOP概述 笔记https://my.oschina.net/hava/blog/758873Spring框架 - AOP使用 笔记https://my.o ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第2章.IoC容器
第2章.IoC容器 IoC容器概述 abstract: 介绍IoC和bean的用处和使用 IoC容器处于整个Spring框架中比较核心的位置:Core Container: Beans, Core, ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第5章.Web框架
第5章--Web框架 Web框架概述 Web框架单元测验 本次得分为:13.50/15.00, 本次测试的提交时间为:2017-09-25 1单选(2分) 关于Spring MVC中Dispatche ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第4章.数据访问
第4章--数据访问 Spring JDBC DAO (Data Access Object) 实现数据访问相关接口(接口和实现分离) ORM (Object Relation Mapping) 对象关 ...
随机推荐
- HDU 2031 进制转换(10进制转R进制)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2031 进制转换 Time Limit: 2000/1000 MS (Java/Others) M ...
- Springmvc+Spring+Mybatis整合开发(架构搭建)
Springmvc+Spring+Mybatis整合开发(架构搭建) 0.项目结构 Springmvc:web层 Spring:对象的容器 Mybatis:数据库持久化操作 1.导入所有需要的jar包 ...
- python3中sys.argv[]小记
1.python3中sys.argv[]用于传递程序外部的参数,外部一般指命令行输入的参数,argv[]所传递的参数实质上是一个列表,其第一个元素为程序本身. 2. sys.argv[] #传入的参数 ...
- SpringBoot整合Swagger2以及生产环境的安全问题处理
1.创建springboot项目 https://www.cnblogs.com/i-tao/p/8878562.html 这里我们使用多环境配置: application-dev.yml(开发环境) ...
- 解决IDEA打印到控制台的中文内容乱码
File-->Settings-->Editor-->File Encodings->将图中内容均设置为UTF-8--->点击+号选中自己的项目->Apply--& ...
- linux系统快速安装宝塔
宝塔面板分linux面板和windows面板,安装宝塔linux面板首先要访问宝塔官网查看对应版本进行选择 宝塔面板的安装需要注意的地方有: 1.纯净系统 2.确保是干净的操作系统,没有安装过其它环境 ...
- nginx 日志记录 自定义详解(分析上报用)
nginx 日志记录 自定义详解 1.log_format 普通格式 log_format main '$remote_addr - $remote_user [$time_local] $req ...
- 安装cronsun管理定时脚本
1. cronsun 是一个分布式任务系统,单个结点和 *nix 机器上的 crontab 近似.支持界面管理机器上的任务,支持任务失败邮件提醒,安装简单,使用方便,是替换 crontab 一个不错的 ...
- 大数据学习之Hadoop环境搭建
一.Hadoop的优势 1)高可靠性:因为Hadoop假设计算元素和存储会出现故障,因为它维护多个工作数据副本,在出现故障时可以对失败的节点重新分布处理. 2)高扩展性:在集群间分配任务数据,可方便的 ...
- MapReduce清洗日志数据统计PV量
package mapreduce.webpv; import java.io.IOException; import org.apache.commons.lang.StringUtils; imp ...