jsp基礎知識03-2

honghu79 13年前發布 | 2K 次閱讀 google應用商城
       
提交表單的時候能否提交中文,提交中文有亂碼出現
方法1:可以在ActionServlet中的service方法中加上:request.setCharaterEncoding("utf-8");
方法2:過濾器

過濾器
 過濾器鏈
 過濾器應該怎么用呢>
 首先我們先創建一個類CharacterEncodingFilter讓他繼承javax.servlet.Filter
 實現其主要的方法
CharacterEncodingFilter類
 
package org.whatisjava.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CharacterEncodingFilter implements Filter {
 public void destroy() {
  //做一些收尾工作
  
 }
 public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
  //注意這里是ServletRequest不是HttpServletRequest,這是sun公司的一個做的擴展的東西
  //過渡設計的產物,在應用的時候可以直接轉換成
  HttpServletRequest req=(HttpServletRequest)request;
  HttpServletResponse resp=(HttpServletResponse)response;
  req.setCharacterEncoding("utf-8");
  //FilterChain意思是過濾器鏈
  //將請求和響應傳給后面的組件
  
  chain.doFilter(request, response);
  //類似于方法調用,執行完上面這句之后,接著會執行下面代碼
  
  //記住還要聲明一下,讓tomcat知道這個過濾器是攔在誰前面的;
  //怎么聲明呢?在web.xml文件中聲明filter,filter-mapping
  //最典型的例子,如論壇注冊時,名字正規性,
  //必須調用該方法才能往下傳
  //比如安全日志
  //存在多個filter時,看filter-mapping在web.xml文件中的先后順序
  
  
 }
 public void init(FilterConfig config) throws ServletException {
  //類的對象在創建的時候使用
  //相當于初始化狀態
 }
}
 
 
修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
 <filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>org.whatisjava.filter.CharacterEncodingFilter</filter-class>
 </filter>
 <filter>
  <filter-name>LoggingFilter</filter-name>
  <filter-class>org.whatisjava.filter.LoggingFilter</filter-class>
 </filter>
 
 
 <filter-mapping>
  <filter-name>LoggingFilter</filter-name>
  <url-pattern>*.action</url-pattern>
 </filter-mapping>
 <filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>*.action</url-pattern>
 </filter-mapping>
 
 
 <servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>
   org.smartstruts.action.ActionServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet>
  <servlet-name>ImageServlet</servlet-name>
  <servlet-class>
   org.whatisjava.servlet.ImageServlet
  </servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.action</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>ImageServlet</servlet-name>
  <url-pattern>/image</url-pattern>
 </servlet-mapping>
</web-app>
 
 
LoggingFilter類
 
package org.whatisjava.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoggingFilter implements Filter {
 public void destroy() {
  // TODO Auto-generated method stub
 }
 public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
  // TODO Auto-generated method stub
  HttpServletRequest req=(HttpServletRequest)request;
  HttpServletResponse resp=(HttpServletResponse)response;
  
  String clientIp=req.getRemoteAddr();
  int clientPort=req.getRemotePort();
  String uri=req.getRequestURI();
  long time=System.currentTimeMillis();
  
  //req.getServerName();
  //req.getServerPort();
  
  chain.doFilter(request, response);
  
  time=System.currentTimeMillis()-time;
  System.out.println(clientIp+"****"+uri+"***"+time);
  
  
  
  
 }
 public void init(FilterConfig arg0) throws ServletException {
  // TODO Auto-generated method stub
 }
}
 
 
總結:
 可變對象   引用
 不可變對象  string ,Integer
 session.setAttribute();如果是可變對象,則只需要set一遍就行
 如果是不可變對象,則需要重復set
 
對struts-config文件再進行一些小修改:
smartstruts-config.xml
<global-forwards>
  <forward name="" path="" redirect=""/>
</global-forwards>

四、標記庫
在一個項目里面可能存在多個重復的信息,假設這個信息需要變更時
 怎么能快速修改呢?
 
 可以把它們放到一個屬性文件里面〉
  user=User Name
  user_error=user and passowrd is error.
package test;
import java.util.Enumeration;
import java.util.ResourceBundle;
public class TestResource {
 public static void main(String [] args) throws Exception{
 ResourceBundle rb=ResourceBundle.getBundle("res");
 
 //ResourceBundle是JDK中專門用來讀取屬性文件的鍵值對的
 //"res"為擴展名
 
 String value=rb.getString("user");
 //getString取的是鍵,返回的是值
 System.out.println(value); 
 
 Enumeration en=rb.getKeys();
 //Enumeriation
 //Iterator迭代器已經將Enumeriation
 //屬性文件不能識別中文
 //那么如何將屬性值弄成中文呢?
 
 //通過native2ascii來進行轉換
 
 while (en.hasMoreElements()){
  en.nextElement();
  //System.out.println(en.toString()); 
  //System.out.println(en);
  System.out.println(value);
 }
 //System.out.println(value);
 }
}
這樣也有利于國際化
 
標記庫,怎么做?
  1、首先設計一個標記庫
   <hello  num="100" value="..."/>===>功能描述,輸出value里面的內容num次;
  2、寫一個類
   HelloTag extend SimpleTagSupport
   定義
    num
    value
   重寫父類的doTag(){}方法
package org.smartstruts.taglib.bean;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class HelloTag extends SimpleTagSupport {
 private int num;
 private String value;
 public HelloTag(){
  System.out.println("HelloTag...");
 }
 
 public int getNum() {
  return num;
 }
 public void setNum(int num) {
  System.out.println("setNum"+num);
  this.num = num;
 }
 public String getValue() {
  return value;
 }
 public void setValue(String value) {
  System.out.println("setValue"+value);
  this.value = value;
 }
 @Override
 public void doTag() throws JspException, IOException {
  // 必須要重寫父類的方法
  System.out.println("Tag...");
  JspContext jspCtx=this.getJspContext();
  //getJspCcontext方法是simpleTagSupport的方法
  
  PageContext ctx=(PageContext)jspCtx;
  
  //jsp引擎把jsp頁面轉換成一個servlet(上面聲明一些內建對象)
  //大多數內建對象都是servlet的api
  //PageContext是專門為創建的對象
  //PageContext的一種能力:往setXxxx,可以設置數據或者提取數據
  //還封裝了對其他內建對象的引用,out,session,request,pageContext
  JspWriter out=ctx.getOut();
  for (int i=1;i<num;i++){
   System.out.println(value+" ");
  }
 
  
  super.doTag();
 }
 
 
}
 
   但是由于jsp引擎工作,可以使得我們jsp頁面可以調用doTag,可以獲取一個重要的PageContext對象
  PageContext除了有setAttribute,getAttribute,還可以獲取其它的內建對象,也就可以做任何關于web方面的事情
    比如html,session,request等。
  3、在web-inf目錄下新建一個文件hello.tld
  如:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib 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 web-jsptaglibrary_2_0.xsd"
    version="2.0">
 
  <display-name>Test</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>test</short-name>
 
  <tag>
    <name>hello</name>
    <tag-class>org.smartstruts.taglib.bean.HelloTag</tag-class>
    <body-content>empty</body-content>
    <!--body-content>這里可以寫兩種:JSP/empty</body-content>-->
    <attribute>
        <name>num</name>
        <required>true</required><!--用戶是否必須得填寫這個屬性-->
        <rtexprvalue>false</rtexprvalue>
    </attribute>   
    <attribute>
        <name>value</name>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>
</taglib>

 最好的是把全局的資源配置文件放到servlet的application里面
 
 MessageResources
 

*********************************************************************
1、config.xml文件
 添加屬性
  <message-resources  parameter="res">
  指定參數文件的路徑,不包含擴展名properties
2、rule.xml文件跟著變更:  
 <pattern value="message-resources">
   <object-create-rule
    classname="org.whatisjava.controller.MessageResources" />
   <set-next-rule methodname="setMessageResources" />
   <set-properties-rule />
  </pattern>
3、做一個類:MessageResources
 其屬性為:parameter,提供get,set方法
4、StrutsConfig文件變更:增加MessageResources屬性,get,set方法
5、ActionServlet初始化的時候也把res資源文件初始化好,并把他放到大家能訪問的地方
 
  
 private void initResources(){
  //首先要創建一個對象能存放讀入的res資源文件內容
  Map messages=new HashMap();
  //String resName=config.getMessageResources().getParameter();
  MessageResources mr=config.getMessageResources();
  if (mr!=null){
   
  String resName=mr.getParameter();  
  ResourceBundle rb=ResourceBundle.getBundle(resName);
  
  Enumeration en=rb.getKeys();
  //Enumeriation
  //Iterator迭代器已經將Enumeriation
  //屬性文件不能識別中文
  //那么如何將屬性值弄成中文呢?
  
  //通過native2ascii來進行轉換
  
  while (en.hasMoreElements()){
   String key=(String)en.nextElement();
   String value=rb.getString(key);
   //System.out.println(en.toString()); 
   //System.out.println(en);
   messages.put(key,value);
  
  }
  
  ServletContext ctx=this.getServletContext();
  ctx.setAttribute(Constants.MESSAGES_KEY, messages);
  //MESSAGES_KEY是我們自己寫的一個常量
  
  }
  
 }
6、創建一個對象類Messages
 package org.smartruts.resources;
import java.util.HashMap;
import java.util.Map;
public class Messages {
 private Map<String,String> map=new HashMap<String,String>();
 
}
//首先要創建一個對象能存放讀入的res資源文件內容、
7、寫一個TLD文件
<?xml version="1.0" encoding="UTF-8" ?>
<taglib 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 web-jsptaglibrary_2_0.xsd"
    version="2.0">
 
  <display-name>Smart Struts TagLib</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>bean</short-name>
 
  <tag>
    <name>message</name>
    <tag-class>org.smartstruts.taglib.bean.MessageTag</tag-class>
    <body-content>empty</body-content>
    <!--body-content>JSP</body-content>-->
    <attribute>
        <name>key</name>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>   
  </tag>
</taglib>
8、創建一個MessageTag文件
package org.smartstruts.taglib.bean;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import org.smartstruts.Constants;
public class MessageTag extends SimpleTagSupport {
 //<message key=""/>
 private String key;
 
 public String getKey() {
  return key;
 }

 public void setKey(String key) {
  this.key = key;
 }
 @Override
 public void doTag() throws JspException, IOException {
 
  JspContext jspCtx=this.getJspContext();
  PageContext ctx=(PageContext)jspCtx;
  //以上兩句是必不可少的
  //通過getServletContxt獲得所有的內建對象
  ServletContext servletCtx=ctx.getServletContext();
  //從serlvetcontext中拿出key的值
  Map map=(Map)servletCtx.getAttribute(Constants.MESSAGES_KEY);
  
  if (map!=null){
  String value=(String)map.get(key);
  if (value!=null){
   ctx.getOut().write(value);
   //輸出到指定的位置即可
   
  }
  }
  super.doTag();
 }
 
 
 
}
9、在頁面中用標簽庫拿出數據
 通過資源文件就可以了。
 
 但是以前驗證碼錯誤信息是怎么來實現國際化呢?可以從application中把數據拿到

 Action類修改添加setMessage
 
 
 package org.smartstruts.action;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.smartstruts.Constants;
public abstract class Action {
 private HttpServlet servlet;//為什么要加上這個呢??
 //1v1 to 1v2
 public static final String SUCCESS="success";
 public static final String FAIL="fail";
 
 
 public abstract String execute(ActionForm form,HttpServletRequest request,
   HttpServletResponse response) throws Exception;
 
 protected void setMessage(HttpServletRequest request,String name,String key){
  //protected子類才能用的方法
  //此方法接收3個參數
  ServletContext ctx=this.getServlet().getServletContext();
  Map map=(Map)ctx.getAttribute(Constants.MESSAGES_KEY);
  //根據這個key到資源文件中找到value值
  //找到這個value后,然后往request里面寫入了一個信息,name,value
  if (map!=null){
   String value=(String)map.get(key);
   if (value!=null){
    request.setAttribute(name, value);
    
   }
  }
  
  
 }
 public HttpServlet getServlet() {
  return servlet;
 }
 public void setServlet(HttpServlet servlet) {
  this.servlet = servlet;
 }
}
 
10、驗證類
TestAction extends Action
this.setMessage(request,"error_msg","user");

 
**************************************************************************

 
 本文由用戶 honghu79 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!