Servlet(创建、使用、生命周期、http协议、http请求、http响应、过滤器)

目录

一.作用

二.servlet生命周期

创建无参构造

初始化 init

服务 service

销毁 destory

三.http协议

1.简介

2.http请求

2.1前端发送请求

2.2跨域

什么是跨域?

为什么浏览器要限制跨域访问?

为什么要跨域?

解决跨域问题的方法

3.http响应

四.过滤器

1.作用

2.实现Filter接口中的三个方法


一.作用

  • 接收用户发送的请求(请求头,请求行,请求体)

  • 调用程序处理

  • 将结果响应给客户端(状态码)

二.servlet生命周期

什么时候创建,什么时候销毁,在各阶段调用的方法

创建无参构造

默认是第一次访问servlet程序;

可通过配置在服务器启动时创建  :<load-on-startup>  值>=0  </load-on-startup>

初始化 init

在构造方法执行完后紧接着执行,初始化servlet,只调用一次;

用来执行一些初始化操作,读取文件中的数据

服务 service

每次客户端的请求都会调用service方法

销毁 destory

在正常关闭服务器时

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
    HttpServlet是javaEE中的一个类,我们的Servlet处理类必须继承此类,
    这样就具备了Servlet程序功能,启动服务器时,就会加载这些继承了HttpServlet的类

    在哪里规定的调用顺序:
        在最上层定义了一个Servlet接口,所有的Java EE(实现了该接口的类)都按照此规范执行
 */
public class LoginServlet_back extends HttpServlet {

    /*
       无参构造方法,初始化创建的对象
       在第一次访问这个Servlet时或服务器启动时被调用了,只调用了一次
     */
    public LoginServlet(){
        System.out.println("LoginServlet无参构造方法");
    }


    /*
       在构造方法执行完成后,紧接着来执行,用来初始化servlet,只调用了一次,
       如果没有初始化的需要,也可以不进行重写,那么会调用父类中init().
     */

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init"+config.getInitParameter("count"));
    }


    /*
      为前端提供服务的,每次访问servlet程序,service方法都会执行, 多次执行
     */

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service");
    }


    /*
        在服务器关闭时会被调用,可以在服务器关闭时执行一些必要的操作,
        此方法可以在我们的类中不重写,会调用父类中destroy()
     */
    @Override
    public void destroy() {
        System.out.println("destroy");
    }


}

三.http协议

1.简介

http协议(HyperText Transfer Protocol超文本传输协议)是网络模型中应用层协议,用来规定浏览器和服务器之间如何传输超文本内容.也基于 tcp/ip协议 ,客户端与服务器之间交互必须是建立连接.

2.http请求

a.当浏览器连接到服务器后,向服务器发送的请求,称为http请求.

一个http请求包含3个部分:

-------------------------------------------------------------------------------------------------------------------------
              请求行: 请求的地址,http版本,状态码 都是由浏览器自动处理
              请求头: 客户端的一些信息,都是由浏览器自动处理,以键值对方式向后端发送,键都是固定的
              请求体:表单post方式提交的数据区域,请求体中参数以键值形式传递;

                          多个用&链接,服务器接收后再解析。

http请求又分为get请求方式和post请求方式

-------------------------------------------------------------------------------------------------------------------------
            get:  
               超链接请求是get;
               地址栏直接访问是get;
               get主要用来从服务器端获取数据;
               向服务器端传输数据量小,并且在地址栏会显示;
               后端地址?键=值&键=值.
            post:
            表单提交post方式提交数据;
            主要用于从前端向后端传输大量数据(可以上传文件);
            不在(url)地址栏显示,数据存放在请求体中,相对安全.

b.在Servlet中,HttpServletRequest表示请求​​​​​​​

由于前端发送的http请求有get和post两种,故后端提供doGet()和doPost()进行对应的处理。
虽然调用doGet()和doPost(),但构造方法,init,service,gestroy方法仍然正常执行。
当servlet中无需初始化的内容时,可不重写init(),但服务器依然会调用父类中的重写的init().
父类中已经重写了service(),并会根据请求方式进行判断【get-->doGet(),post-->doPost()】
当servlet中无需最终执行的操作时,可不重写destroy(),但服务器依然会调用父类中的重写的destroy()。

当一次http请求发送到服务器时,tomcat会将请求中所有的数据,都封装到一个实现HttpServletRequest类的对象中.
使用此对象,就可以获取所有的请求数据.
req.getMethod();//得到客户端请求方式
req.getScheme();//请求协议
req.getLocalAddr();//获取远端的IP和端口
tomcat8之后
post (数据在请求体中),如果有中文,乱码;
get  有中文,正常输出;

因此:post数据接收前,需设置一个解码规则:
      req.setCharacterEncoding("utf-8");

但为了避免多次反复写解码代码,造成代码冗余,我们可以通过过滤器实现解码效果。

2.1前端发送请求

        1.表单像后端发送请求,属于同步请求

                发一个请求,给一个回应,回应的内容会覆盖浏览器的内容,这样会打断前端其他的正常操作,不友好。

        2.异步请求  

                可使用一个js提供的对象向后端发送请求,会被js对象接收,然后在js中,用接收到的内容局部更新网页,此过程整个页面不会更新;

前后端交互出现跨域问题:属于前端问题;

前端服务页面中(8848)接收后端服务器响应的数据(8080)【跨域】,使用Ajax技术前后端交互,前端默认会进行阻止,为了安全,不让前端服务接收其他后端的数据;

协议、域名、端口有一个不同就属于跨域问题;

跨域问题解决:前端解决/后端解决:在响应头中设置说明,告知浏览器,此次响应是可靠的。

2.2跨域

什么是跨域?

跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。只要协议,域名,端口有任何一个的不同,就是跨域.

为什么浏览器要限制跨域访问?

安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题:

1.用户访问www.mybank.com ,登陆并进行网银操作,这时cookie啥的都生成并存放在浏览器

2.用户突然想起件事,并迷迷糊糊地访问了一个邪恶的网站 www.xiee.com

这时该网站就可以在它的页面中,拿到银行的cookie,比如用户名,登陆token等,然后发起对www.mybank.com 的操作。

3.如果这时浏览器不予限制,并且银行也没有做响应的安全处理的话,那么用户的信息有可能就这么泄露了。

为什么要跨域?

公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。

解决跨域问题的方法

1.前端解决

        这里不做解释

2.后端

跨域资源共享(CORS)

服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许ajax进行跨域的访问。

只需要在后台中加上响应头来允许域请求!在被请求的Response header中加入设置,就可以实现跨域访问了!

创建过滤器实现后端设置允许跨域访问。

 <!--配置允许跨域的响应-->
    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.ffyc.webback.filter.CorsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern><!--配置哪些请求地址进入到过滤器-->
    </filter-mapping>
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


public class CorsFilter implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        //允许携带Cookie时不能设置为* 否则前端报错
        httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域
        httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等
        httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie

        filterChain.doFilter(servletRequest, servletResponse);
    }
}

3.http响应​​​​​​​

a.服务器向客户端回送的数据称为响应

 b.HttpServletResponse

服务器接收到客户端的每个http请求,会分别创建HttpServletResponse对象代表响应。

getWriter() :获得一个PrintWriter字符输出流输出数据;

-------------------------------------------------------------------------------------------------------------------------

response.setContetnType("text/html;charset=utf-8");

或者

response.setHeader("Content-Type,"text/html;charset=utf-8");

方法可以同时设定response所使用的字符集编码和浏览器打开所用的字符集编码

四.过滤器

在请求进入到servlet之前,可以配置哪些请求进入到指定的过滤器,完成一些公共的处理。

1.作用

对服务器web资源进行拦截;

减少代码冗余,提高可维护性

● Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。

2.实现Filter接口中的三个方法

●init(FilterConfig filterConfig):对filter对象进行初始化,只在容器初始化filter对象结束后被调用一次。参数 FilterConfig可以获得filter的初始化参数。

● doFilter(ServletRequest request, ServletResponse response, FilterChain chain):filter进行过滤操作的方法。过滤器实现类必须实现该方法。方法体中可以对request 和response进行预处理。其中FilterChain可以将处理后的request 和response对象传递到过滤链上的下一个资源。

● destroy():该方法在容器销毁过滤器对象前被调用。

import javax.servlet.*;
import java.io.IOException;

/*
    编码过滤器
*/
public class EncodFilter implements Filter {
/*可不重写init()和destroy(),会调用父类中的*/

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        //System.out.println("编码过滤器");
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        //filterChain过滤链,处理完后让请求继续向下执行,下一个可能是目标servlet,也可能是下一个过滤器
        filterChain.doFilter(servletRequest,servletResponse);

    }
}
<!--配置编码过滤器-->
    <filter>
        <filter-name>encodFilter</filter-name>
        <filter-class>com.ffyc.webback.filter.EncodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encodFilter</filter-name>
        <url-pattern>/*</url-pattern><!--配置哪些请求地址进入到过滤器-->
    </filter-mapping>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小谭同学ha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值