偶是测试新手,希望前辈们能多多指教。

发布新日志

  • 在JAX-WS中的快速信息集

    2009-05-05 14:10:26

        JAX-WS通过检查标准的HTTP头的Accept和Content-Type字段来支持快速信息集。在默认情况下,所有的JAX-WS Web Services的快速信息集都是打开的(通过服务运行时实现)。为了在信息交换中使用快速信息集,客户端必须明确指出客户端运行时有支持快速信息集文档的能力。我们可以通过向服务端发送一个以标准的XML格式编码的初始化请求,这个请求包括了HTTP Accept字段,它的值为MIME类型的application/fastinfoset。在发送初始化请求后,所有的客户端和服务端的数据规范都将以快速信息集格式编码,只要客户端继续使用同一个BindingProvider对象实例就会一直保持这种状态。

        在JAX-WS中,我们可以用两种方法来完成上述的约定:

    1. 在客户端的JVM中设置系统属性。

    2. 在binding provider对象(一个端口协议和委派)中设置属性。

        不管使用哪种方法,都需要指定属性名" com.sun.xml.ws.client.ContentNegotiation"和它的值"pessimistic"。在JAX-WS2.0中为了描述属性名,还在com.sun.xml.ws.developer.JAXWSProperties接口中定义了一个常量,CONTENT_NEGOTIATION_PROPERTY。但这个常量在以后的JAX-WS版本中并不建议使用。

        在这里我们使用第一种方法(也就是设置系统属性),我们可以通过如下的命令行来运行Web service客户端:
     
              java –Dcom.sun.xml.ws.client.ContentNegotiation=pessimistic ...
     
        下面的代码段显示了如何使用Ant来运行Web Sevice客户端:

    <target name="run"> <java fork="true" classname="${client}"> <classpath> <path refid="client.classpath"/> <pathelement location="${build.classes.home}"/> <pathelement location="${basedir}/conf"/> </classpath> <sysproperty key="com.sun.xml.ws.client.ContentNegotiation" value="pessimistic"/> <arg value="${isbn}"/> </java> </target>
    我们还可以通过第二种方法(也就是设置binding provider对象的方法)来达到同样的目的:
    CatalogPortType port = service.getCatalogPort(); ((BindingProvider) port).getRequestContext().put(JAXWSProperties.CONTENT_NEGOTIATION_PROPERTY, "pessimistic"); //((BindingProvider) port).getRequestContext().put("com.sun.xml.ws.client.ContentNegotiation", "pessimistic");
        上面的例子使用了一个端口协议。如果我们正在使用一个Dispatch实例,我们可以再次转换它,以得到一个请求上下文,并设置相应的属性来开启数据传输规范。这是因为在JAX-WS中的Dispatch实例也是一个BindingProvider
  • 使用Filter技术防止用户非法访问页面

    2009-05-05 13:35:16

    一 Filter概述

    Filter 技术是servlet 2.3 新增加的功能,它新增加的功能包括:
    1. 应用程序生命周期事件控制
    2. 新的国际化
    3. 澄清了类的装载规则;
    4. 新的错误及安全属性;
    5. 不赞成使用HttpUtils 类
    6. 各种有用的方法
    7. 阐明并扩展了几个servlet DTD
    8. filter功能

    其中最重要的就是filter功能。它使用户可以改变一个request和修改一个response,
    Filter 不是一个servlet,它不能产生一个response它能够在一个request到达servlet之前
    预处理request,也可以在离开servlet时处理response。换种说法,filter其实是一个
    “servlet chaining”(servlet 链)

    一个filter 包括:
    1. 在servlet被调用之前截获
    2. 在servlet被调用之前检查servlet request
    3. 根据需要修改request头和request数据
    4. 根据需要修改response头和response数据
    5. 在servlet被调用之后截获

    二 Filter在检修ABC系统中的应用

    检修ABC系统在初期搭建框架的时候决定使用Filter来处理用户非法访问URL以及Session过期等问题。
    我们首先定义了一些可以通过URL直接访问的页面,如登陆页面,重登陆页面等。当用户没有登陆而
    尝试访问受保护的URL时,Filter将拦截该请求,并把访问的URL重定向到登陆页面。

    在web.xml中的配置如下:
      <filter>
        <filter-name>filterservlet</filter-name>
        <filter-class>com.comtop.app.common.FilterServlet</filter-class>
        <init-param>
      <param-name>freePages</param-name>
      <param-value>

    /Login.jsp;/LoginAction.do;/index.jsp;/ReLogin.jsp;/SSOLoginAction.do;
         </param-value>
        </init-param>
        <init-param>
          <param-name>toPage</param-name>
          <param-value>/ReLogin.jsp</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>filterservlet</filter-name>
        <url-pattern>*.do</url-pattern>
      </filter-mapping>

      <filter-mapping>
        <filter-name>filterservlet</filter-name>
        <url-pattern>*.jsp</url-pattern>
      </filter-mapping>

    <filter></filter>中定义一些基本信息,比如filter的名称,filter的类以及相关初始参数。这里我
    们把能直接访问的页面定义为freePages,并定义了它的值。还定义了默认的重定向页面,Relogin.jsp。
    接着定义了filter-mapping,让后缀名为.do或.jsp的URL都被Filter所保护。

    FilterServlet具体代码(import部分省略):

    public class FilterServlet extends HttpServlet implements Filter {
     private FilterConfig filterConfig;
     private String[] freePages;
     private String toPage = null;
     private static Logger logger;

     
    /**
      * 初始化filter(这里重写父类的方法)
      * @param filterConfig FilterConfig filter配置对象
      * @throws ServletException
      */

     public void init(FilterConfig filterConfig) throws ServletException {
      logger = Toolkit.getInstance().getLogger(this.getClass().getName());
      int i = 0;
      String pages = null;
      StringTokenizer strTokenizer = null;

      if(logger.isDebugEnabled()) {
       logger.debug("init validate session filter ");
      }

      this.filterConfig = filterConfig;
      
    //以下从配置文件获取配置信息

      this.toPage = filterConfig.getInitParameter("toPage");
      pages = filterConfig.getInitParameter("freePages")
      if(toPage == null || pages == null || toPage.trim().length() == 0 ||
       pages.trim().length() == 0) {
    logger.error("web.xml中filterServlet没有配置初始化参数\"toPage\"或\"freePage\".");
       throw new ServletException(
    "web.xml中filterServlet没有配置初始化参数
    \"toPage\"或\"freePage\"."
    );
      }
      if(logger.isDebugEnabled()) {
       logger.debug("toPage:" + toPage);
       logger.debug("freePages:" + pages);
      }

      strTokenizer = new StringTokenizer(pages, ";");
      this.freePages = new String[strTokenizer.countTokens()];
      while(strTokenizer.hasMoreTokens()) {
       freePages[i++] = strTokenizer.nextToken();
      }

      if(!isFreePage(toPage)) {

    logger.error("web.xml中filter初始化参数\"toPage\"的值必须是\"freePage\"中的某个页面.");
       throw new ServletException(
    "web.xml中filter初始化参数\"toPage\"的值

    必须是\"freePage\"中的某个页面."
    );
      }
     }

     
    /**
      * 判断一个请求URI是否是不过滤的页面
      * @param requestURI String 请求URI
      * @return boolean 返回true为不过滤页面
      */


     private boolean isFreePage(String requestURI) {
      boolean isFree = false;
      for(int i = 0; i < freePages.length; i++) {
       if(requestURI.endsWith(freePages[i])) {
        return true;
       }
      }
      return isFree;
     }

     
    /**
      * 判断请求是否为有效Session
      * @param request ServletRequest 请求对象
      * @return boolean 返回true为有效Session
      */

     private boolean isValidSession(ServletRequest request) {
      HttpServletRequest httpRequest = (HttpServletRequest)request;
      if(httpRequest.getSession().getAttribute(GlobalConstants.SECURITY_LOGIN_KEY)

    ==
       GlobalConstants.SECURITY_IS_LOGIN) {
       return true;
      }
      if(logger.isDebugEnabled()) {
       logger.debug("Session无效,请求:" + httpRequest.getRequestURI());
      }
      return false;
     }

     
    /**
      * 过滤动作
      * @param request ServletRequest 请求对象
      * @param response ServletResponse 响应对象
      * @param filterChain FilterChain 过滤器链对象
      */

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain

    filterChain) {
      String requestURI = null;
      ActionErrors errors = new ActionErrors();
      ActionError errorSession = null;
      HttpServletRequest httpRequest = (HttpServletRequest)request;
      HttpServletResponse httpResponse = (HttpServletResponse)response;
      requestURI = httpRequest.getRequestURI();

            if(logger.isDebugEnabled()) {
       logger.debug("Session filter RequestURI:" + requestURI);
      }
      if(!isFreePage(requestURI)) {
    //如果是保护页面

       if(!isValidSession(request)) {
    //如果Session无效

        String toPageURL = null;
        try {
         toPageURL = httpRequest.getContextPath() + toPage;
         httpResponse.encodeRedirectURL(toPageURL);
         httpResponse.sendRedirect(toPageURL);
    //转发响应

        } catch(IOException ex) {
         logger.error("Session filter过滤时发生IO异常", ex);
        }
       }
      }

      if(!httpResponse.isCommitted()) {
    //如果响应未提交,交给过滤器链

       try {
        filterChain.doFilter(request, response);
       } catch(ServletException sx) {
        filterConfig.getServletContext().log(sx.getMessage());
       } catch(IOException iox) {
        filterConfig.getServletContext().log(iox.getMessage());
       }
      }

     }
     
    //父类的方法

     public void destroy() {
     }
     
     public FilterConfig getFilterConfig() {
      return this.filterConfig;
     }

     public void setFilterConfig(FilterConfig filterConfig) {
      this.filterConfig = filterConfig;
     }

    }


    这里isFreePage方法判断用户访问的URL是否是受保护的,从配置文件中将freePages的值得到后,以分号
    为隔离符将它们取出放到一个数组中,这个数组存放的每个String都是一个freePage。另外,isValidSession
    方法判断在session中是否存在用户的登陆信息,如果用户未登陆,则返回false。每一个filter从doFilter()方法
    中得到当前的request及response,在doFilter()方法中,以下代码完成核心判断:

      if(!isFreePage(requestURI)) {
    //如果是保护页面

       if(!isValidSession(request)) {
    //如果Session无效

        String toPageURL = null;
        try {
         toPageURL = httpRequest.getContextPath() + toPage;
         httpResponse.encodeRedirectURL(toPageURL);
         httpResponse.sendRedirect(toPageURL);
    //转发响应

        } catch(IOException ex) {
         logger.error("Session filter过滤时发生IO异常", ex);
        }
       }
      }

    只有是通过isFreePage(requestURI)和isValidSession(request)两层验证的页面才能被访问到,基本实
    现了防止用户非法访问页面的情况。在实际项目中还可以添加更多的验证方法。

Open Toolbar