好好学习

good good study,day day up:) 

Spring

Bromon的blog上对Spring的IoC与Di有个比较浅显易懂的解释,引用过来看看

首先想说说IoCInversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比Connection等),对象始终会和其他的接口或类藕合起来。

  那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。如果你还不明白的话,我决定放弃。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DIDependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉springA中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。关于反射的相关资料请查阅java doc

Filter

 

以下是几种Filter可运行的方式:

l         统一的认证处理

l         对用户的请求做检查、做更精确的记录

l         监视或对用户所传递的参数作前置处理,例如:防止SQL Injection攻击

l         改变图像文件的格式

l         对响应做编码处理

l         对响应作压缩处理

l         XML的输出使用XSLT来转换

 

要使用Filter需要在web.xml中设定,使用<dispatcher>元素,用来设定Filter所对应的请求方式。

1.         REQUEST

当用户直接对网页做出请求的动作时,才回通过此Filter。因此当用户通过RequestDispatcher方法的转向请求(forward())时,不会通过此Filter

2.         FORWARD

当用户的请求是通过RequestDispatcherforward()方法时,才回通过此Filter。其他请求方式不会通过此Filter

3.         INCLUDE

当用户的请求是通过RequestDispatcherinclude()方法时,才回通过此Filter。其他请求方式不会通过此Filter

4.         ERROR

当用户请求是通过错误机制处理的时候,才回通过此Filter。同样,其他请求方式则不会通过此Filter

 

一个用户验证的例子:(摘自《JSP2.0技术手册》,作者:林上杰、林康司)

SessionChecker.java

package test;

 

import java.io.*;

 

import javax.servlet.*;

import javax.servlet.http.*;

 

public class SessionChecker implements Filter {

    private ServletContext context;

 

    private String targetURI;

 

    public void destroy() {

 

    }

 

    public void doFilter(ServletRequest request, ServletResponse response,

           FilterChain chain) throws IOException, ServletException {

       HttpServletRequest httpRequest = (HttpServletRequest) request;

       HttpServletResponse httpResponse = (HttpServletResponse) response;

       HttpSession session = httpRequest.getSession(false);

       if (session != null) {

           String passed = (String) session.getAttribute("passed");

           if (passed.equals("true")) {

              chain.doFilter(httpRequest, httpResponse);

              return;

           } else if (passed.equals("passing")) {

              if (new String(httpRequest.getRequestURI())

                     .equals("test/LoginChecker")) {

                  chain.doFilter(httpRequest, httpResponse);

                  return;

              }

           } else {

 

           }

           session.removeAttribute("passed");

       }

       StringBuffer requestURL = httpRequest.getRequestURL();

       String query = httpRequest.getQueryString();

       if (query != null)

           requestURL.append(query);

       httpRequest.setAttribute("originalURI", new String(requestURL));

       httpRequest.getRequestDispatcher(targetURI).forward(httpRequest,

              httpResponse);

    }

 

    public void init(FilterConfig config) throws ServletException {

       context = config.getServletContext();

       targetURI = config.getInitParameter("targetURI");

    }

 

}

 

 

LoginChecker.java

package test;

 

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

public class LoginChecker extends HttpServlet{

       protected void doPost(HttpServletRequest httpRequest,HttpServletResponse httpResponse) throws IOException,ServletException{

              String userId=httpRequest.getParameter("userId");

              String password=httpRequest.getParameter("password");

              String targetURI=httpRequest.getParameter("originalURI");

              if((!userId.equals("admin"))||(!password.equals("123"))){

                     throw new ServletException("认证失败");

              }

              HttpSession session=httpRequest.getSession();

              session.setAttribute("passed", "true");

              httpResponse.sendRedirect(targetURI);

       }

}

 

 

Login.jsp

<%@ page language="java" contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=GB18030">

<title>Login</title>

</head>

<body>

    <c:set var="passed" value="passing" scope="session"/>

    <form action="test/LoginChecker" method="post">

       <table>

           <tr>

              <th>用户名:</th>

              <td><input type="text" name="userId"></td>

           </tr>

           <tr>

              <th>用户密码:</th>

              <td><input type="password" name="password" ></td>

           </tr>

           <th><input type="hidden" name="originalURI" value="${requestScope.originalURI }"></th>

           <tr>

              <th><input type="submit" name="submit" value="登录"></th>

           </tr>

       </table>

    </form>

</body>

</html>

 

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>

    Filter_Test</display-name>

    <welcome-file-list>

       <welcome-file>index.html</welcome-file>

       <welcome-file>index.htm</welcome-file>

       <welcome-file>index.jsp</welcome-file>

       <welcome-file>default.html</welcome-file>

       <welcome-file>default.htm</welcome-file>

       <welcome-file>default.jsp</welcome-file>

    </welcome-file-list>

   

    <filter>

       <filter-name>SessionChecker</filter-name>

       <filter-class>test.SessionChecker</filter-class>

       <init-param>

           <param-name>targetURI</param-name>

           <param-value>/Login.jsp</param-value>

       </init-param>

    </filter>

    <filter-mapping>

       <filter-name>SessionChecker</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

   

    <servlet>

       <servlet-name>LoginChecker</servlet-name>

       <servlet-class>test.LoginChecker</servlet-class>

    </servlet>

    <servlet-mapping>

       <servlet-name>LoginChecker</servlet-name>

       <url-pattern>/LoginChecker</url-pattern>

    </servlet-mapping>

</web-app>

 

 

 

JSTL

方便自己查询,其实用到的也就那几个

JSTL1.1使用及标签

JSTL的使用,必须引入两个包jstl.jarstandard.jar,然后在页面中加入

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>

<%@ taglib prefix=”fmt” uri=”http://java.sun.com/jsp/jstl/fmt”%>

<%@ taglib prefix=”sql” uri=”http://java.sun.com/jsp/jstl/sql”%>

<%@ taglib prefix=”xml” uri=”http://java.sun.com/jsp/jstl/xml”%>

<%@ taglib prefix=”fn” uri=http://java.sun.com/jsp/jstl/functions%>

 

Core:

       <c:out>

       语法1

              <c:out value=”value” default=”defaultValue”/>

       语法2

              <c:out value=”value”>

                     本体内容

              </c:out>

       <c:set>

       语法1:将value的值存储进范围为scopevarName变量中

              <c:set value=”value” var=”varName” scope=”{page|request|session|application}”/>

       语法2:将本体内容的数据存储至范围为scopevarName变量中

              <c:set var=”varName” scope={…}>

                     本体内容

              </c:set>

       语法3:将value的值存储至target对象的属性中

              <c:set value=”value” target=”target” property=”propertyNmae”/>

       语法4:将本体内容的数据存储至target对象的属性中

              <c:set target=”target” property=”propertyName”>

                     本体内容

              </c:set>

       <c:remove>

              将范围为scope的变量移除

              <c:remove var=”varName” scope=”…”/>

       <c:catch>

              <c:catch var=”varName”>

                     可能出错的代码

              </c:catch>

       <c:if>

              语法1

<c:if test=”testCondition” var=”varName” scope=”…”/>

              语法2

<c:if test=”testCondition” var=”varName” scope=”…”>

       本体内容

</c:if>

      

<c:choose>

              本身只当做<c:when><c:otherwise>的父标签。

              <c:choose>

                     本体内容(<c:whern><c:otherwise>)

              </c:choose>

              本体内容只能有

l         空白

l         1个或多个<c:when>

l         0个或1<c:otherwise>

<c:forEach>(本人最喜欢用这个,呵呵~~~J

       语法1:

       <c:forEach [var=”varName”] items=”collection” [varStatus=”varStatusName” begin=”begin” end=”end” step=”step”]>

              本体内容

       </c:forEach>

       语法2

       <c:forEach [var=”varName”] [varStatus=”” begin=”” end=”” step=””]>

              本体内容

       </c:forEach>

<c:import>

这个标签可以把其他静态或动态文件包含至本身JSP网页。它和JSP Action<jsp:include>最大的差别在于:<jsp:include>只能包含和自己同一web application下的文件;而<c:import>除了能包含同一个web application的文件外,还可以包含不同web application或者是其他网站的文件。

<c:import url=”url” [context=”context” var=”varName” scope=”…” charEncoding=””]>

       本体内容

</c:import>

       如果在同一个服务器上,但并非同一个web站点的文件要被import,就要使用context属性。假设此服务器上还有一个web站点,名为others

       <c:import url=”/jsp/index.jsp” context=”/others”/>

       被包含文件的web站点必须在server.xml中定义过,且<Context>crossContext属性值必须为true.

       <c:url>

       好处是可以动态产生url地址

       <c:redirect>

       自动导向网页地址(也可以用来传参数)

 

Format:

       <fmt:setLocale>

       用来设定地区

              <fmt:setLocale value=”zh_CN”/>

       <fmt:requestEncoding>

       用来设定字符编码,功能和request.setCharacterEncoding()相同

              <fmt:requestEncoding value=”value”/>

SQL

       JSTLSQL标签让我们可以更轻松使用数据库内容,但是其并没有ConnectionPool的功能,所以一般不建议在大型项目上使用,但是在一些小型网站,它还是很好用的。

       <sql:setDataSource>

              用来设定数据来源

              语法1:直接用已经存在的数据来源

              <sql:setDataSource dataSource=”dataSource” var=”varName” scope=”…”/>

              语法2:使用JDBC方式连接

              <sql:setDataSource url=”” driver=”” user=”” password=”” var=”” scope=””/>

       <sql:query>

              语法1:没有本体

              <sql:query sql=”sqlQuery” var=”varName” scope=”…” dataSource=”” maxRows=”” startRow=””/>

              语法2有本体

               <sql:query var=”varName” scope=”…” dataSource=”” maxRows=”” startRow=””>

              查询本体

              </sql:query>

       :

       <sql:query var=”result” maxRows=”2” startRow=”1”>

              SELECT * FROM test

       </sql:query>

       <table>

       <c:forEach items=”${result.rows}” var=”row”>

       <tr>

       <td>${row.Id}</td>

       <td>${row.Age}</td>

       </tr>

       </c:forEach>

       </table>

 

       <sql:update>

       更新命令

       <sql:param><sql:dateParam>

       sql语句可以动态设定变量

 

 

 

JSP复习笔记: 

指令:

       JSP1.2的规范中,有三种指令:pageincludetaglibJSP2.0新增Tag File功能,Tag File是以 .tag 为扩展名的。使用includetaglib指令调用它

       Page指令:

       <%@ page …%>  还支持XML语法的

       <jsp:directive.page attribute1=”value1” attribute2=”value2” />

       属性:

1、  language=”scriptingLanguage”  指定JSP Container用什么语言来编译JSP网页。JSP2.0中只可以使用Java语言,默认也是它(写了也白写,呵呵)

2、  extends=”className”     定义此JSP网页产生的servlet是继承哪个父类。

3、  import=”importList”       定义此JSP网页可以使用哪些Java API

4、  session=”true|false”        决定此网页是否可以使用session对象。默认true

5、  buffer=”none | size in kb”       决定是否有缓冲区,默认8KB

6、  autoFlush=”true | false”   决定输出流的缓冲区是否要自动清除,缓冲区满了会产生异常,默认true

7、  isThreadSafe=”true | false”     JSP能否处理超过一个以上的请求。默认true,如果为false,单线程模式将会启动。SingleThreadModelServlet2.4中已经声明不赞成使用

8、  info=”text”      说明信息

9、  errorPage=”error_url”     如果网页发生异常,网页会被重新定向到指定的URL

10、              isErrorPage=”true | false”      表示此页面是否为处理异常错误的网页

 

三个指令:pageincludetaglib

       page:只有import这个属性可以重复,其他则不行。

       Include:网页中有中文会出乱码,Resin下正常

 

<%! 声明 %> 

<% Scriptlet %>

<%= 表达式 %>

 

l       每个声明仅在一个页面中有效,若想每个页面都用到,最好写成一个单独的JSP,然后用<%@ include %>包含进来

l       <%! %>声明的是全局变量,即及格用户同时共享此变量,因此尽量使用<% %>声明变量

l       <%= 表达式 %>结尾不能有” ; ”   这个表达式能够包括任何Java语法,有时也能作其他JSP元素的属性值

 

Action Elements:

       <jsp:useBean>

       <jsp:setProperty>

       <jsp:getProperty>

 

       <jsp:include>

       <jsp:forward>

       <jsp:param>

       <jsp:plugin>

       <jsp:params>

       <jsp:fallback>

 

       <jsp:root>

       <jsp:declaration>

       <jsp:scriptlet>

       <jsp:expression>

       <jsp:text>

       <jsp:output>

 

       <jsp:attribute>

       <jsp:body>

       <jsp:element>

 

       <jsp:invoke>

       <jsp:doBody>

 

隐含对象(Implicit Object):就是当你在写JSP网页时,不须做任何的声明就可以直接使用带给对象

 

四种范围:

pageContext

request

session

application

 

l       pageContext中无getAttributeNames()方法

 

 

JSTLJavaServer Pages Standard Tag Library

       核心标签库(Core tag library)

              表达式操作:

                     out

                     set

                     remove

                     catch

              流程控制:

                     if

                     choose

                            when

                            otherwise

              迭代操作:

                     forEach

                     forTokens

              URL操作:

                     import

                            Param

                     url

                            Param

                     redirect

                            Param

JSP中要使用JSTL中的核心标签库时,必须使用<%@ taglib %>指令,并且设定prefixuri的值,通常设定如下:

<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>

 

(JSP&JavaBean)自省机制:

       自省机制就是指,当服务器接收到请求时,它根据请求的参数名称,自动设定与JavaBean相同属性名称的值。

 

<jsp:setProperty>

       <jsp:setProperty name=”myBean” property=”*” />

       < jsp:setProperty name=”myBean” property=”myProperty” />

       < jsp:setProperty name=”myBean” property=”myProperty” param=”ParamName” />

       < jsp:setProperty name=”myBean” property=”myProperty” value=”MyValue” />

<jsp:getProperty>

       <jsp:getProperty name=”myBean property=”myProperty” />

 

Session Tracking:

1.       建立含有数据的隐藏表格字段

2.       重写包含额外参数的URL

3.       使用持续Cookies

4.       使用ServletHttpSession API

 

session过期时,将session数据写回数据库或文件,或者将某个负责记录用户所点击页面数据的对象加入session中。此时,就需要实现javax.servlet.http.HttpSessionBindingListener,此接口有两个必须实现的方法:

public void valueBound(HttpSessionBindingEvent event)

public void valueUnbound(HttpSessionBindingEvent event)

 

Filter:

Filter的运用方法:

1.       统一的认证处理

2.       对用户的请求做检查、做更精确的记录

3.       监视或对用户所传递的参数作前置处理

4.       改变图像文件的格式

5.       对响应作编码的动作

6.       对响应作压缩处理

7.       XML的输出使用XSLT来转换

 

实现一个Filter必须实现javax.servlet.Filter接口,Filter接口有三个方法:

public void destroy()

 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException

 

public void init(FilterConfig filterConfig) throws ServletException

 

web.xml:

      

       <filter>

       <filter-name>Hello</filter-name>

       <filter-class>com.googlepages.timnity</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>Hello</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

 

保留原本用户请求的网页技巧:

    StringBuffer requestURL=httpRequest.getRequestURL();

    String query=httpRequest.getQueryString();

    if(query!=null)

       requestURL.append(query);

    httpRequest.setAttribute(“originalURI”,new String(requestURL));

    httpRequest.getRequestDispatcher(targetURI).forward(httpRequest,httpResponse);

 

 

java.util.Arrays的BUG - 二分搜索算法(转)

chris 发表于2006-06-07
   作者:chris 来自:Joshua Bloch's blog

Joshua Bloch, 获得过Jolt最畅销奖的《Effective Java》的作者, 是Sun Microsystems的杰出工程师和Transarc的资深系统设计师, J2SE 5.0 Tiger的代言人和领路人, 也是还是JSR166的发起人之一..

后来, Joshua Bloch去了Google, 成为了Google的首席工程师

Joshua Bloch拥有卡耐基.梅隆大学(CMU)计算机科学的博士学位。

在最近Joshua Bloch的一篇文章里, Joshua Bloch回忆了当年在CMU上课的时候, vividly Jon Bentley 第一节算法课, 就要求所有刚进来的PHD学生, 每人都写一个二分查找算法. 然后发现, 多数人的算法都存在BUG, 这在当时给了Joshua Bloch 一个很深的印象..

在之后, Joshua Bloch 负责java.util.Arrays 代码编写的时候, 采用了Bentley 在<<Programming Pearls >>一书中的二分查找算法, 结果在8年后的今天, Joshua Bloch 发现, 这里面原来还是有一个BUG.

问题到底是出在哪里? 竟然逃过了Bentley 和Joshua Bloch 的双重检测?

一起来看看java.util.Arrays的代码:

1:     public static int binarySearch(int[] a, int key) {
2:         int low = 0;
3:         int high = a.length - 1;
4:
5:         while (low <= high) {
6:             int mid = (low + high) / 2;
7:             int midVal = a[mid];
8:
9:             if (midVal < key)
10:                 low = mid + 1;
11:             else if (midVal > key)
12:                 high = mid - 1;
13:             else
14:                 return mid; // key found
15:         }
16:         return -(low + 1);  // key not found.
17:     }



这是很经典的一个二分查找算法.

bug出现在第6行:

6:             int mid =(low + high) / 2;

在一般情况下, 这个语句是不会出错的, 但是, 当low+high的值超过了最大的正int值 (231 - 1) 的时候, mid会变成负值,  这个时候, 会抛出ArrayIndexOutOfBoundsException 异常..


所以当一个数组包含超过2的30次方 个元素的时候, 就很可能会带来问题... 当然, 在一般的应用里面, 很少数组会包含那么多元素, 但是现在这样的情况已经越来越多了, 比如Google的海量运算..

那如何解决这个问题?

很简单, 修改这行语句为:

6:             int mid = low + ((high - low) / 2);
或者
6:             int mid = (low + high) >>> 1;


在c或者c++中, 则可以如下实现:
6:             mid = ((unsigned) (low + high)) >> 1;


这个问题告诉我们, 无论什么时候, 我们都不要想当然我们的程序是完美的. 我们需要细心的设计,测试再测试,符合规范的方法等等...对此, 你有什么经验和大家分享吗?

同样给我们带来的思考是: 8年了, java.util.Arrays 竟然存在这样一个bug, 这不得不让我们对JDK本身的测试性, 稳定性 怀有疑问.. 将来又会有多少个类似的bug出现呢?


本文 by Chris(From Matrix)

(最后一段的评论,倒觉得是多余的担心,没有什么东西是完美的,在计算机技术发展之下,新的要求导致以前并未注意的缺陷出现)

 

 

 

JSF中的单选按钮(Use the selectoneradio)

       JSF中的单选按钮,<h:selectOneRadio>,虽然好用,容易绑定,可是……却居然没有checkedselected属性,为了能让页面显示的时候让它默认选中一项,可是费了我不少功夫。Google了一下,网上,包括台湾和各大E文社区,都有不少人在问这个问题。既然解决了,就把心得写一下,以便和我碰到同样问题却无从入手的朋友们能节约一点青春:)

       单选按钮中,有两种加入单选项的方式,一种是使用<f:selectItems>,一种是使用<f:selectItem>,前者比较灵活,有多少项,就会显示多少个对应的单选按钮;后者在页面中就定好了单选项的多少。两者的默认选中使用的方法稍微有点不同,但是基本都是需要绑定后台bean的属性来控制选中状态(还是有checked属性会方便很多,希望下个版本会改进)。

       我们先试试<f:selectItems>。这个测试需要一个呈现的页面,一个后台bean,还有faces-config.xml

 

test.jsp

<%@ page contentType="text/html;charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<f:view>

  <html>

    <head>

      <meta http-equiv="Content-Type" content="text/html; charset=GBK"/>

      <title>MyTitle</title>

    </head>

    <body><h:form>

        <h:selectOneRadio value="#{test.state}" layout="pageDirection">

          <f:selectItems value="#{test.educationItems}"/>

        </h:selectOneRadio>

      </h:form></body>

  </html>

</f:view>

 

简单地加入了三行,就是产生一个单选radio组。Layout属性是控制单选按钮排放的,这里是纵向排放。<h:selectOneRadio>标签的value绑定的就是后台bean的状态值,而<f:selectItems>中的value绑定的是一个SelectItem[]数组,数组中有多少项,页面上就会呈现多少个单选项.具体bean代码看后面

 

faces-config.xml:

<managed-bean>

        <managed-bean-name>test</managed-bean-name>

        <managed-bean-class>mypackage.Test</managed-bean-class>

        <managed-bean-scope>session</managed-bean-scope>

              <managed-property>

            <property-name>state</property-name>

            <value>b</value>

        </managed-property>

</managed-bean>

前面的是后台bean的实例化,实例对象为test,在页面中使用.后面的红字部分,就是将state这个后台bean中的属性设初值.这里是b,这样页面呈现的时候,单选组中应该默认选中第二项.

 

Test.java:

package mypackage;

 

import javax.faces.model.SelectItem;

 

 

public class Test {

    private String state;

 

//PROPERTY state

    public void setState(String state) {

        this.state = state;

    }

 

    public String getState() {

        return state;

    }

   

    private static SelectItem[] educationItems=new SelectItem[]{

        new SelectItem(new String("a"),"选项A"),

        new SelectItem(new String("b"),"选项B "),

        new SelectItem(new String("c"),"选项C "),

        new SelectItem(new String("d"),"选项D")

    };

   

    public SelectItem[] getEducationItems() {

        return educationItems;

    }

}

 

bean中要引入SelectItem,该类中有几个可重载的构造函数我使用的这个是public SelectItem(java.lang.Object p1, java.lang.String p2) { },前一个Object是判断选中的字符串或索引,后边的String是显示单选按钮对应的Label.

 

,运行一下,看看效果吧.其实也不难,只是方式变化了一下,非得绑定值不可.如果有checked属性的话,会方便不少.sun Studio Creator2中就有一个替代的组件,selected属性.

state的初值设定可以在bean中完成,这样灵活性就好一些,大家自己根据需要实现吧J

 

下面看一下<f:selectItem>的实现,faces-config.xmlTest.java都不用修改,代码和上面的一样,另建一个test1.jsp页面,代码如下:

 

<%@ page contentType="text/html;charset=GBK"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<f:view>

  <html>

    <head>

      <meta http-equiv="Content-Type" content="text/html; charset=GBK"/>

      <title>MyTitle</title>

    </head>

    <body><h:form>

        <h:selectOneRadio layout="pageDirection" value="#{test.state}">

            <f:selectItem itemLabel="High School" itemValue="a"/>

            <f:selectItem itemLabel="Bachelor's" itemValue="b"/>

            <f:selectItem itemLabel="master's" itemValue="c"/>

            <f:selectItem itemLabel="Doctorate's" itemValue="d"/>

        </h:selectOneRadio>

    </h:form></body>

  </html>

</f:view>

 

可以看到,只是使用了itemValue属性,而且它并没绑定值,而是在页面上直接赋予值,仍然跟bean中的state属性对应.而且并没有使用到SelectItem[]数组.

 

 

 

 

Tomcat数据库连接池(Tomcat connection pool)

Tomcat数据库连接池终于算是搞定,弄了一天多,还算得到一些经验。不过不知道是不是太笨了,弄完了觉得还是挺简单的,却耗费我不少精力。

 

首先实验一下“正宗”的招数,就是Tomcat的官方文档,网上有翻译,讲得比较笼统,还不如看E文文档,也很简单。

一、建立mysql数据库,库:test      表:timnity    字段:first_name varchar(20)last_name varchar(20)      mysql下怎么建库建表请参考mysql的文档

 

二、修改$CATALINA_HOME/conf/server.xml ,在<Context></Context>之间加入:

<Context docBase="TestDB" path="/TestDB" reloadable="true" source="org.eclipse.jst.j2ee.server:TestDB">

         <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"/>

         <ResourceParams name="jdbc/TestDB">

             <parameter>

                <name>factory</name>

                <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

             </parameter>

             <parameter>

                <name>maxActive</name>

                <value>100</value>

             </parameter>

             <parameter>

                <name>maxIdle</name>

                <value>30</value>

             </parameter>

             <parameter>

                <name>maxWait</name>

                <value>10000</value>

             </parameter>

             <parameter>

                <name>username</name>

                <value>root</value>

             </parameter>

             <parameter>

                <name>password</name>

                <value>soft</value>

             </parameter>

             <parameter>

                <name>driverClassName</name>

                <value>org.gjt.mm.mysql.Driver</value>

             </parameter>

             <parameter>

                <name>url</name>

                <value>jdbc:mysql://localhost:3306/test?autoReconnect=true</value>

             </parameter>

         </ResourceParams>

      </Context>

 

在你的项目里WEB-INF目录下,修改WEB.XML文件,在<web-app></web-app>之间写入

<resource-ref>

       <description>Mysql Test App</description>

       <res-ref-name>jdbc/TestDB</res-ref-name>

       <res-type>javax.sql.DataSource</res-type>

       <res-auth>Container</res-auth>

    </resource-ref>

 

编写JSP文件:

<%@ page language="java" contentType="text/html; charset=GB18030"

    pageEncoding="GB18030"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<sql:query var="rs" dataSource="jdbc/TestDB">

    SELECT first_name,last_name FROM timnity

</sql:query>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=GB18030">

<title>TestDB</title>

</head>

<body>

<h2>Results</h2>

<c:forEach var="row" items="${rs.rows}">

    First_name:${row.first_name }<br/>

    Last_name:${row.last_name }<br/>

</c:forEach>

</body>

</html>

 

(用JSTL写法确实简单)

 

还有十分重要的一步,要把JDBC连接包放到$CATALINA_HOME/common/lib

这样,连接池就配置正确了

 

 

 

在实践中遇到的问题:

1、  由于使用Eclipse开发,在项目-构建路径中已经加入JDBC连接包,但是运行时仍然会报找不到ClassName,必须把连接包放至$CATALINA_HOME/common/lib里。

web.xml可以不写,但在实际项目中最好是写上