1.什么是Servlet?
JavaServlet是运行在WEB服务器上或应用服务器上的程序,它是作为来自WEB浏览器或者其他HTTP请求客户端和请求和HTTP服务器上的数据库或者应用程序的中间层(处理http请求与响应)
2.启动web服务器时Servlet做了什么事情(tomcat为例)
tomcat是一个web应用服务器,是一个Servlet/Jsp容器,tomcat作为Servlet的容器,负责把收到来自于web的请求传送给Servlet,并负责把Servlet的响应传送给客户端,而Servlet是运行在支持JAVA语言的服务器上的组件
tomcat将http请求文本接收并解析,然后封装成HttpServletRequest类型request对象,所有http请求头数据可通过request对象调用对应的方法的获取到
tomcat同时会将响应信息封装成HttpServletResponse类型response对象,通过response属性就可以控制输出到浏览器内容,然后将response交给tomcat,tomcat会将其变成响应文本格式发送给浏览器
3.详解创建Servlet创建原理
3.1servlet的生命周期
3.2为什么创建servlet是继承HttpServlet,而不是实现Servlet接口
3.3在servlet的生命周期中是执行service方法,为什么我们只需要写dopost和doget方法
3.1servlet的生命周期是什么?
当web.xml的load-on-startup大于等于0时,服务器启动时就会初始化一个Servlet对象,也就是执行init(ServletConfig,conf)方法
当web.xml的load-on-startup不设置或者小于0,在第一次请求时会初始化一个Servlet对象
初始化的Servlet对象会去处理所有来自客户端的请求,在service(ServletRequest req, ServletResponse res)里执行
最后服务器关闭时才会销毁这个对象,执行destroy()方法
3.2在创建Servlet时候是去继承HttpServlet类,而不是实现Servlet接口
3.3在初始化对象去处理请求的时候调用的是service方法,为什么我们只需要写dopost和doget方法
public class TestControl extends HttpServlet
public abstract class HttpServlet extends GenericServlet
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
由类关系我们可知,HttpServlet继承了GenericServlet,GenericServlet实现了Servlet接口
Servlet接口中主要定义了三个方法:init(ServletCobnfig, conf) service(ServletRequest req, ServletResponse res) destroy ()方法
getServletConfig()主要是获取ServletConfig对象,ServletConfig对象可以获取到servlet一些信息
因此Servlet接口的作用是三个生命周期运行方法,获取ServletConfig方法,通过ServletConfig可以获取到ServletContext,通过继承GenericServlet我们就可以使用Servlet的方法,能拿到ServletConfig,也可以拿到ServletContext,那样太麻烦了,所以我们可以看到GenericServlet也直接实现了ServletConfig接口,这样我们也就直接就可以拿到ServletContext信息
在GenericServlet中有两个init方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
一个成员变量
private transient ServletConfig config;
getServletConfig()
public ServletConfig getServletConfig(){return config}
在init(ServletConfig config)方法中,为了方便在其他地方亦可以使用ServletConfig对象,而不仅仅局限在init(ServletConfig,config)方法中,所以创建了一个私有成员变量config,在init(ServletConfig config)方法中就将其赋值给config,然后通过getServletConfig()方法就能够获取ServletConfig对象了,但是在init(ServletConfig config)中还调用了一个
init()方法,并且这个init()方法是空的,什么读也没有,这是为什么呢?
当我们需要在init方法中做一点别的事情,我们想到的方法就是继承GenericServlet中init(ServletConfig config)方法,这样依赖,
就破坏了原本在GnereicServlet类中的init(ServletConfig config)写的代码,也就是在GenericServlet类中成员变量config就一直
是null,无法得到赋值,因为被重写了,就不会在执行GenericServlet中init(ServletConfig config)方法中代码。要想赋值就必须在重写init(ServletConfig config)方法中调用父类的init(ServletConfig config)方法,也就是super.init(ServletConfig config),这样依赖,就很不方便。所以在GenericServlet类中增加了一个init()方法,以后需要在init方法中需要初始化别的数据,只需要重写init()方法,而不需要去覆盖(ServletConfig config)这个方法。
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
在GenericServlet类中并没有实现service方法,而想到的是他的子类实现了,那就是HttpServlet
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
从HttpServlet代码我们可以知道将传过来的ServletRequest强制转换成了HttpServletRequest类型,ServletResponse强制转换成了HttpServletRespnse类型
该方法主要是去执行判断是那种请求方法一般是get或者post,然后调用到相应请求方式函数中,这样我们就知道了写Servlet时为什么只需要重写dopost或者doget方法
四、几大重点对象讲解:
ServletConfig对象(通过getServletConfig获取):
getServletName():获取Servlet名称,在web.xml中的Servlet-name
getInitParameter():获取Servlet对象初始化参数的值,获取的是在web.xml中Servlet节点下init参数的值
getInitParameterNames():获取Servlet中所有初始化参数的名字,返回的是枚举类型
ServletContext对象:获取方式getServletContext(),或者getServletConfig.getServletContext()我们只需要使用第一种就行
功能:tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web配置公共信息等,通俗来说,就是一个web项目,就存在一个ServletContext实例,每个Servlet都可以访问他。
1、web项目中共享数据,getAttribute(String name)\setAttribute(String name, Object obj),removeAttribute(String name)
setAttribute(String name, Object obj)在web项目中范围内存放内容以便让在web项目中所有的Servlet都能访问
2.整个web项目初始化参数(全局参数),每个Servlet都能获取到该初始化值
getInitParameter(String name) 通过指定名称获取初始化值
getInitParameterNames()获取枚举类型
web.xml配置整个web项目的初始化
3、获取web项目资源
3.1获取web项目下指定的资源路径:getServletContext().getRealPath("/WEB-INF/web.xml")
3.2获取web项目下指定资源的内容,返回的是字节输入流。InputStream getResourceAsStream(java.lang.String.path)
等等。。
request对象:将请求文本封装成的对象,所以通过request能获得请求文本的所有内容,请求头、请求体、请求行
1、请求行内容获取
实际访问路径 http://localhost:8080/day08/Demo05Servlet?username=jack&password=1234
统一资源标记符:String uri = request.getReuqestURI() (/day8/Demo05Servlet)
统一资源定位符:StringBuffer url = request.getRequestURL()( http://localhost:8080/day08/Demo05Servlet)
协议和版本: String protocol = request.getProtocol()(HTTP/1.1)
协议:String scheme = request.getScheme()(http)
主机(域名) : String serverName = request.getServerName()(localhost)
端口: int port = request.getServerPort()(8088)
发布到tomcat下的项目名称:String contextPath = request.getContextPath()
Servlet路径: String servletPath = request.getServletPath()(/Demo05Servlet)
所有请求参数:String queryString = request.getQueryString()(username=jack&password=1234)
远程主机ip地址: String remoteAddr = request.getRemoteAddr()
2.请求头获取
String getHeader(java.lang.String name)获取指定头内容String
long getDateHeader(java.lang.String name) 获得指定头内容Date
int getInitHeader(java.lang.String name)获得指定头内容int
Enumeration getHeaders(java.lang.String name)获取指定名称所有内容
3请求体获取(GET/POST)
String request.getParameter(String)获得指定名称,一个请求参数值
String[] request.getParameterValues(String)获得指定名称,例如checkbox,select等
Map<String, String[]> request.getParameterMap()获得所有的请求参数
4.请求转发
request.getRequestDispatcher(String path).forward(request,response); //path:转发后跳转的页面,这里不管用不用“/”开头,都是以web项目根开始,因为这是请求转发,请求转发只局限在=与在同一个web项目下使用,所以这里一直都是从web项目根下开始的
web项目根:
开发:G:\Workspaces\test01\WebRoot\...
运行时:D:\java\tomcat\apache-tomcat-7.0.53\webapps\test01\
web站点根:
运行时:D:\java\tomcat\apache-tomcat-7.0.53\webapps\
从这里可以看出,web项目根就是从该web项目名开始,所以我们请求转发时,只需要接着项目名后面需要访问路径写就行了
特点:浏览器中的url不会改变,也就是浏览器不知道服务器做了什么,是服务器帮我们跳转页面,并且转发后的页面,能够继续使用原先的request,因为是原先的request,所以request域中的属性都可以继续获取到
response对象:
常用的一个方法就是:response.setHeader(java.lang.String name, java.lang.String value)设置指定的头,一般常用
例如:设置每隔3秒就自动刷新一次
response.setHeader('Refresh',3)
重定向(页面跳转)
方式一:response.setStatus(302); //状态码302就代表重定向response.setHeader('location','http://www.baidu.com')
方式二:使用封装好的,通过response.sendRedirect('http://www.baidu.com')
特点:服务器告诉浏览器要跳转的页面,是浏览器主动去跳转的页面,浏览器知道,也浏览器的地址栏中url会改变,是浏览器重新发起一个请求道另外页面页面,所以request是重新发起的根请求转发不一样
注意:response.sendRedirect(path)
response.sendRedirect('/test01/MyServlet01');使用了‘/’开头表名从web站点根开始
response.sendRedirect('MyServlet'); 没有使用'/'开头,说明是从web项目根开始,所以无需写test01
参考文章地址:https://www.cnblogs.com/whgk/p/6399262.html