Servlet基础
Servlet是什么?
详情请看这个链接什么是Servlet
我感觉理解起来挺好的。
Servlet的执行过程
Servlet运行在服务器上,浏览器发送请求给服务器,服务器中的Servlet程序,响应浏览器的请求,根据请求的内容来访问数据库或者做出响应。
Servlet的生命周期
四个状态:实例化,初始化,服务,销毁
出生:(实例化–>初始化)第一次访问Servlet就出生(默认情况下)
活着:(服务)应用活着,servlet就活着
死亡:(销毁)应用卸载了servlet就销毁。 停止服务器的时候
public class HelloServlet implements Servlet{
//出生:第一次访问Servlet会调用构造方法
public HelloServlet() {
System.out.println("创建了对象");
}
//出生:第一次访问Servlet会调用初始化请求
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("初始化");
}
//服务:做出相应,每次访问都会调用Service
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("服务的Service");
res.getWriter().write("Hello Servlet");
}
//销毁死亡:程序停止时调用
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("销毁");
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}
Servlet的创建时机
默认情况下Servlet在第一次使用Servlet时才创建
可以在web.xml中设置load-on-startup为2,Servlet就会启动Tomcat时调用构造方法和初始化方法
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.echo.web.servlet.HelloServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
Servlet实现的三种方式
第一种:实现javax.servlet.Servlet接口 如上述代码 少用
public class HelloServlet implements Servlet{
...
}
第二种:继承javax.servet.GenericServlet类(适配器模式:选择性的实现某些方法) 少用
public class HelloServlet2 extends GenericServlet{
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
res.getWriter().write("HelloServlet2");
}
}
第三种:继承javax.servlet.http.HttpServlet类(模板方法设计模式) 常用
public class HelloServlet3 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
resp.getWriter().write("HelloServlet3..");
}
}
Servlet GenericServlet HttpServlet 三者的关系
Servlet是一个接口
GenericServlet是Servlet的实现类
HttpServlet是GenericServlet的子类
Servlet映射
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
url-pattern:
*.com
*.com 以.com结尾的字符串的请求都可以访问 是一个通配符,代表任意字符串 注意这种写法前面不能加/
/.com会报错
/*
所有字符串都可以访问,万能访问,没有限制
/echo/hello
代表加了个前缀,访问时要加前缀/echo/hello http://localhost:8080/Hello/echo/hello
加前缀可以起到划分模块的作用
映射匹配优先级
HelloServlet1
/hello
http://localhost:8080/Hello/hello如果要匹配它
先精准匹配 匹配 /hello
没有的话再模糊匹配/*
http://localhost:8080/Hello/echo/hello.com
会先模糊匹配/*
如果没有模糊匹配 就会访问hello.com
ServletContext
什么是ServletContext?
参见一位大佬的博客ServletContext介绍及用法
ServletContext代表的是整个应用,一个应用只有一个ServletContext对象,是单例对象
作用:
域对象:在一定范围内(当前应用),使多个Servlet共享数据
常用方法:
void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
Object getAttribute(String name);//从ServletContext对象的map中取数据
void rmoveAttribute(String name);//根据name去移除数据
@WebServlet("/Lesson01Servlet1")
public class Lesson01Servlet1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
//1.获取一个应用的servlet上下文
ServletContext context = this.getServletContext();
System.out.println(context);
//aaa@qq.com
//2.往上下文存数据
context.setAttribute("name", "echo is beautiful");
}
}
@WebServlet("/Lesson01Servlet2")
public class Lesson01Servlet2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
//1.获取一个应用的servlet上下文
ServletContext context = this.getServletContext();
System.out.println(context);
//aaa@qq.com
//2.取servlet上下文的数据
String name = (String)context.getAttribute("name");
System.out.println(name);
//echo is beautiful
}
}
@WebServlet("/Lesson01Servlet3")
public class Lesson01Servlet3 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
//1.获取一个应用的servlet上下文
ServletContext context = this.getServletContext();
System.out.println(context);
//aaa@qq.com
//2.移除servlet上下文的数据
context.removeAttribute("name");
}
}
三个Servlet应用程序 公用一个ServletContext
获取全局配置信息
@WebServlet("/Lesson02Servlet1")
public class Lesson02Servlet1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//掌握通过上下文对象从web.xml中获取全局配置信息
/**
* 注意:在web.xml中context-param配置的信息不是通过getAttribute()方法获得的
* 而是通过.getInitParameter()方法
* 本例是为了说明,可以在某个servlet中通过调用上下文对象来实现从xml获取全局属性
*/
//String s = (String) this.getServletContext().getAttribute("encoding");
String s = (String) this.getServletContext().getInitParameter("encoding");
System.out.println("web.xml中获取的值 : " + s);
}
}
获取资源路径
@WebServlet("/Lesson03Servlet1")
public class Lesson03Servlet1 extends HttpServlet{
/**
* 通过浏览器地址栏进行访问的都是get请求 发出get请求到服务器后 通过servlet的doGet方法进行处理
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* ServletContext的String getRealPath(String path)方法
* 1.根据资源名称得到资源的绝对路径
* 2.可以得到当前应用的任何位置的任何资源
*/
//在Servlet中获取info.properties数据
//1.创建属性对象
Properties pro = new Properties();
//2.关联属性文件的路径
//String path = "src/com/echo/web/lesson03/info.properties";
//上述路径是不对的,因为Servlet在运行时会自动打包。
//web项目,查找文件时,要从类路径找
//.getRealPath()获取绝对路径
String path = this.getServletContext().getRealPath("WEB-INF/classes/com/echo/web/lesson03/info.properties");
System.out.println(path);
//G:\JavaProject\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\day09-20180317\WEB-INF\classes\com\echo\web\lesson03\info.properties
pro.load(new FileInputStream(path));
System.out.println(pro.getProperty("username"));
//解决乱码
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
//响应客户端
resp.getWriter().write(path);
resp.getWriter().write("-----");
resp.getWriter().write(pro.getProperty("username"));
}
}
Servlet转发
@WebServlet("/Lesson04Servlet1")
public class Lesson04Servlet1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* request:请求
* response:响应:给客户端返回数据
*/
//解决乱码
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
//resp.getWriter().write("来自servlet1的数据");
//1.获取请求转发对象
RequestDispatcher rd = req.getRequestDispatcher("/Lesson04Servlet2");
//2.执行转发
rd.forward(req, resp);
/**
* 转发过程:浏览器请求Servlet1 servlet1收到响应之后 创建一个请求转发对象 然后执行转发
* 将请求转发到servlet2之后 servlet2响应请求,执行响应
*/
}
}
@WebServlet("/Lesson04Servlet2")
public class Lesson04Servlet2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* request:请求
* response:响应
*/
//解决乱码
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().write("来自servlet2的数据");
}
}
本人才疏学浅,这些记录大部分来源于老师所讲,用作记录及时提醒自己,若有谬误之处,还望各位大神指正海涵。
。。。。
其实也没人看。。。。