JavaWeb常用开发技术总结-js、spring、javabean、mysql数据库、dwr的使用等

来源:互联网 发布:淘宝上买气排会怎么样 编辑:程序博客网 时间:2024/05/21 02:11

JaveWeb 程序开发

一、    表单及表单元素

a)      文本框的应用:

<inputtype="password" name="userPass"style="font-family:Wingdings; width:139;" onpaste="returnfalse" oncut="return false" oncopy="return false"/>

不能复制,剪贴,黏贴一般用于密码框!

二、    窗口与导航条

a)       打开一个窗口自动关闭:

                       i.             父页面:

window.open("child.html","新的窗口","width=500;heigth=300;top=10;left=10")

                     ii.             子页面为body的onload 事件添加:

onload="window.setTimeout('window.close()',5000);";

 

b)       弹出窗口居中显示

function shownewpage(){              varhc=window.open("child.html","新的窗口","width=500;height=300;");              varwidth=screen.width;              varheigth=screen.height;              hc.moveTo((width-500)/2,(heigth-300)/2);}


c)       关闭窗口时,刷新父窗口

Window.opener.location.reload(); 

Window对象的opener 属性返回一个引用,表示返回打开这个子窗口的窗口的!所有通过它可以调用打开它的窗口的属性!

d)     弹出模式对话框

varresult=window.showModalDialog("child.html","","dialogWidth=407;dialogHeight=257;");

然后再模式对话框里:

parent.window.returnValue=document.form1.userPass.value;window.close();

e)      弹出全屏的模式对话框

var width=screen.width;var height=screen.height;varresult=window.showModalDialog("child.html","全屏的模式对话框","Dialogwidth="+width+";Dialogheight="+height+";");


三、    JavaScript函数:

a)       小写的金额转换为大写的金额

<script language="javascript"type="text/javascript">         functionchangeMoneyStr(str){                   varbasestr="零壹贰叁肆伍陆柒捌玖";                   varbasecw="万仟佰拾亿仟佰拾万仟佰拾元角分";                   varnewstring=(str*100).toString();                   newstringlog=newstring.length;                   newdw=basecw.substr(basecw.length-newstringlog);                            window.alert(newdw);                   varnum0=0;                   wan=0;                   dxje="";                   for(vari=1;i<=newstringlog;i++){                            xzf=newstring.substr(i-1,1);//小写金额                            dzf=basestr.substr(xzf,1);//大写金额                                 dw=newdw.substr(i-1,1);//单位                            if(dzf=="零"){                                     dzf="";                                     if(dw=="亿"){                                                                                   }elseif(dw=="万"){                                               dzf="";                                               wan=1;                                     }elseif(dw=="元"){                                                                         }else{                                               dw="";                                     }                                     num0=num0+1;                            }else{                                     if(num0-wan>0){                                               dzf='零'+dzf;                                     }                                     num0=0;                            }                            dxje=dxje+dzf+dw;                   }                   if(newstring.length!=1){                            if(newstring.substr(newstring.length-2)=="00"){                                     dxje=dxje+'整';                            }else{                                     dxje=dxje;                            }                                     }                   returndxje;         }                 function showpigresult(){                   varresult=changeMoneyStr(document.form1.money.value);                   document.getElementById("showresult").innerHTML=result;         } </script>


四、    JavaBean技术

a)       String类的 split() 应注意的地方:

1、如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split(".");

2、如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");

“.”和“|”都是转义字符,必须得加"\\";

3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu=? or n=?”,把三个都分隔出来,可以用String.split("and|or");

五、    正则表达式在JAVA中的应用:

Pattern p = Pattern.compile("a*b");Matcher m = p.matcher("aaaaab"); sboolean b = m.matches(); 
在仅使用一次正则表达式时,可以方便地通过此类定义 matches 方法。此方法编译表达式并在单个调用中将输入序列与其匹配。
语句 boolean b = Pattern.matches("a*b","aaaaab");等效于上面的三个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。
此类的实例是不可变的,可供多个并发线程安全使用。Matcher 类的实例用于此目的则不安全。

六、    MySQL数据库

1.选择唯一值:

         selectdistinct * from student;

2.为某一列取别名,不能使用as :

         selectstuScore*0.9 '结果'from student order by stuScore desc;

3.条件查询:

         select* from student where stuAddress!='泾阳';  

4.范围查询:

         select* from student where stuScore between 80 and 100;

5.自增长标识列:

       auto_increment;

6.选择来自一个集合的数据:(当集合中的数据不存在时,不会出现异常!)

         select* from student where stuId in(1,2);

7.识别null数值或isnull :

         select* from student where stuScore is not null;

8.模糊查询:

          select * from student where stuName like'高%';

9.分组条件:(可以不查出stuAddress)

          select * from student group by stuAddress

         having count(*)>3;

10.查询最大值:

          select max(stuScore) '最大分数' from student;

11.实现四舍五入到指定长度:

          select round(100.12345,3);

12.显示当前时间(获取系统的当前时间):

          select now();

13.日期函数:

         selectmonth(),year(),dayofmonth();

         selectdayofmonth(now());

七、    JSP部分:

a)        使用 application内置对象读web.xml 中的参数:

Web.xml 中如下:

<context-param>                   <param-name>driver</param-name>                   <param-value>com.jdbc.mysql.Driver</param-value> </context-param> <context-param>                   <param-name>uri</param-name>                   <param-value>jdbc:mysql://localhost:3306/shopping</param-value>  </context-param>  <context-param>                   <param-name>user</param-name>                   <param-value>root</param-value>  </context-param><context-param>                   <param-name>pwd</param-name>                   <param-value>root</param-value></context-param>


上面就是在 web.xml 中配置将要读取的的全局参数! 下面使用 application 进行读取并显示到页面上:

         Servlet中的代码:

             String driver =getServletContext().getInitParameter("driver");                   Stringuri=getServletContext().getInitParameter("uri");                   Stringuser=getServletContext().getInitParameter("user");                   Stringpwd=getServletContext().getInitParameter("pwd");


   通过上面的连个步骤就可以读取全局变量!

b)           使用 config 对象,读取servlet的参数:

不管是Jsp页面还是servlet, config内置对象代表翻译之后的的 .java 本身!这种方法读取参数的使用场合:字符过滤器:

Serlet 中的配置如下:

<servlet>    <servlet-name>config</servlet-name>    <servlet-class>config</servlet-class>    <init-param>               <param-name>charset</param-name>              <param-value>utf-8</param-value>   </init-param> </servlet>


在serlvet 中的代码如下:

         Stringcharset=this.getServletConfig().getInitParameter("charset");

 

c)        request 对象:

        使用 request.getParameterMap() 可以获取请求的Map 集合对象;使用request应注意以下情况:

           并不是每个表单域都可以生成请求参数的,只有有name属性的表单域才可以生成请求参数的!如果多个表单域的name值相同,则生成一个请求参数;表单域的name属性为请求参数的名,value属性值为请求的值;如果某个表单的disabled=”true”则该表单不在生成请求参数!

       

  Map<String,Object>res=request.getParameterMap();                   Iterator<?>iter=res.keySet().iterator();                   while(iter.hasNext()) {                            Stringstr=iter.next().toString();                            System.out.println(str);   }

         使用如上代码获取请求信息的Map<String,String> 对象!为什么我们在jsp中设置的请求参数,不管是在 jsp中还是在 servlet中都可以获得到;原因就在于;系统将我们的请求参数放入了一个Map,不管是在jsp中还是在 servlet  总我们都是访问的这个map对象;

      

   Stringqstr=request.getQueryString();                   System.out.println(qstr);                   StringstrE=java.net.URLDecoder.decode(qstr,"utf-8");                   System.out.println(strE);                   String []arrayStr=strE.split("&");                   for (Stringstring : arrayStr) {                            System.out.println("每个请求参数的值,对"+string);                            String []subStr=string.split("=");                            System.out.println("名称:"+subStr[0]);                            System.out.println("值"+subStr[1]);  }

         Request 对象的 getQuaryString() 方法,可以获取请求字符串,java.net.Decoder.decode()用于解码(原因是在请求参数中含有非西欧字符的参数,所以要使用java.net.Decoder.decode()进行解码);

         使用getRequestDispatcher(“{0}”).forward()跳转时,要在 0 处的项目资源加 ‘/’;

d)       response 对象:

比较request.getRequestDispatcher().forward(request,response)response.sendRedirect():

Forward 执行完之后还是上一次的请求,而redirect  后生成第二次请求;forward 请求后,目标页面可以访问请求的请求参数,因为是同一个request请求,即所有的请求参数在同一个 request对象中都存在,而使用 redirect 后目标页面不能使用原来的请求参数,因为已经是第二次请求了,那也就是说,request对象的消失,请求的参数就会跟着消失;还有使用 forward 请求 url 中的地址不会改变. 而使用 redirect 会改变为目标的 url;

e)        cookie 的读写:

写入 cookie 对象:ss

//设置临时Cookie

        

   Cookie tempCookie=newCookie("temp","222222");           tempCookie.setMaxAge(-1);   //默认值,不会把 Cookie 保存到硬盘上           response.addCookie(tempCookie);            //设置 MaxAge 为 0 的 Cookie           Cookie cookie=newCookie("cookie","111111");           cookie.setMaxAge(0);  //表示浏览器接受 Cookie  后会被立即删除           response.addCookie(cookie);            //设置永久的 Cookie           Cookie mcookie=newCookie("name","000000");           mcookie.setMaxAge(60*60*24);           response.addCookie(mcookie);

         读取 cookie 对象:

              

  protectedCookie getCookie(Cookie [] cookies,String name){                   if(cookies!=null){                            for(Cookie c : cookies) {                                     if(c.getName().equals(name)){                                               returnc;                                     }                            }                     }                   returnnull;             }              PrintWriter out = response.getWriter();                                     //获得临时的  Cookie                   Cookie temp=getCookie(request.getCookies(),"temp");                   if(temp!=null){                            out.print("临时Cookie的值为:"+temp.getValue());                   }else{                            out.print("没有值!");                   }                    //获取时间为 0 的Cookie,这个 Cookie永远都不可能获得到                   Cookiecookie=getCookie(request.getCookies(), "cookie");                   if(cookie!=null) {                            out.print("MaxAge为零的Cookie:"+cookie.getValue());                   }else {                            out.print("没有值!");                   }                    //获取永久的Cookie                   Cookiename=getCookie(request.getCookies(), "name");                   if(name!=null) {                            out.print("永久Cookie 值:"+name.getValue());                   }else {                            out.print("没有值!");                   }

cookie中写的时候对汉字的处理:

添加之前将字符串使用java.net.URLEncoder.encode("高江涛","utf-8"); 取出来之后将结果java.net.URLDecoder.decode(temp.getValue(),"utf-8");

f)        自定义标签:

传统的Jsp脚本有什么坏处:

                        i.             Jsp 脚本非常丑陋,难以阅读!

                       ii.             Jsp 脚本和 HTML 代码混杂,维护成本高!

                     iii.             HTML 页面中嵌入 Jsp 脚本,导致美工难以参加开发!

 

g)        自定义标签的开发步骤:

                        i.             建立自定义标签的处理类;

                       ii.             建立一个 *.tld 文件,每一 tld文件都对应一个标签库,每个标签库对应多个个标签!

                     iii.             在Jsp 页面上使用自己的标签!

 

h)        .tld 文件的描述(根元素为 tag-lib):

                        i.             tlib-version:标签库的版本,这个对程序的作用不大!

                       ii.             short-name:标签库默认的短名,通常对程序的作用也不大!

                     iii.             uri: 该标签库的uri,指定该标签库的唯一标示;

                     iv.             tag:tag-lib 下可以有多个 tag,每个 tag 都代表一个标签;

 

i)          tag 下的元素描述:

name: 这个非常重要,jsp页面就是根据这个来使用这个标签的;

tag-class: 这个是这个标签的后台处理类!

body-content: 这个属性可以是一下值:tagdependent: 指定标签的处理类,自己负责处理标签体! Empty: 空体标签;scriptless: 该标签里面可以含有静态的 HTML , 表达式语言,但不可以是JSP 脚本! JSP :这个已被忽视;

 

j)          带属性自定义的标签开发:

对于有属性的标签,要为tag添加 attribute 子元素: 每个 attribute 子元素定义一个属性,attribute含有一下子元素:

         Name: 属性的名称;

         Required:设置该属性为必须属性;

         Fragment:是否支持Jsp脚本等动态内容!s

k)        在页面上使用自己定义的标签:

<%@ taglib uri="http://xabc.net"prefix="mytag" %>

 

带体的标签:

Collection<?>itemList=(Collection<?>)getJspContext().getAttribute(this.getCollection());         for (Object object : itemList) {            getJspContext().setAttribute(this.getItem(),object);            getJspBody().invoke(null);}

g)      过滤器:

a)         过滤器的使用场合:

                        i.             权限过滤;

                       ii.             日志过滤;

                     iii.             非法IP过滤;

                     iv.             字符集过滤;

 

b)        创建过滤器的后台处理类,实现Filter接口,实现如下方法:

                        i.             init(FilterConfigconfig); 用于对过滤器的初始化;

                       ii.             defiler(ServletRequestrequest,SerletResponse response,FilterChain chain);用于将请求继续传递;

                     iii.             destroy():用于在 Filter 销毁之前将某些资源回收!

c)         在 web.xml 下如下配置:

<filter>        <filter-name>filter</filter-name>        <filter-class>util.DoFilter</filter-class>        <init-param>            <param-name>endoding</param-name>            <param-value>utf-8</param-value>        </init-param>              <init-param>            <param-name>fristPage</param-name>            <param-value>index.jsp</param-value>        </init-param>        <init-param>            <param-name>IP</param-name>            <param-value>127.0.0.2</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>filter</filter-name>        <url-pattern>/*</url-pattern></filter-mapping>


 

* 过滤器主要是对用户的请求进行预处理,也可以对 HttpServletResponse进行后处理!

 

过滤器的核心代码:

public void doFilter(ServletRequest request,ServletResponse response,           FilterChainchain) throws IOException, ServletException {           request.setCharacterEncoding(this.encoding);           HttpServletRequesthrequest=(HttpServletRequest)request;           HttpServletResponsehresponse=(HttpServletResponse)response;           Stringspath=hrequest.getServletPath();//获取请求的路径           Stringip=hrequest.getLocalAddr();//获取请求的IP           if(!ip.equals(this.IP)) {                    if(!spath.endsWith(this.firstpage)) {request.getRequestDispatcher(this.firstpage).forward(hrequest,hresponse);                    }else{                             chain.doFilter(hrequest,hresponse);                    }           }else{                    hrequest.setAttribute("msg","<scriptlanguage='javascript'>window.alert('您被限制了!')</script>");                    hrequest.getRequestDispatcher("error.jsp").forward(hrequest,hresponse);           }}


 

h)      监听器:

a)         使用 Listener 的步骤:

                        i.             创建 Listener 实现类,实现ServeltContextListener 接口;包含一下方法:

1.          contextInitialized (ServletContextEvent sce): 启动web应用时,系统调用的方法;

2.         contextDestroyed(ServletContextEvent sce): 关闭 web 应用时,系统调用的方法;

                       ii.             在web.xml 中配置如下:

<listener>       <listener-class>util.Listener</listener-class></listener>


      监听器如 servlet的 load-on-startup一样,但是比servlet的 load-on-startup 执行的还早,还有监听器不负责处理及相应用户的请求; 还有监听器在web.xml 下配置的时候无需配置参数,所访问的参数为全局共有参数。

 

v)       JSP中表达式语言(Expressionlanguage)

a)         ${1+2}: 前加 ‘ \’ 表示此EL 表达式不被解析;

b)        表达式语言的内置对象:

                        i.             pageContext:代表页面的 pageContext 对象,与JSP中的PageContext相同;

                       ii.             pageScope:获取page 范围内的属性;

                     iii.             requestScope:获取 request 范围内的属性;

                     iv.             sessionScope: 获取 session 范围内的属性;

                       v.             applicationScope: 获取 application 范围内的属性;

                     vi.             param :用于获取请求参数;

                    vii.             paramValues:用于获取请求的参数,与param不同的是该对象是用于获取返回值为数组的参数;

                  viii.             header:用于获取请求头信息;

                     ix.             headerValues: 用于获取请求头信息; 与header不同的是该对象是用于获取返回值为数组的请求参数;

                       x.             initParam:用于获取有 web 应用初始化的参数;

                     xi.             cookie:用于获取指定 cookie 的值;

i)       EL的自定义函数:

                        i.             自定义表达式语言与自定义标签类似;步骤分为:

1.         开发 EL函数处理类,这个类中的方法要求是静态的方法;

2.         建立tld 文件,tld 文件的描述:

name: 指定了函数的名称;

function-class: 函数对应的处理类;

function-signature: 指定函数的实现方法;

3.         使用该函数;

<%@ taglib uri="http://xabc.com"prefix="fn"  %>    ii. public staticString reverse(String str){                   returnnew StringBuffer(str).reverse().toString();         }         publicint  countChar(String text){                   returntext.length();         }   <function>                        <name>reverse</name>                        <function-class>demo.myfunction</function-class>                        <function-signature>                                 java.lang.Stringreverse(java.lang.String)                        </function-signature>   </function>     <function>               <name>countChar</name>               <function-class>demo.myfunction</function-class>               <function-signature>                        intcountChar(java.lang.String)               </function-signature></function>


 

八、   ajax中dwr框架的使用:

   a. 配置dwr.xml:

 <dwr>         <allow>                   <createcreator="new" javascript="JCheckName">                            <paramvalue = "net.xabc.bbs.biz.UserBiz" name ="class"/>                            <include  method ="checkName"/>                   </create>         </allow>    </dwr>

    b.配置 web.xml:

      

 <servlet>                   <servlet-name>dwr</servlet-name>                   <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>                   <init-param>                            <param-name>debug</param-name>                            <param-value>true</param-value>                   </init-param>         </servlet>         <servlet-mapping>                   <servlet-name>dwr</servlet-name>                   <url-pattern>/dwr/*</url-pattern>  </servlet-mapping>

   c.在js中设置回调函数:

  

 functioncheckName(){         var name= document.getElementById("uName").value;         JCheckName.checkName(name,checkUserName);       }

九、 Struts2技术应用:s

1.      Struts2上传文件:

 

原理:

Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。

Web.xml 下的配置:

 

< filter >         < filter-name > struts-cleanup </filter-name >         < filter-class >            org.apache.struts2.dispatcher.ActionContextCleanUp        </ filter-class >     </ filter >         < filter >         < filter-name > struts2 </ filter-name>         < filter-class >             org.apache.struts2.dispatcher.FilterDispatcher        </ filter-class >     </ filter >         < filter-mapping >         < filter-name > struts-cleanup </filter-name >         < url-pattern > /* </ url-pattern >     </ filter-mapping >     < filter-mapping >         < filter-name > struts2 </ filter-name>         < url-pattern > /* </ url-pattern >     </ filter-mapping >


 

org.apache.struts2.dispatcher.ActionContextCleanUp 在 struts 是对org.apache.struts2.dispatcher.FilterDispatcher 的一个补充,在做上传文件加上这个配置时,上传文件就万无一失了!

 

Struts.xml中的配置:

< action name ="fileUpload" class="tutorial.FileUploadAction" >            < interceptor-refname ="fileUpload" >                < param name="allowedTypes" >                   image/bmp,image/png,image/gif,image/jpeg                </ param >            </ interceptor-ref>            < interceptor-refname ="defaultStack" />                       < result name="input" > /FileUpload.jsp </ result >            < result name="success" > /ShowUpload.jsp </ result >        </ action >


 

通过在 strust.xml 中拦截器的配置,可以限制上传文件的大小和类型!但是如果在一个 Action 中配置拦截器,那么要在引用一次默认的拦截器栈!

在程序中:

private List<File> photo;private List<String> photoContentType;private List<String>photoFileName;private String savePath;


这四个属性是必须的并且为他提供 get,setter 方法,这几个属性是 struts 框架自动为其赋值的!

 

九、Struts2 的输入验证:

 

基本原理:

 

遇到类型转换错误的时候(也就是说不能进行类型转换),struts2框架自动生成一条错误信息,并且将该错误信息放到addFieldError里面

 

类型转换与输入校验的流程

 

1. 首先Struts2对客户端传来的数据进行类型转换

 

2. 类型转换完毕后再进行输入校验

 

3. 如果类型转换和输入校验都没有错误发生,那么进入execute方法(调用商业逻辑)

 

注意:如果类型转换不成功,也同样要进行输入校验!

 

xxx-validation.xml中的一段配置:

<field name="username">            <field-validatortype="requiredstring">                     <paramname="trim">true</param>                     <message>${getText('name.requied')}</message>            </field-validator>            <field-validatortype="regex">                     <paramname="expression"><![CDATA[(\w{4,25})]]></param>                     <message>${getText('name.regex')}</message>            </field-validator>   </field>   <fieldname="password">            <field-validatortype="requiredstring">                     <paramname="trim">true</param>                     <message >${getText('pass.required')}</message>            </field-validator>            <field-validatortype="regex">                     <paramname="expression"><![CDATA[(\w{4,25})]]></param>                     <message>${getText('pass.regex')}</message>            </field-validator>   </field>   <fieldname="age">            <field-validatortype="int">                     <paramname="max">150</param>                     <paramname="min">0</param>                     <message  >${getText('age.range')}</message>            </field-validator>   </field>   <fieldname="birthday">              <field-validatortype="date">                     <paramname="min">1900-01-01</param>                     <paramname="max">2050-02-21</param>                     <message>${getText('birth.range')}</message>            </field-validator></field> 


使用 ${getText(‘ xxx’)}获取国际化资源文件!这段配置存在于 classpath 目录下 XXXXX-validation.xml 中!xxxx表示处理逻辑的 Action;

 

自动搜索:

如果在一个action中有多个业务,struts支持 效验文件自动搜索规则;如:UserAction-login-validation.xml;UserAction 是处理业务的Aciton, login 是登录的方法!struts2搜索规则是从上到下的,实际上用的效验规则是所有的效验规则总和;如果在两个效验文件中指定的效验规则发生了冲突,则后面的的取胜!

 

校验器的配置风格:

A.       字段效验风格:

<field name="username">                   <field-validatortype="requiredstring">                            <paramname="trim">true</param>                            <message>${getText('name.requied')}</message>                   </field-validator>                   <field-validatortype="regex">                            <paramname="expression"><![CDATA[(\w{4,25})]]></param>                            <message>${getText('name.regex')}</message>                   </field-validator></field>

B.       非字段效验风格:

 

<validator type="regex">                   <paramname="fieldName">username</param>                   <paramname="trim">true</param>                   <paramname="expression"><![CDATA[(\w[4,25])]]></param>                   <message>${getText('username.required')}</message></validator>

注意:如果使用非字段效验风格的话,必须指定 filedName 属性!

 

短路校验器:

             通过在<field>  </field>或 <validator></validator > 中配置short-circuit设置该校验是否为短路效验器!改值默认为 false(非);

 

 Struts2 中所有的内建校验器:

 

A.       必填校验器:

<field name="username">                   <field-validatortype="required">                            <message>userNameto be not  null!</message>                   </field-validator></field>


B.       必填字符串校验器:

 <field name="username">                   <field-validatortype="requiredstring">                            <paramname="trim">true</param>                            <message>请填写用户名!</message>                   </field-validator></field>


注:该校验器有一个属性 trim表示是否在校验前清空前后的空格;默认为true;

 

C.       整数校验器:

<validator type="int">                   <paramname="fieldName">age</param>                   <paramname="max">150</param>                   <paramname="min">0</param>                   <message>年龄必须在 0-150 岁之间!</message></validator>

注:该校验器采用的是非字段配置风格,配置的;整数效验器有两个属性 max 和min,最大和最小值!

 

D.       日期校验器:

      

   <validator type="date">                   <paramname="fieldName">birthday</param>                   <paramname="max">2050-02-01</param>                   <paramname="min">1990-01-01</param>                   <message>对不起,您的生日超范围了!</message>   </validator>

         注:max和min指的是最大和最小!

 

E.       表达式校验器:

<validator type="expression">                   <paramname="expression">1==1</param>                   <message>正确!</message></validator>

注:该校验器只能使用非字段校验器风格!

 

F.       字段表达式校验器:

<validator type="fieldexpression">                   <paramname="fieldName">pass</param>                   <paramname="expression"><![CDATA[(pass==repass)]]></param>                   <message>原密码要和重复密码相同!</message></validator>

G.       网址校验器:

<validator type="url">                   <paramname="fieldName">url</param>                   <message>您的主页必须是一个有效的网址!</message></validator>

H.       字符串长度校验器:

 

<validator type="stringlength">                   <paramname="fieldName">username</param>                   <paramname="maxLength">10</param>                   <paramname="minLength">1</param>                   <message>长度必须在 1-10 之间!</message></validator>

 

I.        正则表达式校验器:

<validator type="regex">                   <paramname="fieldName">username</param>                   <paramname="expression"><![CDATA[(\w{4,25})]]></param>                   <paramname="caseSensitive">false</param>                   <message>请填写正确格式的用户名!</message></validator>

注:在这个校验器中 caseSensitive表示: 在做效验的时候是否区分大小写,默认为 true,区分大小写!

 

在程序中验证:

             重写父类的validate 方法,如果在一个action 中,存在多个业务逻辑的处理方法,那么就要为其提供 validateXxx() 方法;如果使这种情况的话,建议不要在出现父类的 validate() 方法,以为如果有父类的validate()时,struts2 的验证顺序为类型转换 validateXxx() ,validate() ;

 

在程序中使用 ActionError,如果使用了 ActionError 的话,建议将form的 theme 属性设置为 simple;在页面上使用 <s:actionErrors/> 标签显示! 如果使用 fieldError时,在页面上使用<s:fieldErrors/>标签来显示信息!

 

值得注意的是ActionError在底层时放入到 List 中,而FieldError 时放入到 Map 中的!

 

一般情况下如果效验不是太复杂的话,我们都是配置文件的方式完成输入效验!但是对于配置文件难以解决校验我们重写 ActionSupport 类的 validate() 方法! 但是配置文件和 重写父类的validate() 方法建议不要同时使用!

 

2.      Struts2 核心拦截器

A.       struts2 的拦截器是根据 aop的思想设计的,实现aop有两种方式 dynamic prox 和  cglib; 拦截器的出现满足了我们对 dry 的实现!

关于动态代理的一段关键代码:

        

 Proxy.newProxyInstance(UserAction.class.getClassLoader(),                                     newClass[] { IAction.class }, hander);public Object invoke(Object proxy,Method method, Object[] args)                       throwsThrowable {             Objectobj=null;             if("execute".equals(method.getName())) {                       doService.Inteceptor();                       obj=  method.invoke(actionService, args);                       doService.Inteceptor();             }else{                       obj=method.invoke(actionService,args);             }             returnobj;   }

 

B.       struts2中实现一个拦截器的几种方式:

实现 Interceptor 接口;

继承 DefaultInterceptor 类;

继承MethodFilterInterceptor 类(方法过滤拦截器);

 

C.       拦截器在struts.xml中的配置:

首先在 struts.xml 中注册拦截器:

    <interceptors>                            <interceptorname="" class=""></interceptor>   </interceptors>


拦截器栈和拦截器在struts.xml 中没有太大的区别 (从宏观角度上看!)

然后在Action中引用:

<interceptor-refname="MyInterceptor3">                                <paramname="includeMethods">userlogin</param> </interceptor-ref><interceptor-refname="defaultStack"></interceptor-ref>

如果配置了多个拦截器引用,执行的顺序是从上到下! 在这里还可以配置参数,在Action中引用时注册的参数会覆盖注册时的参数值,并且这些参数会自动封装到 Inteceptor中;

十、Spring 技术应用:

1.       Spring 的配置文件:

配置文件的名称可以为多个,并且名称随便给! 最后通过ClassPathXmlApplicationContext的构造函数传入配置文件的路径;

为了减少配置文件的字节,一般可采取两种方案: 使用通配符或者写多个配置文件,最后通过如上方式引入!但是在多个配置文件中应注意的是:不能出现相同的Id名称!

         按名称自动装载,或按类型自动装载!

使用 <import /> 在配置文件中导入!<importresource="applicationContext.xml"/>

2.       构造注入:

<bean id="gaojiangtao"class="entity.User">        <constructor-arg index="0">            <value>高江涛</value>        </constructor-arg>        <constructor-arg index="1">            <value>男</value>        </constructor-arg>        <constructor-arg index="2">            <value>18</value>        </constructor-arg>        <constructor-arg index="3">            <value>泾阳</value>        </constructor-arg>        <constructor-arg index="4">            <value>770212507</value>        </constructor-arg></bean>
  使用构造器注入时,使用 index(参数索引为 Spring 官方推荐的构造其注入用法);

 

3.       普通属性注入:

<property name="list">                   <list>                       <value>list1</value>                       <value>list2</value>                       <value>list3</value>                   </list>              </property>              <property name="set">                   <set>                       <value>set1</value>                       <value>set2</value>                       <value>set3</value>                   </set>              </property>              <property name="array">                   <list>                       <value>array1</value>                       <value>array2</value>                       <value>array3</value>                   </list>              </property>              <property name="map">                   <map>                       <entry key="k1" value="v1"/>                       <entry key="k2"value="v2"></entry>                   </map>         </property>


以上是几种常见的集合的注入!

 

5.       属性编辑器:

首先定义属性编辑器后台类,继承PropertyEditorSupport, Java.beans 包下的;重写它的 setAsText()方法,在方法中类型转换完成之后,通过 this.setValue()方法保存;

然后在 Spring 配置文件中注册:

<bean id="propertyEdit"class="org.springframework.beans.factory.config.CustomEditorConfigurer">                           <propertyname="customEditors">                                         <map>                                                       <entrykey="java.util.Date">                                                                     <beanclass="net.xabc.entity.PropertyEdit"></bean>                                                       </entry>                                  </map>                    </property>              </bean>

通过以上的注册,Spring就会知道把相应的类型进行转换!

 

6.       几种初始化 Ioc 容器的方式:

ClassPathResourceresource=new ClassPathResource("applicationContext.xml");BeanFactoryfactory=new XmlBeanFactory(resource); Resourceresource=new FileSystemResource("E:\\applicationContext.xml");BeanFactoryfactory=new XmlBeanFactory(resource); ApplicationContextact=new ClassPathXmlApplicationContext("applicationContext.xml");

7.       采用静态工厂方法或者实例工厂方法创建对象:

 

静态工厂方法:

<bean id="gaojiangtao" class="entity.factory"factory-method="createUser">  

要求createUser方法必须为静态的!

实例工厂方法:

<beanid="createuser" class="entity.factory"></bean><beanid="gaojiangtao" factory-bean="createuser"  factory-method="createUser"></bean> 

8.       名称自动装备 和 类型自动装备:

     名称自动装备就是:如果一个类中的一个属性为 user时, 在配置文件中,我们没有为这个user属性设置它的引用! 那么 Spring就会自动在所有的Id中找 Id 为user的<bean> 如果找到了,Spring 容器自动添加其引用!(default-autowire="byName")

           类型自动装备就是,Spring容器会在配置文件中找 Spring 为 user 对应的类型,

找到了会自动添加其引用 !(default-autowire="byType")

        

9.       采用 aspectJ 的 annocaton 方式实现aop:

a)         spring依赖库

   * SPRING_HOME/dist/spring.jar

   * SPRING_HOME/lib/jakarta-commons/commons-logging.jar

   * SPRING_HOME/lib/log4j/log4j-1.2.14.jar

   * SPRING_HOME/lib/aspectj/*.jar

b)        采用Aspect定义切面

 

c)         在Aspect定义Pointcut和Advice

 

d)        启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中

<aop:aspectj-autoproxy/>

 

e)         注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点

即Advice中通过方法名引用这个切人点

 

10.   采用静态文件实现 aop:

首先,定义切面类!然后在配置文件中注册配置的切面类!

<aop:config>            <aop:aspect id="aspectTransaction"ref="transactionHander">                     <aop:pointcut id="transaction"expression="execution(* staticFile.*.add*(..))"/>                     <aop:beforemethod="startTransaction" pointcut-ref="transaction"/>                     <aop:aftermethod="closeTransaction" pointcut-ref="transaction"/>            </aop:aspect> </aop:config>

注意:

Aspect默认情况下不用实现接口,但对于目标对象,在默认情况下必须实现接口

如果没有实现接口必须引入CGLIB库!

我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得参数值、方法名等等!

 

11.   Java的动态代理,以及 CGLIB对aspectj 实现 aop 的支持:

 

如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

如果目标对象实现了接口,可以强制使用CGLIB实现AOP

如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

 

如何强制使用CGLIB实现AOP

添加CGLIB库,SPRING_HOME/cglib/*.jar

在spring配置文件中加入<aop:aspectj-autoproxyproxy-target-class="true"/>

      

JDK动态代理和CGLIB字节码生成的区别?

JDK动态代理只能对实现了接口的类生成代理,而不能针对类

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法

因为是继承,所以该类或方法最好不要声明成final 

             

12.    SSH集成(第一种集成方案):

 

原理:在Action中取得BeanFactory对象,然后通过BeanFactory获取业务逻辑对象

 

1springstruts依赖库配置

* 配置struts

          --拷贝struts类库和jstl类库

          --修改web.xml文件来配置ActionServlet

          --提供struts-config.xml文件

          --提供国际化资源文件

* 配置spring

          --拷贝spring类库

          --提供spring配置文件

         

2、在strutsAction中调用如下代码取得BeanFactory

BeanFactoryfactory =WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());

3、通过BeanFactory取得业务对象,调用业务逻辑方法

13.   采用声明式事务:

 

a、声明式事务配置

       * 配置SessionFactory

              <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">                            <propertyname="configLocation">                                          <value>classpath:hibernate.cfg.xml</value>                            </property>              </bean>

         * 配置事务管理器

           

    <bean id="transactionProxy" class="org.springframework.orm.hibernate3.HibernateTransactionManager">                            <propertyname="sessionFactory"ref="sessionFactory"></property>    </bean>

         * 配置事务的传播特性

         <tx:advice id="txadvice"transaction-manager="transactionProxy">                   <tx:attributes>                            <tx:method name="add*"propagation="REQUIRED"/>                            <tx:method name="update*"propagation="REQUIRED"/>                            <tx:method name="delete*"propagation="REQUIRED"/>                            <tx:method name="*"read-only="true"/>                   </tx:attributes>         </tx:advice>

         * 配置那些类那些方法使用事务

          

         <aop:config>                   <aop:pointcut id="allMethod"expression="execution(* net.xabc.hr.biz.impl.*.* (..))"/>                   <aop:advisor advice-ref="txadvice"pointcut-ref="allMethod"/>         </aop:config>

 

b、编写业务逻辑方法

       * 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是

           Hibernate Session的轻量级封装

         * 默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的

         * 编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理

         * 关于事务边界的设置,通常设置到业务层,不要添加到Dao上 

 

c、了解事务的几种传播特性

 

       1.      PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启

         2.      PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行

         3.      PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

         4.      PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

         5.      PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。

         6.      PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常

         7.      PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,

              则按TransactionDefinition.PROPAGATION_REQUIRED属性执行

 

dSpring事务的隔离级别

       1.           ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.

                   另外四个与JDBC的隔离级别相对应

              2.           ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。

                   这种隔离级别会产生脏读,不可重复读和幻像读。

              3.           ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

              4.           ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

                   它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

              5.           ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

                   除了防止脏读,不可重复读外,还避免了幻像读。

 

14.   Spring中的任务调度:

a)       Java Timer 调度器:

需继承 TimerTask 类,重写 run() 方法;

           

           <bean id="testTask"     class="org.rongxin.springtest.time.Task.TestTask"/>          <bean id="scheduledTestTask"    class="org.springframework.scheduling.timer.ScheduledTimerTask">              <property name="timerTask">                  <ref bean="testTask" />              </property>              <property name="period">                   <value>10000</value>  //间隔时间              </property>              <property name="delay">                  <value>2000</value>  //懒执行的时间  (都是以毫秒为单位)              </property>          </bean>          <beanid="timeFactory"  class="org.springframework.scheduling.timer.TimerFactoryBean">                  <property name="scheduledTimerTasks">                       <refbean="scheduledTestTask" />                  </property>          </bean>

b)       Quartz(opensymphon) 调度器:

继承QuartzJobBean,必须要  quartz-1.5.2.jar ! 重写它的 executeInternal 方法!

<bean id="jobDetail"   class="org.springframework.scheduling.quartz.JobDetailBean">   //任务的详细信息            <propertyname="jobClass">                     <value>org.rongxin.springtest.time.Task.QuartzJob</value>            </property>            <propertyname="jobDataAsMap">                     <map>                               <entrykey="fristDate">                                        <beanclass="java.util.Date" />                               </entry>                     </map>            </property></bean>


//间隔多少时间执行任务

   <beanid="simpleTrigger"    class="org.springframework.scheduling.quartz.SimpleTriggerBean">            <propertyname="jobDetail">                     <refbean="jobDetail" />            </property>            <propertyname="startDelay" value="2000" />            <propertyname="repeatInterval" value="2000" />   </bean>


//到什么时间执行任务

<beanid="cronTrigger"            class="org.springframework.scheduling.quartz.CronTriggerBean">            <propertyname="jobDetail" ref="jobDetail" />            <propertyname="cronExpression">                     <value>** * * * ?</value>  //? 是星期天不必设置!  * 代表任意            </property></bean><beanid="quartFactory"    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">            <propertyname="triggers">                     <refbean="cronTrigger"/>            </property> </bean>

十一、     Hibernate介绍:

一般应用中常用到五个接口

1.configaction

通过这个接口的实例来找到映射配置文件的信息,然后根据里面的映射信息创建sessionFactory对象

 

2.session

管理增删改差五个方法

一个应用程序中可以有多个session实例,可以随时销毁,因为它占用资源小,被称为第一插件

 

3.sessionFactory

线程是安全的,它的同一个实例可以给多个线程调用

它的实例是重量级的,不能随意销毁

负责实力所有的session对象,一般一个应用程序中只能有一个SESSIONFACTORY,因为它占用的系统资源过大!

称为hibernate的第二插件

 

4.query和criteria

执行hibernate查询方法的接口,它包装了一个HQL查询语句,criteria完全封装了字符串形式的查询语句,比QUERY更加面向对象,一般用于动态查询。他们功能比session中的find()方法强大许多,因为find()方法只能执行一些简单的,单一对象的查询

5.Transaction

管理事务接口

 

十二、     SSH 集成:

第一种集成方案:

 

原理:在Action中取得BeanFactory对象,然后通过BeanFactory获取业务逻辑对象

 

aspringstruts依赖库配置

   * 配置struts

            --拷贝struts类库和jstl类库

            --修改web.xml文件来配置ActionServlet

            --提供struts-config.xml文件

            --提供国际化资源文件

   * 配置spring

            --拷贝spring类库

            --提供spring配置文件

         

b、在strutsAction中调用如下代码取得BeanFactory

BeanFactoryfactory =WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());

c、通过BeanFactory取得业务对象,调用业务逻辑方法


(第二种集成方案):

原理:将业务逻辑对象通过spring注入到Action中,从而避免了在Action类中的直接代码查询

 

aspringstruts依赖库配置

       * 配置struts

                   --拷贝struts类库和jstl类库

                   --修改web.xml文件来配置ActionServlet

        <context-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath*:applicationContext-*.xml</param-value>        </context-param>          <listener>                 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>        </listener>

                   --提供struts-config.xml文件

                   --提供国际化资源文件

         * 配置spring

                   --拷贝spring类库

                   --提供spring配置文件

b、因为Action需要调用业务逻辑方法,所以需要在Action中提供setter方法,让spring将业务逻辑对象注入过来

 

c、在struts-config.xml文件中配置Action

      * <action>标签中的type属性需要修改为org.springframework.web.struts.DelegatingActionProxy

          DelegatingActionProxy是一个Action,主要作用是取得BeanFactory,然后根据<action>中的path属性值

          到IoC容器中取得本次请求对应的Action

       

d、在spring配置文件中需要定义strutsAction如:

          

      <beanname="/login" class="com.bjsxt.usermgr.actions.LoginAction"scope="prototype">                   <property name="userManager"ref="userManager"/>      </bean>

         * 必须使用name属性,name属性值必须和struts-config.xml文件中<action>标签的path属性值一致

         * 必须注入业务逻辑对象

         * 建议将scope设置为prototype,这样就避免了struts Action的线程安全问题

 

Srping 中声明式事务的配置:

<!--SessionFactory -->

   <bean id="sessionFatory"            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">            <propertyname="configLocation">                     <value>classpath:hibernate.cfg.xml</value>            </property>   </bean>

   <!-- 配置抽象bean-->

  <bean id="basedao"abstract="true">            <propertyname="sessionFactory" ref="sessionFatory" />   </bean>

   

   <!-- 配置事务管理器-->

 

  <bean id="transactionProxy"class="org.springframework.orm.hibernate3.HibernateTransactionManager">            <propertyname="sessionFactory"ref="sessionFatory"></property>   </bean>

   <!-- 配置事务的传播特性 -->

   <tx:advice id="txadvice"transaction-manager="transactionProxy">            <tx:attributes>                     <tx:methodname="add*" propagation="REQUIRED"/>                     <tx:methodname="update*" propagation="REQUIRED"/>                     <tx:methodname="delete*" propagation="REQUIRED"/>                     <tx:methodname="*" read-only="true"/>            </tx:attributes>   </tx:advice>

   <!-- 配置那些类需要声明事务 -->

   <aop:config>            <aop:pointcutid="allMethod" expression="execution(* org.rongxin.hr.basic.dao.impl.*.*(..))"/>            <aop:advisorpointcut-ref="allMethod" advice-ref="txadvice" />   </aop:config>

 

 

 

 

0 0
原创粉丝点击