controller 一般都是使用Servelet实现控制器,
Servelet:是一个Java 类,处理请求和发送响应的一个过程,为了实现动态页面(开发一个Java程序向浏览器输出数据)而衍生出来的,符合一定的规范,也就是说如果一个类符合一定规范,那么这个类就是一个Servelet这个类就是
public class WelcomeServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("do get 2");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("do post 2");
}
}
理解这个得前提是理解一些http协议,和B/S 模式(浏览器/服务器),浏览器/服务器,浏览器通过网址来访问服务器
Tomacat和servlet的关系:
Tomcat是Web应用服务器,是一个Servlet/JSP 容器,Tomcat作为Servlet容器,负责处理客户请求,把请求传送给Servelt,并将servlet的响应传送会客户,而servlet是一种运行在支持Java语言的服务器上的组件,Servlet至于常见的应用是扩展Java web 服务器功能。
浏览器发送的是一个请求文本,接受到的也是一个响应文本,
以上的步骤是:
Java Servlet API 就是Servlet容器(tomcat)和servlet之间的接口,它定义了servlet各种方法,还定义了servlet容器传送给servlet的对象类,其中最重要的就是ServletRequest和ServletResponse,所以我们在编写servlet 的时候,需要实现servlet接口,按照其规范来操作。
Servelet的使用
Servelet2.5: 必须配置web.xml
Servelet3.0 :@WebServlet
第一种配置文件的方式:
web.xml 内容:
View 种的标签:
WelcomeServlet
上面当点击view 中的
后面会发送的事情如下:
以上的执行过程:
项目中的web和src 都是项目的根目录,当index发出一个请求的时候,首先会在web目录下找对应的响应,然后再去src目录下扫描对应的响应。
如果讲url改为, 在web目录或者src目录找a目录,然后再a目录中找对应的响应
jsp中的/ 代表服务器的根路径
web.xml 中的/ 代表项目的根路径
servlet生命周期: 加载(servlet 容器自动处理) -> 初始化-> 服务(重点) -> 销毁 -> 卸载(servlet 容器自动处理)
服务: 抽象service()方法 (doGet doPost)
初始化: init()方法,该方法在servlet 被加载并实例化以后执行
销毁: destroy servlet 被系统回收的时候会执行
第一次访问servlet的时候,init 和 service 都会触发(可以设置为服务器启动的时候触发
@WebServlet(value = "/WelcomeServlet", loadOnStartup = 1)
),当第二次触发的时候就只会触发service,调用几次就会触发 几次 service,当在关闭服务器的时候就会去调用 destroy 方法,
Servlet API, 由两个软件包组成,对应于HTTP协议的软件包,以及非HTTP协议意外的其他软件包,我们学习的servlet,是为javax.servlet.http 包中的类和接口,是基础的http协议。
servlet 的继承关系
HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
HttpServlet继承了GenaricServlet方法,这是一个通用的Servlet接口实现的抽象通用类,而Servlet接口有以下几个方法
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
这里可以看见servlet生命周期的三个关键方法,init、service、destroy还有就是 getServletConfig()方法来获取ServletConfig对象,ServletConfig对象可以获取到Servlet的一些信息,ServletName、ServletContext、InitParameter、InitParameterNames、通过查看ServletConfig这个接口就可以知道
public interface ServletConfig {
String getServletName();
ServletContext getServletContext();
String getInitParameter(String var1);
Enumeration getInitParameterNames();
此外GenericServlet除了实现Servlet接口外,还实现了ServletConfig接口,那样,就可以直接获取ServletContext了。
GenericServlet中实现了Servlet 中的实现了Servlet 中的方法,但是可以发现有的方法实现了2遍,有空实现
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
这样的实现是有一定的好处的,在正常初始化的时候(并不需要重写用户的init方法及加上用户的逻辑)当继承了GenericServlet的时候就会调用带有参数的init方法,并将config赋值,上面可以看见还有一个getServletConfig的方法,在其他地方也就可以获取得到这个congfig并使用,但是当用户需要重写nit方法及加上用户的逻辑的时候,如果没有这个init() 方法,那么在GenericServlet 中就不会再去执行init(config) 方法了(被重写了),所以在其他地方执行getServletConfig获取到的就是null 了,而由这个init() 方法就可以避免这个问题了,因为用户重写的init()方法是而不是init(config),所以在GenericServlet中init(cofig) 方法还是可以初始化config 的。
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
这个方法并没有被实现,且参数还是ServletRequest,ServletResponse。并没有跟http相关对象挂钩,所以我们接着往下面看。
继续看HttpServlet 实现类:继承了GenericServlet类,通过我们上面的推测,这个类主要的功能肯定是实现service方法的各种细节和设计。并且通过类名可以知道,该类就跟http挂钩了。
该方法中就做一件事情,就是将ServletRequest和ServletResponse这两个对象强转为HttpServletRequest和HttpServletResponse对象。为什么能这样转?首先要知道req、res是什么类型,通过打印System.out.println(req),可以知道,req实际上的类型是org.apache.catalina.connector.RequestFacade
httpServletRequest和HttpServletResponse对象之后,在调用
service(HttpServletRequest req, HttpServletResponse resp)方法, 而这个方法就是会判断请求来的具体是哪个方法,没每种的处理方法也是不一样的,我们常用的就是get,post,所以这里就回到了我们上面编写servlet时的情况,继承httpServlet,而只要重写两个方法,一个doGet,一个doPost,其实就是service方法会调用这两个方法中的一个(看请求方式)。
3.0 的方式给当前servlet设置初始值,但是只是属于当前的某一个servlet,无法为整个web容器设置初始化参数,任然需要在web.xml 中配置。
param-name
param-value
httpServletRequest 中的方法通request 中的方法是一致的, 如, setAttribute(), getCookies(), getMethod()
相同的 httpServletResponse 也是的。
几个重点的对象。ServletConfig、ServletContext,request、response
ServletConfig :
getServletName(); //获取servlet的名称,也就是我们在web.xml中配置的servlet-name
getServletContext(); //获取ServletContext对象,该对象的作用看下面讲解
getInitParameter(String); //获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的只是在该servlet下的初始化参数,web.xml 中的配置:
使用:
ServletContext
获取途径:getServletContext(); 、getServletConfig().getServletContext();
tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web配置公共信息等,通俗点讲,就是一个web项目,就存在一个ServletContext实例,每个Servlet读可以访问到它。
web项目中共享数据,
setAttribute(String name, Object obj) 在web项目范围内存放内容,以便让在web项目中所有的servlet读能访问到
getAttribute(String name) 通过指定名称获得内容
removeAttribute(String name) 通过指定名称移除内容
整个web项目初始化参数 //这个就是全局初始化参数,每个Servlet中都能获取到该初始化值
getInitPatameter(String name) //通过指定名称获取初始化值
getInitParameterNames() //获得枚举类型
web.xml 配置 整个web项目的初始化,需要通过web.xml 配置
request 对象
request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行 。
String getHeader(java.lang.String name) 获得指定头内容String【】
long getDateHeader(java.lang.String name) 获得指定头内容Date
int getIntHeader(java.lang.String name) 获得指定头内容int
Enumeration getHeaders(java.lang.String name) 获得指定名称所有内容
3请求体的获取 -- 请求参数的获取
分两种,一种get请求,一种post请求
get请求参数:http://localhost:8080/test01/MyServlet?username=jack&password=1234
post请求参数: