JavaWeb学习三(细解Servlet和ServletContext)

xiaoxiao2021-02-27  505

一.Servlet细节

1.Servlet与线程安全

因为一个类型的Servlet只有一个实例对象,那么就有可能,会出现一个Servlet同时处理多个请求,那么Servlet线程不安全,但效率高,但也存在线程安全问题

不要在Servlet中创建成员,创建局部变量即可可以创建无状态成员 ,User user=new User();可以创建有状态的成员,但状态必须是只读的User方法内不能有set

2.让服务器在启动时就创建Servlet

<load-on-startup>0</load-on-startup>//在<servlet>中配置<load-on-startup> 其中给出一个非负整数 public class AServlet extends HttpServlet { @Override public void init() throws ServletException { System.out.println("Servlet已经创建成功"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } <servlet> <servlet-name>AServlet</servlet-name> <servlet-class>cn.st.web.servlet.AServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AServlet</servlet-name> <url-pattern>/AServlet</url-pattern> </servlet-mapping>

访问此Servlet效果如下图 可以看出,servlet是服务器启动完成前就创建了

3.<url-pattern>

<url-pattern>是<servlet-mapping>的子元素,用来指定Servlet的访问路径,即URL,它必须是以/开头
(1).可以在<servlet-mapping>中给出多个<url-pattern>
<servlet-mapping> <servlet-name>AServlet</servlet-name> <url-pattern>/AServlet</url-pattern> <url-pattern>/BServlet</url-pattern> </servlet-mapping>

访问以AServlet或者以BServlet结尾的都可以

说明一个Servlet绑定两个URL,无论访问/AServlet还是/BServlet,都是访问的AServlet
(2).还可以在<url-pattern>中使用通配符,所谓通配符就是星号,星号可以匹配任何URL前缀和后缀

使用通配符可以命名一个Servlet绑定一组URL,例如

a.路径
<servlet> <servlet-name>BServlet</servlet-name> <servlet-class>cn.st.web.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BServlet</servlet-name> <url-pattern>/BServlet/*</url-pattern> </servlet-mapping>

/servlet/a,/servlet/b都匹配/servlet/*

b.扩展名
<servlet> <servlet-name>BServlet</servlet-name> <servlet-class>cn.st.web.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>

/abc/deg/ghi.do,/a.do都匹配

c.啥都匹配
<servlet> <servlet-name>BServlet</servlet-name> <servlet-class>cn.st.web.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>

匹配所有URL

4.web.xml文件的继承

每个完整的javaweb应用中都需要有web.xml,但我们不知道所有的web.xml都有一个共同的父文件,在tomcat下的conf\web.xml中的内容,相当于写到了每个项目的web.xml中,它是所有web.xml的共同的”父类”

<servlet-name>default</servlet-name> //它的优先级最低,如果一个请求没有人处理,那么它就来处理,返回404 <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> //当访问路径不存在时,会执行该Servlet,其实我们在访问index.html时也在执行这个Servlet

5.Servlet与反射

Tomcat在对于web.xml中<servlet-class>这里采用了反射的机制来实现的,其实对于以后很多web项目,配置底层是通过反射实现的会有很多很多的,所以我们要打好基础!!!!!

Class.forName(servlet的class); getMethod("servlet",ServletRequest.class,ServletResponse.class); invoke方法

二.ServletContext

1.ServletContext概述

一个项目只有一个ServletContext对象我们可以在N多个Servlet中来获取这唯一的对象,使用它可以给多个Servlet传递数据与天地同寿,这个对象在Tomcat启动时就创建,在Tomcat关闭时才会死去

ServletContext对象的作用是在整个web应用的动态资源之间共享数据!例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了!

2.获取ServletContext

获取ServletContext一共有4种方法,如下:

ServletConfig getServletContextGenericServlet getServletContextHttpSession getServletContextServletContextEvent getServletContext

在Servlet中获取ServletContext对象:

在void init(ServletConfig config)中: ServletContext context=config.getServletContext();

在GenericeServlet或HttpServlet中获取ServletContext对象

GenericServlet类有getServletContext()方法,所以可以直接使用this.getServletContext()来获取 public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context1=this.getServletConfig().getServletContext(); ServletContext context2=this.getServletContext(); System.out.println(context1==context2); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

访问这个Servlet打印出true,证明了在一个项目中只有一个ServletContext对象

3.域对象的功能

(1).域对象的定义
就是用来在多个Servlet中传递数据域对象必须有要存数据功能域对象必须有取数据功能
(2).javaweb四大域对象
ServletContextPageContextServletRequestHttpSession
(3).ServletContext对于存储数据的方法
void setAttribute(String name,Object value):用来存储一个对象,也可以称之为存储一个域属性,Map存储 Object getAttribute(String name):用来获取ServletContext中的数据void removeAttribute(String name):用来移除ServletContext中的域属性Enumeration getAttributeNames():获取所有域属性名称

4.获取应用初始化参数

Servlet也可以获取初始化参数,但它是局部的参数,也就是说,一个Servlet只能获取自己的初始化参数,不能获取别人的,即初始化参数只为一个Servlet准备可以配置公共的初始化参数,为所有Servlet所用,这需要使用ServletContext <servlet> <servlet-name>BServlet</servlet-name> <servlet-class>cn.st.web.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BServlet</servlet-name> <url-pattern>/BServlet</url-pattern> </servlet-mapping> <context-param> <param-name>context-name</param-name> <param-value>context-value</param-value> </context-param> public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context=this.getServletContext(); String name=context.getInitParameter("context-name"); System.out.println(name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

访问这个Servlet控制台打印出

context-value

5.获取资源相关的方法

ServletContext().getRealPath(String name):它得到的是有盘符的路径 public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path=getServletContext().getRealPath("/index.jsp"); System.out.println(path); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

访问此Servlet,控制台打印

E:\javaweb_work\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\javaweb2\index.jsp ServletContext().getResourceAsStream(String name):获取资源的路径后,再创建出输入流对象 public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream io=getServletContext().getResourceAsStream("/index.jsp"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } ServletContext().getResourcePaths(String name):获取当前路径下所有资源的路径,返回的是一个Set集合 public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Set<String> set=getServletContext().getResourcePaths("/WEB-INF"); for(String path:set) { System.out.println(path); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

控制台打印

/WEB-INF/lib/ /WEB-INF/classes/ /WEB-INF/web.xml

6.练习:访问量统计

一个项目中所有的资源被访问都要对访问量进行累加!创建一个int类型的变量,用来保存访问量,然后保存到ServletContext的域中,这样可以保存所有得Servlet都可以访问到!

最初时 ServletContext中没有保存访问量相关的属性当本站第一次被访问时 创建一个变量 设置其值为1 保存到ServletContext终当以后访问 就可以从ServletContext中获取这个变量 然后在其基础之上加1 public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext application=getServletContext(); Integer count=(Integer)application.getAttribute("count"); if(count==null) { count=1; }else { count++; } response.setContentType("text/html;charset=utf-8");//防止乱码 response.getWriter().print("你已经访问了"+count+"次"); application.setAttribute("count",count); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

7.获取类下的资源

获取类路径资源,类路径对一个javaweb项目而言就是WEB-INF下面的classer和WEB-INF/lib每个jar包

在这个包下新建一个a.txt文件

里面添加上这些

public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ClassLoader classLoader=this.getClass().getClassLoader(); //得到ClassLoader,先得到Class,再得到ClassLoader InputStream io=classLoader.getResourceAsStream("cn/st/web/servlet/a.txt"); //调用其getResourceAsStream(),得到InputStream String result=IOUtils.toString(io);//要导入io包 System.out.println(result); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

控制台打印出txt里面的东西了

public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ClassLoader classLoader=this.getClass().getClassLoader(); InputStream io=classLoader.getResourceAsStream("cn/st/web/servlet/a.txt"); String result=IOUtils.toString(io); System.out.println(result); Class class1=this.getClass(); InputStream io2=class1.getResourceAsStream("/../../index.jsp"); String result2=IOUtils.toString(io2); System.out.println(result2); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

控制台不仅打印出了txt中的内容,还打印出了index.jsp里面的代码内容

转载请注明原文地址: https://www.6miu.com/read-113.html

最新回复(0)