<!-- fckeditor -->
<servlet>
<servlet-name>Connector</servlet-name>
<servlet-class>com.fredck.FCKeditor.connector.ConnectorServlet</servlet-class>
<init-param>
<param-name>baseDir</param-name>
<!-- 此為文件瀏覽路徑 -->
<param-value>/UserFiles/</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>SimpleUploader</servlet-name>
<servlet-class>com.fredck.FCKeditor.uploader.SimpleUploaderServlet</servlet-class>
<init-param>
<param-name>baseDir</param-name>
<!-- 此為文件上傳路徑,需要在WebRoot 目錄下新建 UserFiles 文件夾 -->
<!-- 根據(jù)文件的類型還需要新建相關的文件夾 Image、 Flash -->
<param-value>/UserFiles/</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 此參數(shù)為是否開啟上傳功能 -->
<param-name>enabled</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsFile</param-name>
<param-value></param-value>
</init-param>
<init-param>
<!-- 此參數(shù)為文件過濾,以下的文件類型都不可以上傳 -->
<param-name>DeniedExtensionsFile</param-name>
<param-value>php|php3|php5|phtml|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|dll|reg|cgi</param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsImage</param-name>
<param-value>jpg|gif|jpeg|png|bmp</param-value>
</init-param>
<init-param>
<param-name>DeniedExtensionsImage</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsFlash</param-name>
<param-value>swf|fla</param-value>
</init-param>
<init-param>
<param-name>DeniedExtensionsFlash</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Connector</servlet-name>
<url-pattern>/FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SimpleUploader</servlet-name>
<url-pattern>/FCKeditor/editor/filemanager/upload/simpleuploader</url-pattern>
</servlet-mapping>
輸入的jsp文件類似如下:
<html:form action="/fck" method="post">
<fck:editor id = "fcktext" basePath = "/new1/FCKeditor/"
height = "100%"
skinPath = "/new1/FCKeditor/editor/skins/default/"
toolbarSet = "Default"
imageBrowserURL = "/new1/FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector"
linkBrowserURL = "/new1/FCKeditor/editor/filemanager/browser/default/browser.html?Connector=connectors/jsp/connector"
flashBrowserURL = "/new1/FCKeditor/editor/filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector"
imageUploadURL = "/new1/FCKeditor/editor/filemanager/upload/simpleuploader?Type=Image"
linkUploadURL = "/new1/FCKeditor/editor/filemanager/upload/simpleuploader?Type=File"
flashUploadURL = "/new1/FCKeditor/editor/filemanager/upload/simpleuploader?Type=Flash" >
</fck:editor>
<html:submit/><html:cancel/>
</html:form>
其中的id是對應于ActionForm與validationv.xml里的property。分別類似如下:
String strfcktext = fckForm.getString("fcktext");
<form name="fckForm">
<field property="fcktext" depends="required">
<arg key="fckForm.fcktext"/>
</field>
</form>
另外需要注意的是,如果顯示找不到頁面的錯誤,應該是form里FCK相關的路徑設置不正確。數(shù)據(jù)庫段的字段也需要設置足夠大。如果傳輸過程里出現(xiàn)亂碼,可以所有jsp頁面加入:<%@ page language="java" contentType="text/html; charset=UTF-8"%>,在web.xml里加入u-f8 filter:
<!-- u-f8 filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaValidatorForm checkForm = (DynaValidatorForm) form;// TODO Auto-generated method stub
/*HttpSession session=request.getSession();
String strrand = (String)session.getAttribute("rand");
session.setAttribute("rand", strrand);*/
return mapping.findForward("ok");
}
}
check.jsp
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<html>
<head>
<title>JSP for DynaValidatorForm form</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</head>
<body>
<html:form action="/check">
<td><img border=0 src="check/image.jsp"></td>
<html:text property="rand"/><html:errors property="rand"/><br/>
<html:submit/><html:cancel/>
</html:form>
</body>
</html>
checkok.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String rand = (String)session.getAttribute("rand");
String input = request.getParameter("rand");
if (rand.equals(input)) {
%>
<font color=green>OK</font>
<%
} else {
%>
<font color=red>FAIL</font>
<%
}
%>
</body>
</html>
image.jsp
<%@ page language="java" import="java.util.*" %>
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,javax.imageio.*" %>
<%@ page import="java.io.OutputStream" %>
<%!
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os=response.getOutputStream();
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman",Font.PLAIN,18));
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
g.drawString(rand,13*i+6,16);
}
session.setAttribute("rand",sRand);
g.dispose();
ImageIO.write(image, "JPEG",os);
os.flush();
os.close();
os=null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
%>
public class UpfileAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaActionForm upfileForm = (DynaActionForm) form;// TODO Auto-generated method stub
Image image = new Image();
String strimgname = upfileForm.getString("filename");
image.setImgname(strimgname);
imageDAO.save(image);
FormFile filedata = (FormFile)upfileForm.get("filedata");
ServletContext servletContext = this.getServlet().getServletContext();
String filePath = servletContext.getRealPath("/");
try {
InputStream stream = filedata.getInputStream();
OutputStream bos = new FileOutputStream(filePath + "/image/" + filedata.getFileName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ( (bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mapping.findForward("ok");
}
private ImageDAO imageDAO;
public void setImageDAO(ImageDAO dao){
this.imageDAO = dao;
}
}
public class DisplayimgAction extends Action {
/*
* Generated Methods
*/
/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
List results = imageDAO.findAll();
if(results!=null){
HttpSession session=request.getSession();
session.setAttribute("results",results);
return mapping.findForward("ok");
}return mapping.findForward("fail");
}
private ImageDAO imageDAO;
public void setImageDAO(ImageDAO dao){
this.imageDAO = dao;
}
}
ImageDAO.java
public void save(Image transientInstance) {
Session session =this.getSession();
Transaction tx = null;
tx = session.beginTransaction();
session.save(transientInstance);
tx.commit();
session.evict(transientInstance);
}
public List findAll() {
Session session =this.getSession();
Query query = session.createQuery("from Image");
return query.list();
}
displayimg.jsp
<logic:iterate id="element" name="results">
<tr>
<td width="100"><bean:write name="element" property="id"/> </td>
<td width="100"><img src="image/<bean:write name='element' property='imgname'/>"/></td>
</tr>
</logic:iterate>
uploadfile.jsp
<html:form action="/upfile" enctype = "multipart/form-data">
filename : <html:text property="filename"/><html:errors property="filename"/><br/>
filedata : <html:file property="filedata"/><html:errors property="filedata"/><br/>
<html:submit/><html:cancel/>
</html:form>
<!-- u-f8 filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
public class SendMailImpl implements SendMail {
private MailSender mailSender;
public void setMailSender(MailSender mailSender){
this.mailSender = mailSender;
}
private SimpleMailMessage mailMessage;
public void setMailMessage(SimpleMailMessage mailMessage){
this.mailMessage = mailMessage;
}
public void sendmail(String content){
SimpleMailMessage message = new SimpleMailMessage(this.mailMessage);
StringBuffer messageText = new StringBuffer();
messageText.append(content);
message.setText(messageText.toString());
mailSender.send(message);
}
}
<logic:iterate id="element" name="results"> <tr>
<td width="100"><input type="checkbox" name="select" value="<bean:write name="element" property="id"/>"><bean:write name="element" property="id"/></td>
<td width="100"><bean:write name="element" property="name"/> </td>
<td width="100"><bean:write name="element" property="password"/></td>
</tr></logic:iterate>
顯示頁碼的代碼:
<%
int i;
int a=Integer.parseInt(session.getAttribute("amountPage").toString());
for (i=1;i<=a;i++){
out.println("<tr>");
out.println("<td><a href='display.do?pagenum="+ i +"'>"+ i +"</a></td>");
out.println("</tr>");
}
%>
使用DynaValidatorActionForm,校驗是根據(jù)action元素的path屬性值來區(qū)分FormBean,而action元素的path屬性值正是不同action區(qū)分的唯一標記,這樣根據(jù)不同的action我們對同一個ActionForm給出不同的驗證規(guī)則了。
其實,Struts 1.x在此部分已經(jīng)做得相當不錯了。它極大地簡化了我們程序員在做國際化時所需的工作,例如,如果您要輸出一條國際化的信息,只需在代碼包中加入FILE-NAME_xx_XX.properties(其中FILE-NAME為默認資源文件的文件名),然后在struts-config.xml中指明其路徑,再在頁面用<bean:message>標志輸出即可。
不過,所謂“沒有最好,只有更好”。Struts 2.0并沒有在這部分止步,而是在原有的簡單易用的基礎上,將其做得更靈活、更強大。
下面讓我們看一個例子——HelloWorld。這個例子演示如何根據(jù)用戶瀏覽器的設置輸出相應的HelloWorld。
![]() |
Struts 2.0有兩個配置文件,struts.xml和struts.properties都是放在WEB-INF/classes/下。
|
![]() |
在此想和大家分享一個不錯的編寫properties文件的Eclipse插件(plugin),有了它我們在編輯一些簡體中文、繁體中文等Unicode文本時,就不必再使用native2ascii編碼了。您可以通過Eclipse中的軟件升級(Software Update)安裝此插件,步驟如下: 1、展開Eclipse的Help菜單,將鼠標移到Software Update子項,在出現(xiàn)的子菜單中點擊Find and Install;
2、在Install/Update對話框中選擇Search for new features to install,點擊Next; 3、在Install對話框中點擊New Remote Site; 4、在New Update Site對話框的Name填入“PropEdit”或其它任意非空字符串,在URL中填入http://propedit.sourceforge.jp/eclipse/updates/; 5、在Site to include to search列表中,除上一步加入的site外的其它選項去掉,點擊Finsih; 6、在彈出的Updates對話框中的Select the features to install列表中將所有結尾為“3.1.x”的選項去掉(適用于Eclipse 3.2版本的朋友); 7、點擊Finish關閉對話框; 8、在下載后,同意安裝,再按提示重啟Eclipse,在工具條看到形似vi的按鈕表示安裝成功,插件可用。此時,Eclpise中所有properties文件的文件名前有綠色的P的圖標作為標識。 |
之所以說Struts 2.0的國際化更靈活是因為它可以能根據(jù)不同需要配置和獲取資源(properties)文件。在Struts 2.0中有下面幾種方法:
上面我列舉了四種配置和訪問資源的方法,它們的范圍分別是從大到小,而Struts 2.0在查找國際化字符串所遵循的是特定的順序,如圖3所示:
假設我們在某個ChildAction中調用了getText("user.title"),Struts 2.0的將會執(zhí)行以下的操作:
許多情況下,我們都需要在動行時(runtime)為國際化字符插入一些參數(shù),例如在輸入驗證提示信息的時候。在Struts 2.0中,我們通過以下兩種方法做到這點:
開發(fā)國際化的應用程序時,有一個功能是必不可少的——讓用戶快捷地選擇或切換語言。在Struts 2.0中,通過ActionContext.getContext().setLocale(Locale arg)可以設置用戶的默認語言。不過,由于這是一個比較普遍的應用場景(Scenario),所以Struts 2.0為您提供了一個名i18n的攔截器(Interceptor),并在默認情況下將其注冊到攔截器鏈(Interceptor chain)中。它的原理為在執(zhí)行Action方法前,i18n攔截器查找請求中的一個名為"request_locale"的參數(shù)。如果其存在,攔截器就將其作為參數(shù)實例化Locale對象,并將其設為用戶默認的區(qū)域(Locale),最后,將此Locale對象保存在session的名為“WW_TRANS_I18N_LOCALE”的屬性中。
下面,我將提供一完整示例演示它的使用方法。
上述代碼的原理為,LangSelector.jsp先實例化一個Locales對象,并把對象的Map類型的屬性locales賦予下拉列表(select) 。如此一來,下拉列表就獲得可用語言的列表。大家看到LangSelector有<s:form>標志和一段Javascript腳本,它們的作用就是在用戶在下拉列表中選擇了后,提交包含“reqeust_locale”變量的表單到Action。在打開頁面時,為了下拉列表的選中的當前區(qū)域,我們需要到session取得當前區(qū)域(鍵為“WW_TRANS_I18N_LOCALE”的屬性),而該屬性在沒有設置語言前是為空的,所以通過值棧中l(wèi)ocale屬性來取得當前區(qū)域(用戶瀏覽器所設置的語言)。
你可以把LangSelector.jsp作為一個控件使用,方法是在JSP頁面中把它包含進來,代碼如下所示:![]() |
可能大家會問為什么一定要通過Action來訪問頁面呢? 你可以試一下不用Action而直接用JSP的地址來訪問頁面,結果會是無論你在下拉列表中選擇什么,語言都不會改變。這表示不能正常運行的。其原因為如果直接使用JSP訪問頁面,Struts 2.0在web.xml的配置的過濾器(Filter)就不會工作,所以攔截器鏈也不會工作。 |
來,我們將它支解掉。:) 好象沒有什么好說的。很簡單。這是某個form下的一個properties的標準寫法。其中我們要重視一下這句話: <arg0 name="maxlength" key="${var:maxlength}" resource="false" /> , resource屬性指的是:是從資源文件里面讀key的值嗎?
if (resource == "false") {
請取當前定義的變量的值。[因為為false的時候,因為得必須得給個值來組裝錯誤信息,因為此時我們不會到消息資源文件里提取值]
} else if (resource == "true) {
請到資源文件里提取用來組裝錯誤消息的值.
}
你會問:如果我不指定resourse的值怎么樣?默認是true,即:默認下它會去讀properties文件里面的值。 (這似乎與java的boolean的默認是false有點違背),如果我沒有配呢?那么是null.
當然我也做了一個實驗證明了這點:
properties file tips
------------------------------------------------------------------------------
errors.maxlength = The length of the password can not surpass {0}
------------------------------------------------------------------------------
validation.xml tips :
------------------------------------------------------------------------------
<field property="username" depends="maxlength">
<arg0 name="maxlength" key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>
------------------------------------------------------------------------------
如果username的長度超過10的話,那么打印的是:The length of the password can not surpass 10
resouse屬性改成true,
properties file tips
------------------------------------------------------------------------------
errors.maxlength = The length of the password can not surpass {0}
username.maxlength = 10
------------------------------------------------------------------------------
validation.xml tips :
------------------------------------------------------------------------------
<field property="username" depends="maxlength">
<arg0 name="maxlength" key="username.maxlength" resource="true" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>
------------------------------------------------------------------------------
這樣我們也能達到同樣的效果。Right? 但是誰愿意呢? 只是我這樣寫似乎更加容易理解吧.并且這樣做就失去了validation的某些特別的功效,你得為每個重新在資源文件里寫一條message,不值得。
2. validation.xml 中的msg屬性.
官方資料:[The default error message for a pluggable validator can be overriden with the msg element. So instead of using the msg attribute for the mask validator to generate the error message the msg attribute from the field will be used if the name of the field's name attribute matches the validator's name attribute.]后面的例子我也就沒有給出來,那么這句話到底在肌理哇啦個什么呢? 先看一小段代碼:
------------------------------------------------------------------------------------------------
<field property="username" depends="maxlength">
<arg0 name="maxlength" key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>
------------------------------------------------------------------------------------------------
再強調一遍:validation的錯誤信息是這樣組裝的:通過arg0 - arg3等來和資源文件里面的并且消息名字在validator-rule.xml定義好的規(guī)則所對應的消息來合成的。validator-rule.xml所定義的msg是面向所有的該規(guī)則的錯誤消息,每個form field可以通過arg0-arg3來定制自己的消息(這個我提到過)
如果我們加入msg消息到filed標簽下面:
------------------------------------------------------------------------------------------------
<field property="username" depends="maxlength">
<msg name="maxlength" key="msg.maxlength" />
<arg0 name="maxlength" key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>
------------------------------------------------------------------------------------------------
那么此時的maxlength在規(guī)則里面的msg將會被<field>里面的msg覆蓋,也就是說<arg0>的定義形同虛設,更會無視resourse屬性的false or true;
3.幾個規(guī)則(rules)作用于同一個form的屬性上面
------------------------------------------------------------------------------------------------
<field property="username" depends="required,maxlength,minlength">
<arg0 name="maxlength" key="${var:maxlength}" resource="false" />
<arg1 name="required" key="prompt.username" />
<arg2 name="minlength" key="${var:minlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
<var>
<var-name>minlength</var-name>
<var-value>3</var-value>
</var>
</field>
------------------------------------------------------------------------------------------------
如果很多約束針對某一個form的屬性,我們可以這樣寫,當然如果你非要分開寫也可以。那么在xml文件中一個form的field就有多條記錄.
這里有一點需要注意一下:<arg0><arg1><arg2>在這里定義了以后,別的form的屬性也要按照這種順序來,也就是:<arg0>對應的是 maxlength. <arg1>對應的是minlength.<arg2>對應的是 requried.為什么這樣做?
因為在我們的properties文件中是寫死的。如果不這樣做,那么就會出現(xiàn)得到null值的錯誤啦.
------------------------------------------------------------------------------------------------
errors.required ={1} is required.
errors.maxlength = The length of the password can not surpass {0}
errors.minlength = The length of the password can not shorter than {2}
------------------------------------------------------------------------------------------------
補充一下validwhen的用法
<field property="emailAddress" depends="validwhen">
<arg0 key="userinfo.emailAddress.label"/>
<var>
<var-name>test</var-name>
<var-value>((sendNewsletter == null) or (*this* != null))</var-value>
</var>
</field>
上面定義的意思是:如果通訊地址是空或不空時這個字段時有效的