1.Servlet 学习大纲
- servlet 概念以及相关接口简介
- servlet 执行过程
- servlet 路径映射
- 缺省servlet --应用
- servlet生命周期
- servlet自动加载
- servlet线程安全
8)servletConfig 对象
9)servlet相关接口详情 - servletContext对象 --知识点
Servlet就是Controller, 需要在web.xml
中配置它。
2.手动导入Jar包:
相对于maven而言。
参考:
https://www.oschina.net/question/2005688_166884
先把下载的jar包复制到WEB-INF/lib下,然后需要:打开 File -> Project Structure -> Modules -> Dependencies ->绿色 加号 -> 1. Jars + dep....
3.如何去开发一个servlet?
步骤:
1)编写一个java类,继承于HttpServlet类
2)重写doGet和doPost方法
3)servlet程序交给tomcat服务器运行!
3-1:servlet程序的class 码拷贝到WEB-INF/classes目录中
3-2:在web.xml文件中进行配置
4.web.xml
中配置servlet:
Servlet中的映射路径:
url-pattern | 浏览器输入
精确匹配:
/first | http://localhost:8080/first
/ypd/first | http://localhost:8080/ypd/first
模糊匹配:
/* | http://localhost:8080/任意路径
*.后缀名 |
*.do |
*.action |
*.html (伪静态) |
注意:不能同时使用2种模糊匹配。
当有输入的url有读个servlet同事被匹配的情况下:
精确匹配优先(长的最像有限被匹配)
以后缀名(eg:*.do, *.html)结尾的模糊匹配优先级最低!
注意: /*
等同于 /
。 servlet缺省路径,是tomcat内置的一个路径。该路径相对应的是一个DefaultServlet(缺省servlet)。这个缺省的servlet的作用是用于解析web应用的静态资源文件。
web.xml
配置的映射路径优先级要高些。
url中输入http://localhost:8080/index.html 如何访问文件??
- 首先到当前目录下的web.xml文件查找是否有匹配的url-pattern。如果匹配到,就调用。
2)如果没有匹配到,则交给tomcat的内置的DefaultServlet去处理。
3)DefaultServlet 程序到应用的根目录下查找是否存在一个名为index.html的静态文件。如果找到该文件,则读取改文件内容,返回给浏览器。
eg:
FirstServlet
com.ypd.web5.FirstServlet
FirstServlet
/first
要注意:Servlet的class一定要是public class的,否则不能访问。
前提:tomcat 服务器启动时,首先加载webapps中的每个web应用的配置文件 web.xml
servlet向浏览器输出信息:
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
// 向浏览器输出内容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("this is my servlet");
}
}
注意:如果不写response.setContentType("text/html;charset=UTF-8");
这一句,有的时候回报405
错。
5.servlet实现
通过反射:
a) 构造Servlet对象
b) 然后调用servlet中的方法
6.一个项目中要么是动态文件要么是静态文件。
静态文件:index.html
动态文件:servlet
先找动态的,再找静态文件。
7.servlet的生命周期(重点):
servlet的生命周期就是servlet类对象什么时候创建,调用什么方法,什么时候销毁,销毁的时候又做了什么事情。
servlet程序的生命周期是由tomcat服务器控制的。
servlet 方法
1)构造方法:
public LifeDemo() {
2)init方法
public void init(ServletConfig config) throws ServletException {
3)service 方法
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
4)destory 方法
public void destroy() {
构造方法:创建servlet对象的时候调用。第一次访问ervlet的时候创建。
init
方法:创建完servlet对象的时候。
service
方法:每次发出请求时候调用。
destory
方法:销毁servlet对象时候调用。停止服务器或者重新部署web应用的时候。
4个方法全部都是由服务器决定的。
8.servlet的自动加载
默认情况下,第一次访问servlet时候创建servlet对象。如果servlet的构造方法或者init方法中执行了比较多的逻辑代码,那么导致用户第一次访问servlet的时候比较慢。
改变servlet创建对象的时机:提前加载web应用的时候。
在servlet的配置信息(web.xml
)中,加上一个
即可。就会在tomcat服务器启动的时候自动加载。
注意,其中的1
,数值越大,优先级越低。
servlet是单例。
servlet在tomcat中的运行机制是:单实例多线程。
如果多个线程同事访问了servlet对象的共享数据(成员变量)可能会引发线程安全问题。
synchronized (ThreadDemo.class) { // 锁对象必须是唯一的。ThreadDemo.class 也就是这个servlet的类对象,是唯一的。
}
因为servlet是多线程的,所以当多个servlet的线程同事访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。
解决方法:
1)把使用到共享数据的代码块进行同步(synchronized)
2)建议在servlet类中尽量不要使用成员变量。因为synchronized
会等待,尽量少用。哪里使用到了成员变量,那里就同步,以避免因为同步而导致并发效率降低。
Servlet 学习:
HttpServletRequest 请求对象: 获取请求信息
HttpServletResponse 响应对象: 设置响应对象
ServletConfig对象: servlet配置对象
ServletContext对象: servlet的上下文对象
9.ServletConfig对象:
作用:主要用于加载servlet的初始化参数。
创建和得到:
创建的时机:在创建servlet对象之后,在调用init方法之前创建。
得到ServletConfig:直接从有参数的init方法中得到。
servlet的初始化参数配置:
ServletConfig的API。
ServletConfig是对应的:
ConfigDemo
com.ypd.config.ConfigDemo
path
/Users/leo/Downloads/图片1.png
其中的
的信息。
String path = config.getInitParameter("path"); // 这里获取path
File file = new File(path);
因为有封装,我们可以直接拿来用。
this.getServletConfig() // 就获得了config对象
10.ServletContext对象
ServletContext:servlet上下文对象,表示一个当前的web应用环境。一个web应用中,只有一个ServletContext。ServletConfig可以有多个。
ServletContext创建和获取:
创建:在加载web应用时候,创建对象。
得到:从ServletConfig的getServletContext方法得到。
Sun公司设计:
1)先创建ServletConfig对象: ServletContext context = new ServletContext;
2)再创建ServletConfig对象: ServletConfig config = new ServletConfig(); config.setServletContext(context);
class ServletConfig {
ServletContext context;
public ServletContext getServletContext() {
return context;
}
}
所以,ServletContext是从ServletConfig中取得的。
注意;
有了 this.getServletConfig()
, 下面就可以不写了。
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
}
11.ServletContext的作用:
ServletContext对象的核心API(作用):
- getContextPath()
得到web应用路径: 也就是部署到tomcat服务器上面的web应用名称
ServletContext context = this.getServletConfig().getServletContext(); // 也可以this.getServletContext(); 后者推荐。点击查看源码的话,也就是前者。
注意:修改了web.xml
的文件后,运行ItelliJ IDEA 的debugger后, 需要选择Restart Server。如果只是修改了jsp,servlet等java代码,可以不选择Restart Server,只选择Update classes and resources.
应用到请求重定向:
String contextPath = this.getServletContext().getContextPath();
response.sendRedirect(contextPath + "/index.html");
12.配置web应用参数,也叫上下文参数。
注意:IntelliJ IDEA 的输出 System.out.prsintln()
快捷键是:sout
注意:两种配置参数的区别
ContextA
ContextA's value
和
ConfigDemo
com.ypd.config.ConfigDemo
path
/Users/luowensheng/Downloads/图片1.png
aaa
aaa's value
前者是全局的,后者是局部的。
13.域对象(重点):
域对象:作用用于保存数据和获取数据。可以在不同的动态资源中共享数据。
域对象就是一个对象。域对象就是存数据的容器。
案例:(将Servlet1的name=eric共享给Servlet2)
Servlet1 Servlet2
name=eric
方案1:(传参)
response.sendRedirect("/Servlet2?name=eric") request.getParameter("name") 获取
局限:自能传递字符串类型。
如果想要传递对象就不可以了。
方案2:(域对象)
可以共享任意类型数据。
ServletContext
就是一个域对象,可以完成数据共享。
共享数据,有2个动作,一个是保存,另外一个是获取。还可以删除数据。
Servlet1中,保存数据:
// 1.得到域对象,ServletContext也是域对象
ServletContext context = this.getServletContext();
// 2.把数据保存到域对象中
context.setAttribute("context_demo3_name", "eric"); // 注意也可以保存对象。
Servlet2中,取出数据:
ServletContext context = this.getServletContext();
String context_demo3_name = (String)context.getAttribute("context_demo3_name");
可以使用removeAttribute(名称)
移除。
ServletContext域对象:作用范围在整个web应用中都有效。
所有域对象:
HttpServletRequest域对象
ServletContext域对象
HttpSession域对象
PageContext域对象
RequestDispatcher.forward()方法将当前的request和response重定向到该 RequestDispacher指定的资源。// 也就是重定向页面,传递request和response参数。
例子:
1)转发
// 转发。实现的效果和重定向是一样的。
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/index.html");
rd.forward(req, resp);
还有一种重定向方法:
2)重定向
String path = this.getServletContext().getContextPath(); // 这句就是获取当前应用的根目录
resp.sendRedirect(path + "/index.html");
两者区别:
1)前者的浏览器地址栏保留之前的,后者的浏览器地址栏会变化为新的。(转发地址栏不会改变,重定向地址栏会改变)
2)转发只能转发当前web应用的资源,不能转发到当前web应用以外的资源。重定向可以访问到其他应用的资源。(比如:https://www.baidu.com都可以的)
3)最重要的,转发可以通过HttpServletRequest
来传递对象(request.setAttribute),重定向不能。
因为:重定向的原理是,立刻响应一个302和location给用户。重定向的request和setAttributes的request不是同一个。
结论:如果要使用request域对象进行数据共享,只能使用转发技术,不能使用重定向技术。
request.getRequestDispatcher方法的作用是什么?
这一步之前的工作是对提交的request做处理,这一步(这句话)是表示:处理完了,分发到下一个JSP页面或者下一个Action继续处理。
会有forward()和redirect()两种情况,forward()是request中的参数继续传递,redirect()则是重新生成request了。