Java Web 控制客户端访问视图

本文探讨了在JavaWeb开发中实现权限控制的方法,包括基于控制器的访问限制、视图级别的保护策略及通过配置文件(web.xml)实现的安全控制。此外还介绍了JSP与Servlet的工作流程与生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

             在java web中关于处于权限问题,要许多关于Web客户端访问的权限框架,其实他的实质也就是通过根据一定的业务规则,允许客户端访问特定的资源视图的而已。实质也开发者自定义业务逻辑通过标签和控制器控制访问一样。但是某些安全框架,基于业务方法的安全访问就必须采用AOP或者反射实现相关的权限控制了。

       可能针对特定客户端对特定资源的访问的,如限制或者控制客户端访问的原因之一例如:用户登录可能有更多的访问的某一个特定的视图时,或者视图的某一个特定的部分只能被特定的某种角色用户访问时,据出现控制客户端的视图问题。

             无论处于那种情况,处于保护资源视图,要么用户看到部分视图,要么用户看不到视图。

 

 

实现保护视图的策略如下:

 (1)加入一种应用逻辑,每当控制器或者视图被处理时,就运行这一个逻辑。从而限制用户。

 (2)可以配置运行时系统,在某些资源被访问之前,必须要通过另一种一个用资源的内部调用才能完成。例如通过采用控制器作为这种访问控制的一个委派点,另一种委派实在视图中直接加入保护。

 

在视图内部中实现保护:

  (1)阻塞对整个资源的访问

           A。  这种情况最好采用集中在控制器里处理,这样代码便于管理和修改。

           B。但是很有一种不推荐的方式就是哦在每一个页面顶部加入一个定制的自定义标签助手,用以完成安全访问检查。

  (2)只阻塞对局部资源的访问。

          此种情况最好采用定制的自定义标签助手实现比较简单易于管理。

 

 

 

通过配置实现保护特定角色访问的视图:

      为了限制客户端直接访问特定的视图,可以配置表现层引擎,比如web容器,通过可以利用配置(web.xml)来限制对特定的资源访问。Servlet2.2以上版本,web容器要内置实现一些安全机制,可以利用这些机制来完成配置保护。安全控制是通过部署描述符(web.xml)来定义。

 

 

    Servlet技术规范规定,基于认证身份方法以及易于表单的身份认证方法都依赖于部署描述符文件中的配置信息。

在配置关于要么全部要么没有访问控制

 

  A。 将所有要控制访问权限的文件放在一个特定的目录中,  可以根据web.xml安全限制中角色,控制特定的目录实现。

 B。也可根据web.xml安全控制描述正则表达式来匹配相关的资源,实现安全控制。

   

JSP执行过程,以及生命周期

JSP执行过程,以及生命周期
JSP 的执行过程
(1) 客户端发出Request (请求);
(2) JSP Container 将JSP转译成Servlet的源代码;
(3) 将产生的Servlet 的源代码经过编译后,并加载到内存并进行实例化;
(4) 把结果Response (响应)至客户端。
在执行 JSP 网页时,通常可分为两个时期:转译时期(Translation Time)和请求时期(Request Time)
转译时期:JSP网页转译成Servlet类。
请求时期:Servlet类执行后,响应结果至客户端。 
注:
转译期间主要做了两件事情:将JSP网页转译为 Servlet 源代码(.java),此段称为转译时
期(Translation time);将Servlet源代码(.java)编译成 Servlet 类(.class),此段称为编译时期(Compilation time)。

生命周期
1、转换 验证JSP页面,没有出现错误,就创建一个包含servlet类的java文件;
2、编译 把java文件编译成类(.class)文件 并报告语法错误
3、加载和实例化 编译成功则将servlet类加载到内存中,并对其进行实例化;
4、jspInit() 执行一次初始化;
5、jspService() 进行请求处理;
6、jspDestroy() JSP引擎从服务器中删除servlet实例时,会调用jspDestroy();

Servlet流程和生命周期:

servlet有良好的生存期的定义,包括如何加载、实例化、初始化、处理客户端请求以及如何被移除。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。

 

1、加载和实例化

 

容器负责加载和实例化一个servlet。实例化和加载可以发生在引擎启动的时候,也可以推迟到容器需要该servlet为客户请求服务的时候。

 

首先容器必须先定位servlet类,在必要的情况下,容器使用通常的Java类加载工具加载该servlet,可能是从本机文件系统,也可以是从远程文件系统甚至其它的网络服务。容器加载servlet类以后,它会实例化该类的一个实例。需要注意的是可能会实例化多个实例,例如一个servlet类因为有不同的初始参数而有多个定义,或者servlet实现SingleThreadModel而导致容器为之生成一个实例池。

 

2、初始化

 

servlet加载并实例化后,容器必须在它能够处理客户端请求前初始化它。初始化的过程主要是读取永久的配置信息,昂贵资源(例如JDBC连接)以及其它仅仅需要执行一次的任务。通过调用它的init方法并给它传递唯一的一个(每个servlet定义一个)ServletConfig对象完成这个过程。给它传递的这个配置对象允许servlet容器的配置信息中的名称-值对(name-value)初始化参数。这个配置对象同时给servlet提供了实现了ServletContext接口的具体对象的方法,该对象描述了servlet的运行环境。

 

2.1初始化的错误处理

 

在初始化期间,servlet实例可能通过抛出UnavailableException 或者 ServletException异常表明它不能进行有效服务。如果一个servlet抛出一个这样的异常,它将不会被置入有效服务并且应该被容器立即释放。在此情况下destroy方法不会被调用因为初始化没有成功完成。在失败的实例被释放后,容器可能在任何时候实例化一个新的实例,对这个规则的唯一例外是如果失败的servlet抛出的异常是UnavailableException并且该异常指出了最小的无效时间,那么容器就会至少等待该时间指明的时限才会重新试图创建一个新的实例。

 

2.2、工具因素

 

当工具(注:根据的理解,这个工具可能是应用服务器的某些检查工具,通常是验证应用的合法性和完整性)加载和内省(introspect)一个web应用时,它可能加载和内省该应用中的类,这个行为将触发那些类的静态初始方法被执行,因此,开发者不能假定只要当servlet的init方法被调用后它才处于活动容器运行状态(active container runtime)。作为一个例子,这意味着servlet不能在它的静态(类)初始化方法被调用时试图建立数据库连接或者连接EJB容器。

 

3、处理请求

 

在servlet被适当地初始化后,容器就可以使用它去处理请求了。每一个请求由ServletRequest类型的对象代表,而servlet使用ServletResponse回应该请求。这些对象被作为service方法的参数传递给servlet。在HTTP请求的情况下,容器必须提供代表请求和回应的HttpServletRequest和HttpServletResponse的具体实现。需要注意的是容器可能会创建一个servlet实例并将之放入等待服务的状态,但是这个实例在它的生存期中可能根本没有处理过任何请求。

 

3.1、多线程问题

 

容器可能同时将多个客户端的请求发送给一个实例的service方法,这也就意味着开发者必须确保编写的servlet可以处理并发问题。如果开发者想防止这种缺省的行为,那么他可以让他编写的servlet实现SingleThreadModel。实现这个类可以保证一次只会有一个线程在执行service方法并且一次性执行完。容器可以通过将请求排队或者维护一个servlet实例池满足这一点。如果servlet是分布式应用的一部分,那么,那么容器可能在该应用分布的每个JVM中都维护一个实例池。如果开发者使用synchronized关键字定义service方法(或者是doGet和doPost),容器将排队处理请求,这是由底层的java运行时系统要求的。我们强烈推荐开发者不要同步service方法或者HTTPServlet的诸如doGet和doPost这样的服务方法。

 

3.2、处理请求中的异常

 

servlet在对请求进行服务的时候有可能抛出ServletException或者UnavailableException异常。ServletException表明在处理请求的过程中发生了错误容器应该使用合适的方法清除该请求。UnavailableException表明servlet不能对请求进行处理,可能是暂时的,也可能是永久的。如果UnavailableException指明是永久性的,那么容器必须将servlet从服务中移除,调用它的destroy方法并释放它的实例。如果指明是暂时的,那么容器可以选择在异常信息里面指明的这个暂时无法服务的时间段里面不向它发送任何请求。在这个时间段里面被被拒绝的请求必须使用SERVICE_UNAVAILABLE (503)返回状态进行响应并且应该携带稍后重试(Retry-After)的响应头表明不能服务只是暂时的。容器也可以选择不对暂时性和永久性的不可用进行区分而全部当作永久性的并移除抛出异常的servlet。

 

3.3线程安全

 

开发者应该注意容器实现的请求和响应对象(注:即容器实现的HttpServletRequest和HttpServletResponese)没有被保证是线程安全的,这就意味着他们只能在请求处理线程的范围内被使用,这些对象不能被其它执行线程所引用,因为引用的行为是不确定的。

 

4、服务结束

 

容器没有被要求将一个加载的servlet保存多长时间,因此一个servlet实例可能只在容器中存活了几毫秒,当然也可能是其它更长的任意时间(但是肯定会短于容器的生存期)当容器决定将之移除时(原因可能是保存内存资源或者自己被关闭),那么它必须允许servlet释放它正在使用的任何资源并保存任何永久状态(这个过程通过调用destroy方法达到)。容器在能够调用destroy方法前,它必须允许那些正在service方法中执行的线程执行完或者在服务器定义的一段时间内执行(这个时间段在容器调用destroy之前)。一旦destroy方法被调用,容器就不会再向该实例发送任何请求。如果容器需要再使用该servlet,它必须创建新的实例。destroy方法完成后,容器必须释放servlet实例以便它能够被垃圾回收。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值