JavaWeb组件(面试必看)

1.Servlet

Servlet是用来处理客户端请求的动态资源,也就是当我们在浏览器中键入一个地址回车跳转后,请求就会被发送到对应的Servlet上进行处理。
1.1 Servlet的任务有:
1)接收请求数据:客户端请求会被封装成HttpServletRequest对象,里面包含了请求头、参数等各种信息。
2)处理请求:通常我们会在service、dopost或者doget方法进行接收参数,并且调用业务层(service)的方法来处理请求。
3)完成响应:处理完请求后,我们一般会转发(forward)或者重定向(redirect)到某个页面,转发是HttpServletRequest中的方法,重定向是HttpServletResponse中的方法,两者是有很大区别的。
1.2 Servlet的创建:
Servlet可以在第一次接收请求时被创建,也可以在在服务器启动时就被创建,这需要在web.xml的< servlet>中添加一条配置信息 < load-on-startup>5< /load-on-startup>,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet,当是一个负数时或者没有指定时,则指示容器在该servlet被请求时才加载。

1.创建一个类实现Servlet接口
2.在web.xml文件中注册servlet(在web.xml文件中配置Servlet)
 
          <servlet>
              <servlet-name>别名</servlet-name>
              <servlet-class>全类名</servlet-class>
          </servlet>
 
          <servlet-mapping>
            <servlet-name>别名</servlet-name>        //对应的Servert
            <url-pattern>/requestadress</url-pattern>   //为Servlet映射一个请求地址   Servlet接受浏览器发给web服务器请求 要有请求地址
        </servlet-mapping>  
 
    客户通过浏览器发送请求给web服务器,如发送的请求为一个地址 如:/requestadress,在配置文件web.XML中会映射这个请求地址给 对应的Servlet(Servlet-name),web服务器通过Servlet-name对应的全类名创建一个Servlet实例 , 通过Servlet实例调用其service()方法完成数据的处理。

1.3 Servlet生命周期
Servlet的生命周期是指Servlet的对象由被创建到销毁的过程。
Servlet的生命周期方法:
1)构造器:
- Servlet第一次处理请求的时候调用,用于创建Servlet的实例,只会调用一次。
- Servlet是单例,同一个Servlet在服务器中只有一个对象,但是它是多线程的,效率高;
- 它是以多线程的方式调用service()方法,Servlet不是线程安全的,在service()中尽量不要操作全局变量。
2)init()
-构造器执行后,init马上被调用,用来做初始化操作,只会调用一次
-注意如果我们调用的是HttpServlet,那么他里面有两个init方法,如果要重写只能重写无参的方法。
3)service()
-每次处理请求时都会调用service方法,它用来处理用户发送的请求,会调用多次
-如果我们通过继承HttpServlet实现Servlet,我们只需重写doGet或doPost
4)destroy()
-Servlet对象销毁之前调用,用来做一些收尾工作吗,只会调用一次。

1.4 ServletConfig接口
每一个Servlet都有其唯一对应的ServletConfig,ServletConfig代表Servlet的配置信息,具体来说就是servlet标签中的内容

 <servlet>
          <servlet-name>Servlet3</servlet-name>
          <servlet-class>com.atguigu.servlet.Servlet3</servlet-class>
          <init-param>(初始化参数)
                  <param-name>username</param-name>
                  <param-value>root</param-value>
 
          </init-param>
   </servlet>

1.5 ServletContext接口
代表整个的web应用,每一个web应用都有其唯一的ServletContext对象,ServletContext对象在服务器启动时创建,在服务器停止时销毁
获取:通过ServletConfig的getServletContext()方法获取

1.6 HttpServletRequest接口
request代表浏览器发送给服务器的请求报文
获取:由服务器创建(服务器将请求报文封装为HttpServletRequest对象),最终作为参数传递到doGet或doPost方法中。
功能:
1)获取浏览器发送的请求参数
2)动态的获取项目的名字(主要用来设置绝对路径)
3)作为一个域对象在不同web资源之间共享数据
4)请求的转发

1.7 HttpServletResponse接口
代表服务端发送浏览器的响应报文
获取:由服务器创建(服务器将响应报文封装为HttpServletRsponse对象),最终作为参数传递到doGet或doPost方法中。
功能;
1)可以向浏览器发送一个页面或页面片段
2)做请求的重定向
3)将数据写到页面

1.8 转发和重定向的区别
在这里插入图片描述
两种跳转获得对象的方式

//获得转发对象getRequestDispatcher()
HttpServletRequest(httpServletRequest).getRequestDispatcher
ServletContext.getRequestDispatcher();
 
//获得重定向对象sendRedirect()
HttpServletResponse(httpServletResponse).sendRedirect();

转发和跳转的小结
1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
2、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;
3、转发是服务器行为,重定向是客户端行为;
4、转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

转发和重定向的选择
1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。
2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

转发和重定向的应用场景
在上面我已经提到了,转发是要比重定向快,因为重定向需要经过客户端,而转发没有。有时候,采用重定向会更好,若需要重定向到另外一个外部网站,则无法使用转发。另外,重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作。

例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动作;这在一个真实的应用程序中,很有可能将表单中的所有产品信息加入到数据库中。但是如果在提交表单后,重新加载页面,执行保存的方法就很有可能再次被调用。同样的产品信息就将可能再次被添加,为了避免这种情况,提交表单后,你可以将用户重定向到一个不同的页面,这样的话,这个网页任意重新加载都没有副作用; 但是,使用重定向不太方便的地方是,使用它无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。由于重定向经过客户端,所以Model中的一切都会在重定向时丢失。但幸运的是,在Spring3.1版本以后,我们可以通过Flash属性,解决重定向时传值丢失的问题。

要使用Flash属性,必须在Spring MVC的配置文件中添加一个。然后,还必须再方法上添加一个新的参数类型:org.springframework.web.servlet.mvc.support.RedirectAttributes。
如下所示:

@RequestMapping(value="saveProduct",method=RequestMethod.POST)
public String saveProduct(ProductForm productForm,RedirectAttributes redirectAttributes){
 
     //执行产品保存的业务逻辑等
  
     //传递参数
       redirectAttributes.addFlashAttribute("message","The product is saved successfully");
   
     //执行重定向
      return "redirect:/……";
}

1.9 Servlet的线程安全性?
Servlet不是线程安全的
当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。

在这里插入图片描述
上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。

1.10 Servlet实现线程安全的三种方式
(1)在Servlet中不使用全局变量.
Servlet线程安全问题很大部分是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。将实例变量编程局部变量,多线程下每个线程对局部变量都会有自己的一份copy,这样对局部变量的修改只会影响到自己的copy而不会对别的线程产生影响,线程安全的。**Java 内存模型中,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。**但是对于实例变量来说,由于servlet在Tomcat中是以单例模式存在的,所有的线程共享实例变量。多个线程对共享资源的访问就造成了线程不安全问题。

(2)同步共享的数据,使用synchronized(this){//共享数据.}同步块.
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。

(3)实现SingleThreadModel接口.
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。

2.Filter

2.1 Filter简介
filer是javaweb中的过滤器,它与servlet一样,也有三个生命周期方法,同时在web.xml的配置也差不多.但是两者的主要功能不同,servlet负责处理请求,filter负责拦截请求和放行.可以实现Url级别的权限访问,敏感词汇过滤,解决编码问题等等.

2.2 filter实现原理
Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
(1)调用目标资源之前,让一段代码执行。
(2)是否调用目标资源(即是否让用户访问web资源)。
(3)调用目标资源之后,让一段代码执行。
web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,我们可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

2.3 filter的四种拦截方式
REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、jsp:forward标签都是转发访问;
INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、jsp:include标签都是包含访问;
ERROR:当目标资源在web.xml中配置为 error-page中时,出现异常后,转发到目标资源时,会执行过滤器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值