Tomcat设置热配置:修改文件后不用重启Tomcat服务器。
Tomcat设置虚拟路径
Servlet:Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
具体内容由我们自己实现,在浏览器可以调用Servlet的实现类的方法。
配置Servlet
1、 在web.xml中配置:
demo1
cn.itcast.web.servlet.ServletDemo1
demo1
/demo1
2、使用注解配置:
Servlet 3.0之后支持使用的方式就可以配置了,注解写在Servlet的实现类中,资源路径就是url-pattern中的内容。
WebServlet注解内容:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";//相当于
String[] value() default {};//代表urlPatterns()属性配置,默认就是这个
String[] urlPatterns() default {};//相当于
int loadOnStartup() default -1;//相当于
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
三、Servlet的生命周期
1. 被创建:执行init方法,只执行一次
* Servlet什么时候被创建?
* 默认情况下,第一次被访问时,Servlet被创建
* 可以配置执行Servlet的创建时机。
* 在
1. 第一次被访问时,创建
2. 在服务器启动时,创建
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题。
解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值
- 提供服务:执行service方法,执行多次
- 每次访问Servlet时,Service方法都会被调用一次。
- 被销毁:执行destroy方法,只执行一次
- Servlet被销毁时执行。服务器关闭时,Servlet被销毁
- 只有服务器正常关闭时,才会执行destroy方法。
- destroy方法在Servlet被销毁之前执行,一般用于释放资源
四、Servlet的执行原理
Servlet不需要主方法就能执行,因为用到了反射的技术。
五、Servlet的继承结构:
Servlet -- 接口:
实现Servlet接口的实现类,五个抽象方法都得实现。
|
GenericServlet -- 抽象类:
空实现了其余四个抽象方法,继承该抽象类只需要实现service()即可。
|
HttpServlet -- 抽象类:
对HTTP协议进行了封装、空实现了五个方法、只需要重写doGet/doPost方法即可、根据请求的方式来执行不同的代码。
六、HTML协议
1.HTML协议是基于TCP/IP协议的一种高级协议
2.默认端口号是:80
3.基于请求、响应模型:一次请求对应一次响应
4. 无状态的:每次请求之间相互独立,不能交互数据
HTML协议1.0版本,每次请求响应都会建立一个新的连接,显然这样是影响性能的。
HTML协议1.1版本、复用连接
请求消息的格式
请求行
请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1
请求头
客户端通过请求头的键值对,告诉服务器一些信息。
常见的请求头的内容:
- User-Agent:告诉服务器一些浏览器的版本等信息。
在服务器端获取User-Agent,可以解决兼容性的问题。 - Referer:告诉服务器,这个连接是从哪里来的。
1.防止别的网站(盗版网站)盗取链接使用。
2.可以进行统计流量的来源。
请求空行
用来分隔请求体与请求头的,注意:只有POST请求方式有请求体。
请求体
封装POST请求消息的请求参数的
关于GET方式与POST方式
1、请求方式:
直接访问网页资源是GET方式,表单中设置POST方式,再提交后才是POST方式。
GET方式与POST方式的区别:
GET
1、get是相当于是明文传输,且url长度有限制,根据浏览器不同限制的长度不同。
2、填入表单的请求参数会显示到地址栏后面、不太安全。
3、没有请求体。POST
1、post的请求参数在请求体中,不是明文传输
2.、请求的url长度没有限制的
3.、相对安全
七、Request对象与Response对象
request对象和response对象的原理
- request和response对象是Tomcat服务器给我们创建的。
- request对象是来获取请求消息,response对象是来设置响应消息做出回应的。
1、Request对象(请求)
Request对象的继承结构:
ServletRequest -- 接口
| 继承
HttpServletRequest -- 接口
| 实现
org.apache.catalina.connector.RequestFacade 类(tomcat)
获取请求行的数据的方法
请求行中的数据有:请求方式、请求的URL、HTTP协议版本信息
- 1、获取请求方式:
String getMethod() - 2、获取URL中的虚拟路径的方法:
String getContextPath() - 3、获取Servlet资源路径: (常用)
String getServletPath() - 4、获取get方式的请求参数:
String getQueryString() - 5、获取URI路径
String getRequestURI(): (常用) - 6、获取URL路径
StringBuffer getRequestURL()
- 7、获取HTTP协议版本:
String getProtocol() - 8、获取客户机的IP地址:
String getRemoteAddr()
获取请求头中的数据
- 1、(常用)String getHeader(String name):通过请求头的名称获取请求头的值
- 2、Enumeration
getHeaderNames():获取所有的请求头名称
获取请求头的数据(使用流)
步骤:
- 1、BufferedReader getReader():获取字符输入流,只能操作字符数据 。
- 2、ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
- 3、使用流对象,获取数据。
POST方法和GET方法都可以使用的、获取请求参数的方法(常用)
-
- String getParameter(String name):根据参数名称获取参数值
-
- String[] getParameterValues(String name):根据参数名称获取参数值的数组
-
- Enumeration
getParameterNames():获取所有请求的参数名称
- Enumeration
-
- Map
getParameterMap():获取所有参数的map集合
- Map
关于请求参数乱码问题:
Q:为什么会出现乱码?
A:request对象是Tomcat创建的,所以解析请求参数使用的是Tomcat的编码集iso-8859-1,但是浏览器使用的是html设置的编码集(utf-8),所以就乱码了。
目前Tomcat 8 已经解决了get方法的乱码问题,但是post方法依然还会乱码。
需要我们自己设置编码集。
request.setCharacterEncoding("utf-8");
2.Response对象(响应)
响应消息与请求消息的格式类似:
- 响应行
内容:协议/版本 响应状态码 状态码描述- 状态码分类:
- 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
- 2xx:成功。代表:200
- 3xx:重定向。代表:302(重定向),304(访问缓存)
- 4xx:客户端错误。 代表: 404(请求路径没有对应的资源)、405:请求方式没有对应的doXxx方法 (例如post方式的请求,却没有doPost方法。)
- 5xx:服务器端错误。代表:500(服务器内部出现异常)
- 状态码分类:
- 响应头
- 常见响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式。
- Content-disposition:服务器告诉客户端以什么格式打开响应体数据。
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体。文件下载
- 常见响应头:
- 响应空行
用于分隔响应头与响应体的。 - 响应体
用于传输数据
Response对象是用来设置响应消息的。
①、设置响应行
- 设置状态码:setStatus(int sc)
②、设置响应头 - setHeader(String name, String value)
③、设置响应体 - 获取Tomcat提供的输出流对象,向响应体中写数据,输出到浏览器。
- PrintWriter getWriter()、获得字符输出流(打印流)
- ServletOutputStream getOutputStream()、获得字节输出流
关于输出乱码问题:
Q:为什么会乱码?
A:因为输出流对象是Tomcat给的,编码集是Tomcat设置的ISO-8859-1,浏览器解析请求体是用的系统的编码集(GBK),所以对应不上就乱码了。
解决方法:
- 1.设置流的编码集:
response.setCharacterEncoding("utf-8"); -
- 设置浏览器解析的编码集:
response.setHeader("content-type","text/html;charset=utf-8");
- 设置浏览器解析的编码集:
两步合一的简便方法:
- response.setContentType("text/html;charset=utf-8");
重定向:
步骤:
- 1.设置状态码为302、
response.setStatus(302); - 2.设置重定向地址、由响应头中的location头指定:
response.setHeader("location","重定向的地址");
一步设置重定向:
- response.sendRedirect("重定向的地址");
重定向(redirect)与请求转发(forward)的区别:
- 重定向
- 地址栏会发生改变
- 可以重定向到服务器外的资源
- 重定向是两次请求、重定向不能由request域共享数据。
- 请求转发
- 地址栏不会改变
- 只能转发到当前服务器中的资源
-
转发是一次请求、转发可以由request域共享数据。
八、请求转发:服务器内部的资源访问
步骤:
- 通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path) - 使用RequestDispatcher对象来进行转发:
forward(ServletRequest request, ServletResponse response)
特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中。
- 转发是一次请求
九、路径的虚拟目录的使用情况
规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
-
1、给客户端浏览器请求资源使用:需要加虚拟目录(项目的访问路径)
- 建议虚拟目录动态获取:request.getContextPath()
- 重定向:因为是客户端请求的。
-
2、 给服务器请求资源使用:不需要加虚拟目录
- 转发路径:因为是服务器请求的。
十、共享数据——域对象
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:一次请求的范围,一般用于请求转发的多个资源中共享数据
1、向域对象中存储数据:
void setAttribute(String name,Object obj)
2、通过键获取值:
Object getAttitude(String name)
3、通过键移除键值对
void removeAttribute(String name):
十一、ServletContext:代表整个web应用
如何获取?
- 通过request对象获取:request.getServletContext();
- 通过HttpServelet获取:this.getServletContext();
作用:- 1.获取MIME类型
- 什么是MIME类型?一种互联网通信过程中定义的文件数据类型。
格式为: 大类型/小类型
例如:text/html、image/jpeg
context.getMimeType(String file)
- 什么是MIME类型?一种互联网通信过程中定义的文件数据类型。
- 2.作为域对象
因为ServletContext对象是整个web应用,所以所有的servlet资源都能访问到存在ServletContext对象中的数据,比较的不安全。
相比request域对象的范围是一次请求经过的servlet、ServletContext的范围太大了。
ServletContext对象的生命周期很长,从服务器启动到服务器关闭。
- 1.获取MIME类型
- 3.获取文件的真实(服务器)路径
在之前获取的文件都是默认在src路径下的,使用ClassLoader就能获取。
但是ClassLoader并获取不了web路径下的文件。
这时就需要ServletContext对象来获取了。
String b = context.getRealPath("/a.txt");//web目录下资源访问
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\a.txt
String c = context.getRealPath("/WEB-INF/b.txt");//WEB-INF目录下的资源访问
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\WEB-INF\b.txt
String a = context.getRealPath("/WEB-INF/classes/c.txt");//src目录下的资源访问
D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded\WEB-INF\classes\c.txt
服务器路径是:D:\ideaProject\basic-code\out\artifacts\Servlet_Response_war_exploded
(本地)工作空间路径是:D:\ideaProject\basic-code\Servlet-Response