目录
一.作用
-
接收用户发送的请求(请求头,请求行,请求体)
-
调用程序处理
-
将结果响应给客户端(状态码)
二.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>