JavaWeb三大组件

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JavaWeb三⼤组件
1.javaweb三⼤组件:servlet,listener,filter;都需要在web.xml中配置(除了两个感知监听器)。

2.服务器端⼩程序每个Servlet都是唯⼀的,能处理的请求是不同的(⽐如登录,查询);前⾯的调度由tomcat完成;要完成获取请求数据,处理请求,完成响应的任务。

3.实现servlet的三种⽅法:javax.servlet.Servlet接⼝,GenericServlet抽象类(service⽅法待实现),HttpServlet类(常⽤)。

4.Servlet接⼝5⼤⽅法:其中3个⽣命周期⽅法不由我们来调⽤,由Tomcat调⽤;对象也不⽤我们来创建,Tomcat创建。

4.1:init(ServletConfig):⽣命周期⽅法,在对象创建之后只执⾏⼀次;当第⼀次被请求才被创建;
4.2:destroy():⽣命周期⽅法,在servlet对象被销毁之前调⽤,只调⽤⼀次;⽐如IO流等释放(很少);服务器被关闭时调⽤;
4.3:service(ServletRequest,ServletResponse):⽣命周期⽅法,被调⽤多次⽤来处理请求;
4.4:getServletConfig()(有⽤),getServletInfo()(⽆⽤)。

5.浏览器如何访问Servlet:必须把Servlet绑定到⼀个路径(web.xml配置):<servlet>name,class</servlet>,<servlet-mapping>name,url-pattern</servlet-mapping>,其中pattern必须/开头。

6.Servlet单例,线程不安全,效率⾼。

7.ServletConfig接⼝:对应的就是web.xml⾥的本Servlet的配置信息被xml解析器解析后,加载到⾥⾯;返回的实例的实现类是Tomcat提供的;
7.1:getServletName()(⼏乎没⽤);
7.2:getServletContext()(有⽤);
7.3:getInitParameter[Names()]:初始化参数相关
8.ServletRequest(Tomcat封装的请求信息),ServletResponse(设置状态码,设置响应头,发送html代码)。

9.GenericServlet抽象类:集成了很多ServletConfig的⽅法(实质也是调⽤ServletConfig的⽅法);注意init()的妙⽤(⾮⽣命周期⽅法与⽣命周期的⽅法链在⼀起);这个类的源代码可在Tomcat源码⾥看到。

10.HttpServlet类:是抽象类但没有抽象⽅法;在http包⾥,重载了两个service()⽅法,⼀个是⽣命周期⽅法,⼀个参数是HttpServletRequest;⽣命周期的service()会强制转换两个参数类型再调⽤⾮⽣命周期service()⽅法;⾮⽣命周期service()⽅法会根据request得到请求⽅式,分别调⽤doGet()或doPost()⽅法。

如果没覆盖着两个⽅法且被调⽤,出现405。

11.Myeclipse可直接右键新建Servlet,可⾃动⽣成web.xml配置以及⾃动列出要覆盖的⽅法。

12.Servlet细节:
12.1:servlet的线程安全问题:不要创建成员变量,创建局部变量即可;或者创建⽆状态成员变量;或者有状态成员变量但只读的;
12.2:服务器启动时即创建servlet,web.xml中配置<load-on-startup>即可(但很少有这种需求);
12.3:servlet-mapping的<url-pattern>可以写多个或者匹配多个(⽤*)(以前没有三⼤组件,⼀般Sevlet需要充当过滤器,所以需要多个路径)。

13.web.xml⽂件(了解):每个项⽬都继承⾃Tomcat⾥conf下的web.xml⽂件:
13.1:DefaultServlet,匹配/,优先级别最低,负责给出404;
13.2:JspServlet,匹配*.jsp,*jspx;
13.3:session-timeout配置,30分钟;
13.4:mime类型和其真实类型。

14.请求与实现:反射,通过url找名字,找到类名ClassForName,创建对象newInstace,调⽤⽅法getMethod;反射总是与配置相出现。

15.域对象:传递数据;javaweb四⼤域对象(作⽤域从⼩到⼤):PageContext,ServletRequest,HttpSession,ServletContext;JSP含有全部,Servlet只含其中3个。

15.1:ServletContext域,即application域,整个web应⽤都存在,可以在web.xml中配置初始值,接⼝可以访问服务器静态内容⽂件,线程不安全;
15.2:Httpsession域,即session域,在会话期间都存在,服务器为每个浏览器开辟专⽤内存,把会话号返回浏览器的cookie;
15.3:ServletRequest域,在请求存在,数据只使⽤⼀次的放在这⾥,⽐如servlet产⽣给jsp显⽰的数据;
15.4:PageContext域,即page域,作⽤在jsp页⾯。

16.ServletContext(重要):⼜名application;⼀个项⽬⼀个,可以在多个servlet之间传递数据;与Tomcat共存亡;
16.1:获得:通过ServletConfig或者GenericServlet类;HttpSession类,ServletContextEvent类;
16.2:内部是⼀个Map,存属性,取属性,移除属性等;演⽰在⼀个Servlet存,另⼀个Servlet读;
16.3:可以获取公共参数<context-param>,之前Servlet获取的只是为⾃⼰所⽤的局部参数;getInitParameter(String);
16.4:获取资源的真实路径(重要):得到有盘符的路径,getRealPath("/index.jsp");然后可以创建File类对象进⾏后续操作;
16.5:获取资源流:把资源以输⼊流的⽅式获取,getResourceAsStream("/a.txt");
16.6:获取指定⽬录下所有资源路径:getResourcePaths("/WEB-INF")。

不会进⼊⼦⽬录。

17.ServletContext应⽤:写⼀个Servlet,根据servletContext的特点,统计所有Servlet的访问量,再利⽤response对象向浏览器输出response.getWriter().print()。

18.获取类路径下的资源:/WEB-INF/classes和/WEB-INF/lib下每个jar包;注意src下的东西会拷贝到classes⽬录下;
18.1:相对/classes⽬录:this.getClass().getClassLoader();然后getResourceAsStream("a.txt");从流到字符串需要利⽤commons-io包的⼯具;
18.2:(复杂,不常⽤)相对class⽂件所在⽬录:this.getClass().getResourceAsStream("a.txt");/a.txt加了/则是相对于/classes⽬录;18.3:(不会这么⽤,有ServletContext.getRealPath("/index.jsp"))获取index.jsp内容:
this.getClass().getResourceAsStream("/../../index.jsp")。

19.BaseServlet:希望在⼀个Servlet写多个请求处理⽅法;⽤户发出请求给出参数确定调⽤的⽅法;⾃定义处理⽅法的函数签名要与service()相同;
19.1:service()中:从req.getParameter()获取⽤户指定的处理⽅法名;然后if-else判断执⾏;
19.2:接上,得到⽅法名,先获取当前对象,然后getMethod(⽅法名,参数类型)得到对象;调⽤method.invoke(this,req,resp);
19.3:接上,可以将反射的处理放到⼀个抽象类⾥然后被不同的Servlet继承,这样只需要实现不同的处理⽅法即可;
19.4:接上,若希望⾃定义⽅法处理完后实现转发或重定向,则在⾃定义⽅法返回String,在抽象类service()的invoke后加上判断逻辑;然后转发req.getRequestDispatcher(路径).forward(req,resp);重定向resp.sendRedirect(req.getContextPath()+path)。

-------------------------------------监听器------------------------------------
1.监听器:很少⽤;⽐如AWT⾥的ActionListener,XML解析的SAX;都是接⼝,⾥⾯放⾃定义的代码;需要注册;发⽣特定事件时执⾏;
2.观察者:事件源,事件,监听器(可能有多个⽅法)。

3.javaWeb中的监听器:事件源是三⼤域;每个域都有两个监听器:XXXListener(两个⽅法,事件是⽣和死),XXXAttributeListener(三个⽅法,事件为添加,替换和移除属性);
3.1:ServletRequest:请求动态资源即创建;
3.2:HttpSession:⼀个项⽬可有0或多个session;执⾏了req.getSession()就会创建;
3.3:ServletContext:服务器启动创建,服务器关闭销毁。

4.实现ServletContext⽣命周期监听器:
4.1:实现ServletContextListener接⼝;
4.2:在web.xml注册<listener>,写明实现类即可;
4.3:⽤处:放⼀些初始化数据库数据的代码,关闭的时候删掉这些临时数据;IOC这⾥放完成⼯⼚注⼊的代码。

5.上述⽅法的参数都有事件对象,如:ServletContextEvent对象,只有⼀个⽅法getServletContext();HttpSessionEvent对象,getSession()⽅法;都是汇报事件源⽤。

6.实现ServletContextAttributeListener属性监听器:
6.1:使⽤eclipse选择实现该接⼝,⾃动在web.xml⾥注册;
6.2:添加、修改、移除属性三个⽅法都有参数ServletContextAttributeEvent对象,getName(),getValue(),getServletContext()⽅法。

7.感知监听器HttpSessionBindingListener:添加到JavaBean上;与HttpSession相关;⽆需在web.xml中注册;感知⾃⼰是否被session添加或移除;
7.1:⽐如⼀个简单User类,实现了该接⼝的两个⽅法valueBound(HttpSessionBindingEvent)和
valueUnbound(HttpSessionBindingEvent);
8.感知监听器HttpSessionActivationListener:也是添加到JavaBean,还要实现Serializable接⼝;⽆需注册;能感知⾃⼰是否随session被钝化和活化
8.1:Session的序列化和反序列化:在服务器启停的时候发⽣;禁⽤该功能在Tomcat的conf的context.xml⽂件添加<Manager
pathname=""/>;
8.2:钝化和活化:太长时间不活跃的session从内存到磁盘;配置参数也是在context.xml(全局⽣效);活化后⽂件还存在;
8.3:两个⽅法sessionWillPassive(HttpSessionEvent)和sessionDidActivate(HttpSe ssionEvent);监听8.2的事件;
8.4:这个监听器基本没啥⽤。

----------------------------------过滤器---------------------------------
1.在⼀组资源(jsp,servlet,css,html等)前⾯执⾏;可以让请求获得资源,也可以不获得;拦截⼀组请求。

2.实现:实现Filter接⼝,在web.xml配置;单例的;
2.1:⽅法init(FilterConfig):服务器启动就创建,创建之后马上执⾏,初始化⼯作;
2.2:⽅法doFilter(ServletRequest,ServletResponse,FilterChain):
2.3:destroy():服务器关闭,⾮内存资源的释放,⼀般⽤不上;
2.4:配置:与servlet相同;⼀般<url-pattern>都含有*,;也可⽤<servlet-name>指定⼀个或多个具体的servlet。

3.相关类:
3.1:FilterConfig:与ServletConfig类似,获取过滤器名字,获取初始化参数和名字,获取ServletContext;
3.2:FilterChain:⽅法doFilter(ServletRequest,ServletResponse);放⾏。

4.多过滤器:FilterChain的doFilter()⽅法,表⽰执⾏⽬标资源或执⾏下⼀过滤器(如有)。

5.四种拦截⽅式:请求REQUEST;转发FORWARD;包含INCLUDE;错误ERROR;
5.1:配置:在<filter-mapping>⾥写<dispatcher>,指明上⾯四种之⼀,默认是请求;
5.2:错误是去往web.xml⾥配置的<error-page>的时候被拦截。

6.<filter-mapping>的放置顺序就是多个过滤器的执⾏顺序。

7.应⽤场景:考虑把多个Servlet都要执⾏的代码,放到Filter中;
7.1:预处理:设置编码req.setCharacterEncoding(),⼀般都放⾏;
7.2:条件判断:⽤户是否登录,IP是否禁⽤的判断;
7.3:后续处理:在⽬标资源执⾏后的处理,⽐如输出数据的处理,如动态页⾯静态化。

8.案例1:分IP统计⽹站的访问次数;
8.1:统计所有资源的访问,放在fliter;不做拦截;
8.2:统计数据放哪⾥?Filter要⽤,页⾯显⽰要⽤;整个项⽬就⽤同⼀个;ServletContext;
8.3:ServletContext的初始化在哪⾥?⽤监听器;在⾥⾯放⼀个统计ip的map;
8.4:材料:静态资源,filter,listener。

9.案例2:粗粒度权限控制;
9.1:细粒度控制,RBAC基于⾓⾊的权限控制;⽤户表,⾓⾊表,权限表,以及⽤户与⾓⾊对应的表,⾓⾊与权限对应的表;
9.2:判断有没有登录,总要使⽤到session;注意HttpServletRequest才能得到session,filter⾥只是ServletRequest;
9.3:只区分游客,会员和管理员:公共资源给所有⼈访问,会员资源放⼀个⽂件夹⼀个filter控制,管理员资源放⼀个⽂件夹被另⼀个filter控制;
9.4:材料:index.jsp,登录页⾯,会员资源,管理员资源;会员filter,管理员filter,登录校验Servlet(判断,在session放信息,回到index)。

10.案例3:解决全站字符乱码,所有资源的POST和GET访问都要解决;
10.1:POST乱码的处理(setCharacterEncoding()),GET乱码的处理(getParameter(),new String()),和响应内容乱码的处理;
10.2:这些公共处理代码放filter;但难点在于GET的处理:a.不知道Servlet获取的参数名字;b.设置完了不知道怎么回传给对应的Servlet;
10.3:解决GET:掉包request,写装饰类,增强getParameter(String);
10.3.1:实现HttpServletRequest接⼝,实现其所有⽅法;利⽤构造⽅法传⼊⼀个HttpServletRequest类型保存,然后利⽤其实现其他⽅法;
10.3.2:增强⽅法的写法和之前⼀样;
10.3.3:chain.doFilter()传⼊⾃⼰增强的req即可;
10.3.4:实现接⼝⿇烦,继承HttpServletRequestWrapper类,只需写getParameter(String)即可。

11.案例4:页⾯静态化;⽹站有⼀些内容是不变的不需要查数据库,⽐如书籍的类别;⾸次查询查数据库,保存到html,⼆次查询直接显⽰;
11.1:材料:link.jsp(查询所有,查询SE分类,查询EE分类...的链接);显⽰页⾯;BookService/Servlet;BookDao;Book实体;
11.2:步骤:创建数据库表;导⼊jar包;创建jsp;
11.3:BookServlet:继承BaseServlet,从req获得参数,调⽤Dao实现findAll(),findByCategory(),把结果req.setAttribute(),跳转到show.jsp;
11.4:BookDao:写sql语句并查询,返回List<Book>;
11.5:填充jsp,c3p0的xml⽂件配置数据库连接信息;
11.6:实现⼀个filter,把⾸次访问servlet的输出保存到html,再重定向到html;⼆次访问直接重定向,filter不再放⾏访问Servlet(判断);
11.7:准备⼀个⽂件夹放中间html;servletContext.getRealPath()得到的是带盘符的路径;req.getContextPath()得到的是项⽬名称;
11.8:输出页⾯是response的out,掉包,换getWriter(传html路径)流与html⽂件绑定⽽不是浏览器,继承HttpServletResponseWrapper,这样show.jsp在使⽤out的时候以为在写浏览器,其实写到中间⽂件;最后重定向到⾃⼰的中间⽂件;解决乱码也在show.jsp设置编码即可。

12.案例3和案例4都是利⽤filter的拦截特性,在chain.doFilter(req,resp)做⼿脚,传⼊⾃⼰改良的req对象或resp对象(装饰类)实现⾃⼰的功能。

相关文档
最新文档