Servlet

1.Servlet 学习大纲

  1. servlet 概念以及相关接口简介
  2. servlet 执行过程
  3. servlet 路径映射
  4. 缺省servlet --应用
  5. servlet生命周期
  6. servlet自动加载
  7. servlet线程安全
    8)servletConfig 对象
    9)servlet相关接口详情
  8. 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 如何访问文件??

  1. 首先到当前目录下的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服务器启动的时候自动加载。

Servlet_第1张图片
图片.png

注意,其中的1,这个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(作用):

  1. 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不是同一个。

Servlet_第2张图片
图片.png

结论:如果要使用request域对象进行数据共享,只能使用转发技术,不能使用重定向技术。

request.getRequestDispatcher方法的作用是什么?

这一步之前的工作是对提交的request做处理,这一步(这句话)是表示:处理完了,分发到下一个JSP页面或者下一个Action继续处理。
会有forward()和redirect()两种情况,forward()是request中的参数继续传递,redirect()则是重新生成request了。

你可能感兴趣的:(Servlet)