??xml version="1.0" encoding="utf-8" standalone="yes"?> 目标效果Q把界面语言Ҏ英文qɾpȝ正常支持中文?/p>
解决办法Q?br />
q入{NB_HOME}\etcQ其中{NB_HOME}为NetBeans的安装\径。编辑netbeans.conf文g。将其中? command line switchs:下面那行命o后添加如下启动参敎ͼ d后的效果CZ如下Q?br />
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true -J-Duser.language=zh -J-Duser.country=US" 如果觉得昄的字体太,可在以上参数后面再添加参?-fontsize {FONT_SIZE}Q改变显C字体的大小。如--fontsize 13Q?br />
d后的效果CZ如下Q?br />
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true -J-Duser.language=zh -J-Duser.country=US --fontsize 13" 关于前面几个参数的解释,可以参照NetBeans的guideQ?a >http://www.netbeans.org/kb/55/using-netbeans/configuring.html#pgfId-1158626 后面d的几个参?J-Duser.language=zh -J-Duser.country=US是调用Java的本w系l属性,讄语言为zhQ中文)Q国家ؓUSQ美国)?br />
不过Q在调用file browser的时候会发现左边一pdwindowsҎ的中文按钮都回变成q?br />
在NetBeans的tools\options\fonts&colors\syntax\下的language选项讄all languages的default的字体ؓ一个能够支持中文的字体Q如QMicrosoft YaHei 需要特别指出的是,~辑器中字体可以通过修改配置解决。但是Output字体无法通过配置q行修改。但我们可以通过修改JDK的默认配|达到目的。不q,q样做会D所有的Java GUIE序都受影响。具体方法参见如下: 默认情况下,NetBeans~辑器和Output字体很难看。编辑器中字体可以通过修改配置解决。但是Output字体无法通过配置q行修改。可以通过修改JDK的默认配|达到目的,不过q样所有的Java GUIE序都会受媄响。下面以JDK6 update 2Z说明?/p>
在JDK安装目录/jre/lib下有一个名为fontconfig.properties.srcQ先备䆾。配|文仉认在GBK和GB18030Ӟ{宽字(monospaceQ优先用了SImSUNQ即宋体Q,可以Ҏ优先使用Courier New(文g中定义ؓalphabetic)。。?/p>
扑ֈ sequence.monospaced.GBK=chinese-ms936,alphabetic,dingbats,symbol 扑ֈ sequence.monospaced.GB18030=chinese-gb18030,alphabetic,dingbats,symbol 如果觉得字体偏小Q可以在启动netbeans d参数fontsize。如netbeans -fontsize 12 也可以将它写qnetbeans配置文g文g<netbeans安装位置>/etc/netbeans.conf的启动参C?/p>
-J-Duser.language=zh -J-Duser.country=US
国家设ؓUSQ是Z使NetBeans的界面显CZؓ英文Q而语a设ؓzhQ是Z使NetBeans能够支持中文。若只需要英文,则可以把language设ؓen?/p>
没有此字体的可以?a >http://xiazai.zol.com.cn/detail/26/253442.shtml#down下蝲
换成 sequence.monospaced.GBK=alphabetic,chinese-ms936,dingbats,symbol
换成 sequence.monospaced.GB18030=alphabetic,chinese-gb18030,dingbats,symbol
-J-Xverify:none
-J-Xms32m
-J-Xmx128m
-J-XX:PermSize=40m
通过q些讄不仅可以让netbeans的启动速度慢加?0U左叻Iq可以让256M的计机畅的跑netbeans4.1,5.0;
解释如下Q?br />
-J-Xverify:none ——关闭Java字节码校?nbsp;
-J-Xms32m ——Java虚拟机初始Heap大小?2M
-J-Xmx128m ——指定Java虚拟使用的最大Heap大小?28MQ注意,不要讄得跟机器的物理内存大相q,否则……呵呵Q?nbsp;
-J-XX:PermSize=40m——设|?#8220;持久内存”大小?0MQ在q个内存区域中保持IDE的各U类Q该讄告诉JVM需要多内存,q且能大大减垃圑ֆ存回收事件的产生。用SunOne Studio或者其他含更多模块的IDE的用户需要把该参数设|更高.
另外Q?nbsp;
在netbeans中打"."来等待代码提C好象很慢,事实上这是一个假象,q个假象以让我们认为netbeans的代码提C速度不如别的ideQ其实netbeans比你我想象的要快的多Q坦白的说我以前也被q中假象所qhQ?nbsp;
ҎQ在netbeans?->tools-->options-->Advanced options-->Editor Settings-->java Editor-->Deley of Completion Window auto pop-->?50该ؓ0Q好了现在netbeans的代码提C就像飞一样快了呵呵,如你q想更快的话把Auto pop javadoc Window的选择取消好了。同L你可以设|别的Editor?
该把修改web.xmlQ把原来?br />
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
改ؓ
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
而上传页面调用时直接用文件名调用Q如upload.jspQ。struts2只处?*.action 的请求?br />
或?br />
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
L也行
若是java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileUploadException错误
那就有可能是导包的问题,若用的是叛_目Q选择属性,然后导入相应的包Q就有可能出显此cȝ错误Q解x法是Q把commons-fileupload-1.2.1.jar,commons-io-1.4.jar复制到到WEB-INF下的lib目录中,虽然效果是一P但不会出错了
?
upload.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'upload.jsp' starting page</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
密码Q?lt;input type="password" name="password"><br>
文g1:<input type="file" name="file1"><br>
文g2:<input type="file" name="file2"><br>
<input type="submit" value="提交"><br>
</form>
</body>
</html>
UploadServlet.java
package com.test.servlet1;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
String path = request.getRealPath("/upload");
// 讄传轮输文件的大小Q当于1024Ӟ把文件存在兹盘上
factory.setRepository(new File(path));
factory.setSizeThreshold(1024 * 1024);
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list){
if(item.isFormField()){
String name = item.getFieldName();
String value = item.getString("GB2312");
request.setAttribute(name, value);
}else{
String name = item.getFieldName();
String value = item.getName();
int start = value.lastIndexOf("\\");
String fileName = value.substring(start+1);
request.setAttribute(name, fileName);
//item.write(new File(path,fileName));
OutputStream os = new FileOutputStream(new File(path,fileName));
InputStream is = item.getInputStream();
// 文件is写到os?br />
byte[] buffer = new byte[400];
int lenght = 0 ;
while((lenght = is.read(buffer ))>0){
os.write(buffer,0,lenght);
}
os.close();
is.close();
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
System.out.println("文g上传出错"+e.getMessage());
e.printStackTrace();
}
request.getRequestDispatcher("upload/result.jsp").forward(request, response);
}
}
result.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'result.jsp' starting page</title>
</head>
<body>
用户?${requestScope.username }
密码:${requestScope.password }
文g1:${requestScope.file1 }
文g2:${requestScope.file2 }
</body>
</html>
我们的项目名?struts2helloQ所使用的开发环境是MyEclipse 6Q当然其实用哪个IDE都是一LQ只要把cd放进d行了Q文件下载不需要再加入M额外的包。读者可以参考文档:http://beansoft.java-cn.org/myeclipse_doc_cn/struts2_demo.pdfQ来了解怎么下蝲和配|基本的Struts 2开发环境?
Z便于大家ҎQ我把完整的struts.xml的配|信息列出来Q?
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="default" extends="struts-default" > <!-- 在这里添加Action定义 --> <!-- 单文件下?--> <action name="download" class="example.FileDownloadAction"> <result name="success" type="stream"> <param name="contentType">text/plain</param> <param name="inputName">inputStream</param> <param name="contentDisposition">attachment;filename="struts2中文.txt"</param> <param name="bufferSize">4096</param> </result> </action> <!-- 文g下蝲Q支持中文附件名 --> <action name="download2" class="example.FileDownloadAction2"> <!-- 初始文g?--> <param name="fileName">Struts中文附g.txt</param> <result name="success" type="stream"> <param name="contentType">text/plain</param> <param name="inputName">inputStream</param> <!-- 使用l过转码的文件名作ؓ下蝲文g名,downloadFileName属?/span> 对应actioncM的方?getDownloadFileName() --> <param name="contentDisposition">attachment;filename="${downloadFileName}"</param> <param name="bufferSize">4096</param> </result> </action> <!-- 下蝲现有文g --> <action name="download3" class="example.FileDownloadAction3"> <param name="inputPath">/download/pȝ说明.doc</param> <!-- 初始文g?--> <param name="fileName">pȝ说明.doc</param> <result name="success" type="stream"> <param name="contentType">application/octet-stream;charset=ISO8859-1</param> <param name="inputName">inputStream</param> <!-- 使用l过转码的文件名作ؓ下蝲文g名,downloadFileName属?/span> 对应actioncM的方?getDownloadFileName() --> <param name="contentDisposition">attachment;filename="${downloadFileName}"</param> <param name="bufferSize">4096</param> </result> </action> </package> </struts>
Struts 2中对文g下蝲做了直接的支持,相比赯p辛苦苦的讄U种HTTP头来_现在实现文g下蝲无疑要简便的多。说h件下载,最直接的方式恐怕是直接写一个超链接Q让地址{于被下载的文gQ例如:<a href=”file1.zip”>下蝲file1.zip</a>Q之后用户在览器里面点击这个链接,可以进行下载了。但是它有一些缺P例如如果地址是一个图片,那么览器会直接打开它,而不是显CZ存文件的对话框。再比如如果文g名是中文的,它会昄一堆URL~码q的文g名例?3457...。而假设你企图q样下蝲文gQ?a href="http://localhost:8080/struts2hello/download/pȝ说明.doc">http://localhost:8080/struts2hello/download/pȝ说明.docQTomcat会告诉你一个文件找不到?04错误Q?em>HTTP Status 404 - /struts2hello/download/ϵͳ˵Ã÷.doc。虽然目前还没发现直接配|Struts 2来正的下蝲中文名字的附Ӟ不过好在作者对JSP中的文g下蝲比较了解Q因此我们另有办法解册个问题。另外一个最大的用途,是动态的生成q下载文件了Q例如动态的下蝲生成的EXCELQPDFQ验证码囄{等。本节内容就依次讨论单的下蝲文g代码Q下载中文附Ӟ最后介l如何下载已l存在的文g?
先说文g下蝲Q编写一个普通的Action可以了Q只需要提供一个返回InputStream的ҎQ该输入代表了被下载文件的入口Q这个方法用来给被下载的数据提供输入,意思是从这个流d来,再写到浏览器那边供下载。这个方法需要由开发h员自己来~写Q只需要返回gؓInputStream卛_。在我们的例子中Ҏ的签名是Q?em>public InputStream getInputStream() throws ExceptionQ当然它也可以是别的名字Q例?em>getDownloadFile()。好了,现在我们所写的q个q行文g下蝲的Actionc?strong>example.FileDownloadAction 的源代码清单如下Q?
package example;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import com.opensymphony.xwork2.Action;
public class FileDownloadAction implements Action {
public InputStream getInputStream() throws Exception {
return new ByteArrayInputStream("Struts 2 下蝲CZ".getBytes());
}
public String execute() throws Exception {
return SUCCESS;
}
}
。注意这里唯一Ҏ的方法就?em>getInputStream()Q在q个Ҏ里面我们使用了一个数l输入流来从字符串{换成的数l作为数据的来源q行d。也许方法体中用这L实现代码Q?
return new java.io.FileInputStream(“c:\\test.txt”);//从系l磁盘文件读取数?/em>
q样会更直观一些?
文g下蝲的第二步Q乃是在struts.xml中对actionq行配置Q其代码清单如下所C:
<!-- 单文件下?-->
<action name="download" class="example.FileDownloadAction">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="struts2.txt"</param>
<param name="bufferSize">4096</param>
</result>
</action>
。这个actionҎ的地方在于result的类型是一个流Q?em>stream
参数
说明
contentType
内容cdQ和互联|MIME标准中的规定cd一_例如text/plain代表U文本,text/xml表示XMLQimage/gif代表GIF囄Qimage/jpeg代表JPG囄
inputName
下蝲文g的来源流Q对应着actioncM某个cd为Inputstream的属性名Q例如取gؓinputStream的属性需要编写getInputStream()Ҏ
contentDisposition
文g下蝲的处理方式,包括内联(inline)和附?attachment)两种方式Q而附件方式会弹出文g保存对话框,否则览器会试直接昄文g。取gؓQ?
attachment;filename="struts2.txt"Q表C文件下载的时候保存的名字应ؓstruts2.txt。如果直接写filename="struts2.txt"Q那么默认情冉|代表inlineQ浏览器会尝试自动打开它,{h于这L写法Q?em>inline; filename="struts2.txt"
bufferSize
下蝲~冲区的大小
。在q里面,contentType属性和contentDisposition分别对应着HTTP响应中的?em>Content-Type?em>Content-disposition头。好Q我们先来看看这个例子,发布q行目后键入测试地址Q?a href="http://localhost:8080/struts2hello/download.action">http://localhost:8080/struts2hello/download.actionQ将会看到浏览器弹出一个文件保存对话框Q如?2.12所C?
?2.12 文g下蝲对话框(IE 7和Firefox 3Q?
如果此时使用某些工具来探浏览器q回的HTTP_会看到下列内容Q?
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-disposition: attachment;filename="struts2.txt"
Content-Type: text/plain
Transfer-Encoding: chunked
Date: Sun, 02 Mar 2008 02:58:25 GMT
。所以用来下载的action配置中,只有两个是和览器有关的Q?em>contentType?em>contentDisposition。关?em>contentType的取|如果是未知的文gcdQ或者说出现了浏览器不能打开的文Ӟ例如.bean文gQ或者说q个action是用来做动态文件下载的Q事先ƈ不知道未来的文gcd是什么,那么我们可以把它的D|成为:application/octet-stream;charset=ISO8859-1 Q注意一定要加入charsetQ否则某些时候会D下蝲的文件出错;有h说这时也可以讄成ؓapplication/x-downloadQ根据笔者的实践Q这个头也能正常工作Q然而个别时候会出现览器无法识别的问题。?em>contentDispositionQ如果其取值是filename="struts2.txt"Q或者是inline; filename="struts2.txt"Q运行后你可以看到浏览器直接昄了文件的内容Q?
Struts 2 下蝲CZQ而不再弹出对话框提示用户保存文g到硬盘上。所以读者如果想保文g是被下蝲而不是被打开Q务必用格?strong>attachment;filename="struts2.txt"Q不要丢?em>attachment;q个cd信息?
xQ关于文件下载的技术内容,已经告一D落。然而做中文pȝQ不可避免的要解决中文附件的下蝲问题。关于这个内容,也无权威的资料可查,我们只能用实践中得到的解x案来处理。也许有读者以为将filename属性设|ؓfilename=”struts2中文.txt”p解决问题了,好,来试试Q把contentDisposition修改成:
<param name="contentDisposition">attachment;filename="struts2中文.txt"</param>
。再ơ键入地址q行试Q看看显C的l果Q如?2.13所C。唉Q真是完全不l面子!IE压根׃能显C出来文件名Q草草敷衍了download_action了事。FirefoxE好点,q出来了一个对话框Q但是很昄Q那个显C的struts2--txtl对不是我们日思夜想的struts2中文.txt。怎么办?解决Ҏ是有Q那是用ISO8859-1~码来显C个中文字W,可以阅读12.8参考资?/u>一节中?em>JSP 文g下蝲的相对完整代?解决中文问题和Weblogic报错)q篇文章Q可以这栯为,所有的文g下蝲代码都是Z同样的纯Servlet的方式来q行的。如果是Java代码Q我们可以这样做Q?
?2.13 IE和Firefox下的中文文g下蝲对话?
String downFileName = new String(“struts2中文.txt”.getBytes(), "ISO8859-1");
然后把生成的l果字符串放到XML文g中就行了Q然而它的输出类gstruts2??.txtQ是无法直接写道我们的XML配置文g中的。所以,我们惛_的的办法Q就是在ActioncM写一个方法来做{码,使它成ؓ某个属性,所以要以get开头。然后,再用12.3.8 lAction注入参数QparamQ?/u>一节的内容Q将文g名以正常的方式设|ؓactioncȝ某个属性,最后呢Q再利用一个小的param参数取g的伎俩:${属性名}Q它可以直接从actioncM动态获取某个属性倹{好了,现在让我们来看看W二个文件下载类FileDownloadAction2的代码:
package example;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import com.opensymphony.xwork2.Action;
public class FileDownloadAction2 implements Action {
private String fileName;// 初始的通过param指定的文件名属?
public InputStream getInputStream() throws Exception {
return new ByteArrayInputStream("Struts 2 下蝲CZ".getBytes());
}
public String execute() throws Exception {
return SUCCESS;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
/** 提供转换~码后的供下载用的文件名 */
public String getDownloadFileName() {
String downFileName = fileName;
try {
downFileName = new String(downFileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downFileName;
}
}
。这个类有两个属性,W一个是fileNameQ它是需要被指定的下载文件名Q第二个则是动态的仅仅?em>getDownloadFileName()q个Ҏ定义的属?em>downloadFileNameQ它的值随着fileName而动态变动,仅仅是把它{换成了ISO8859方式的西Ƨ字W集?
接下来就是如何配|这个action了,q是关键的地Ҏ在,现在配置一个新的actionQ名?em>download2Q其源代码如下:
<!-- 文g下蝲Q支持中文附件名 -->
<action name="download2" class="example.FileDownloadAction2">
<!-- 初始文g?-->
<param name="fileName">Struts中文附g.txt</param>
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">inputStream</param>
<!-- 使用l过转码的文件名作ؓ下蝲文g名,downloadFileName属?
对应actioncM的方?getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
。其中特D的代码是${downloadFileName}Q它的效果相当于q行的时候将action对象的属性的取值动态的填充?em>${}中间的部分,我们可以认ؓ它等价于Q?/em>action. getDownloadFileName()?
好了Q现在让我们重新发布然后q行q个目Q键入地址Q?
http://localhost:8080/struts2hello/download2.action q行讉KQ可以看到运行结果完全正,如图12.14所C?
?12.14 正确昄了文件下载名的对话框QIE和FirefoxQ?
在本节的最后部分,我们来讨Z下如何下载已l存在于当前Web应用目录下的已经存在的文件。一般的|站可能会把要下载的文g攑֜某个固定的目录下Q例?em>WebRoot/download package example;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
public class FileDownloadAction3 implements Action {
private String fileName;// 初始的通过param指定的文件名属?
private String inputPath;// 指定要被下蝲的文件\?/em>
public InputStream getInputStream() throws Exception {
// 通过 ServletContextQ也是application 来读取数?/em>
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
public String execute() throws Exception {
return SUCCESS;
}
public void setInputPath(String value) {
inputPath = value;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
/** 提供转换~码后的供下载用的文件名 */
public String getDownloadFileName() {
String downFileName = fileName;
try {
downFileName = new String(downFileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return downFileName;
}
}
。代码中被改动的部分已经用粗斜体的方式显C出来了。首先是新加入了一个名?em>inputPath的属性,用来制定被下载文件的路径。接着是ServletActionContext.getServletContext()q段代码Q它的意义我们将?u>12.6节详l讨论,在这里读者只需要知道它获取了当前Servlet容器?em>ServletContextQ也是大家常说的jsp中的application对象Q然后用它来打开文g的输入流?
接着要做的就是配|actionQ它和刚刚配|过的download2的内容差不多Q只是多了一个被下蝲的资源的路径属性。现在我们在struts.xml中加入这个新的action定义Q?
<!-- 下蝲现有文g -->
<action name="download3" class="example.FileDownloadAction3">
<param name="inputPath">/download/pȝ说明.doc</param>
<!-- 初始文g?-->
<param name="fileName">pȝ说明.doc</param>
<result name="success" type="stream">
<param name="contentType">application/octet-stream;charset=ISO8859-1</param>
<param name="inputName">inputStream</param>
<!-- 使用l过转码的文件名作ؓ下蝲文g名,downloadFileName属?
对应actioncM的方?getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
。查看粗斜体的部分,首先是自定了被下蝲文g的\径,inputPathQ接着是修改了contentTypeZq制方式。最后重新发布项目ƈq行Q键入地址q行讉KQ?a href="http://localhost:8080/struts2hello/download3.action">http://localhost:8080/struts2hello/download3.action 。很好,可以看到文g下蝲对话框,保存pȝ说明.doc后再用word打开它,内容正确?
注意Q?/strong>而这U文件下载方式却是存在安全隐患的Q因问者如果精通Struts 2的话Q它可能使用q样的带有表单参数的地址来访问:http://localhost:8080/struts2hello/download3.action?inputPath=/WEB-INF/web.xmlQ这Ll果是下蝲后的文g内容是您pȝ里面的web.xml的文件的源代码,甚至q可以用q种方式来下载Q何其它JSP文g的源码。这对系l安全是个很大的威胁。作ZU变通的ҎQ读者最好是从数据库中进行\径配|,然后把ActioncM的设|inputPath的方法统l去掉,a之就是删除这个方法定义:
public void setInputPath(String value) {
inputPath = value;
}
。而实际情况则应该成ؓ download3.action?fileid=1 cM于这L形式来进行。或者呢Q读者可以在execute()Ҏ中进行\径检查,如果发现有访问不属于download下面文g的代码,׃律拒l,不给他们q回文g内容。例如,我们可以把刚才类中的execute()Ҏ加以改进Q成P
public String execute() throws Exception {
// 文g下蝲目录路径
String downloadDir = ServletActionContext.getServletContext().getRealPath("/download");
// 文g下蝲路径
String downloadFile = ServletActionContext.getServletContext().getRealPath(inputPath);
java.io.File file = new java.io.File(downloadFile);
downloadFile = file.getCanonicalPath();// 真实文g路径,L里面?.{信?
// 发现企图下蝲不在 /download 下的文g, 显C空内容
if(!downloadFile.startsWith(downloadDir)) {
return null;
}
return SUCCESS;
}
。这时候如果访问者再企图下蝲web.xml的内容,它只能得C个空白页Q现在访问者只能下载位?em>/download目录下的文g?
]]>
视频内容包括三个例子的实际开发:
HelloWorld Q-l承自ActionSupport的Action
HelloPOJOQ- POJO 模式?Action 开?br />
dQ-单登录,表单验证和form标签
q包含了如何下蝲Q配|Struts 2 开发环境,通过视频你可以了解到?Struts 2 q行开发其实是非常Ҏ上手的,ȝ来说它是和JSFcM的开发模式,而Spring Web MVC 则只能和Struts 1 处于一L开发模式上!
友情提示: 下蝲微Y|盘文g时关闭下载工?/strong>, 否则你将得到错误的文?/strong>, 双击 EXE 会出?/strong> DOS H口. 正确操作是点L件名后能看到昄下蝲链接和文件大等信息.
代码: http://cid-519b3f7aa2172030.skydrive.live.com/self.aspx/Public/MyEclipse6Videos/13_struts2hello.zip 3.25 MB
视频: http://cid-519b3f7aa2172030.skydrive.live.com/self.aspx/Public/MyEclipse6Videos/MyEclipse6_13.exe 49?4U?15.2 MB
视频截图:
Structs2基本配置入门
来源:javaresearch.org 作?liudayong
1、ؓStructs应用配置Web.xml文g
W一?配置ActionServlet
xml 代码
注意:不管应用中包含多个子应?都只需配置一个ActionServlet,因ؓActionServlet支持多线E?目前的Structs框架只允许在应用中配|一个ActionServlet?
W二步:初始化参数对Servlet的运行环境进行初始化配置?/span>
xml 代码
?-1. Struts1.1中用到的初始化参?/span>
参数?/span> |
含义/默认?/span> |
config |
以相对\径的方式指明 Struts应用E序 的配|文件位|?如不讄Q则默认gؓ/WEB-INF /struts-config.xml?/span> |
config/sub1 |
以相对\径的方式指明子应用程?的配|文件位|,一般来_ 很少用到子应用程序, 在此不多描述?/span> |
debug |
讄Servlet的debugU别Q?控制日志记录的详l程度?默认?Q?记录相对最的日志信息?/span> |
detail |
讄Digester的debugU别Q?Digester是Struts框架所使用?用来解析xml配置文g的一个框Ӟ 通过该设|,可以查看不同详细 {的解析日志。默认ؓ0Q?记录相对最的日志信息?/span> |
W三步:配置Ƣ迎清单
当客戯问Web应用Ӟ如果仅仅l出Web应用的Root URLQ没用指定具体的文g名,Web容器会自动调用Web应用的欢q文件?/span>
xml 代码
说明Q?
可以包含多个子元素,首先查找W一个文件?
׃元素中不能配|Servlet映射Q因此不能直接把Structs的Action作ؓƢ迎文gQ可以采用一U变通的Ҏ来实现在Ƣ迎文g中调用Structs Action?
首先Q在Structs配置文g中ؓ被调用的Action创徏一个全局的{发项Q例如:
xml 代码
创徏一个welcome.jsp的文Ӟ最后在web.xml文g中把welcome.jsp文g配置为欢q文Ӟ代码如下Q?/span>
xml 代码
W四步:配置错误处理
xml 代码
也可以ؓWeb容器捕获的Java异常配置,需要设|子元素Q它用于指定Java异常cRWeb容器可能捕获如下异常QRuntimeException或Error ServletException或它的子c,IOException或它的子c:
xml 代码
W五步:配置Structs标签?
使用客户化的标签库,要配|它们:
xml 代码
用于指定标签库的相对或者绝对URI地址QWeb应用Ҏq一URI来访问标{ֺ?
指定标签描述文g在文件资源系l中的物理位|?
2、Structs配置文g
Structs框架在启动时会读入其配置文gQ根据它来创建和配置各种Structslg?br />
Q?Q元?br />
元素是Structs配置文g的根元素Q元素有8个子元素。它的DTD定义如下Q?/span>
xml 代码
在Struts配置中,必须按照以上的DTD指定的先后顺序来配置元素的各个子元素Q如果颠倒了q些元素的配|文件中的位|,在Structs应用启动时会生成错误?
元素
元素包含零个、一个或者多个子元素Q用于配|特定的数据源,它可以包含多个子元素Q用于设|数据源的各U属性?
配置了数据源后,可以在ActioncM讉K数据源,在org.apache.structs.action.ActioncM定义了getDataSource(HttpRequrst)ҎQ它用于获取数据源对象的引用?/span>
DataSource dataSource; Connection connection; dataSource =getDataSource(request); connection=dataSource.getConnection(); |
也可以在配置文g中声明多个数据源Q此旉要ؓ每一个数据源分配唯一的key|通过改值来标识特定的数据源?
Q?Q?元素
元素用来配置多个ActionForm BeanQ?包含多个子元素,,每个包含多个属性,ClassName , name,typeQ?/span>
xml 代码
注意Q配|动态ActionForm BeanQ还必须配置 元素?元素?/span>
xml 代码
(3)元素
用于配置异常处理Q元素可以包含零个或者多个元素?
元素用来讄java异常和异常处理类org.apache.structs.action,Exception Hander之间的映?
(4)元素
元素用来声明全局的{发关p,有零个或多个元素l成。元素用于把一个逻辑映射到特定的URL
属?/span> |
?q?/span> |
className |
和元素对应的配置c, 默认为org.apache.structs. action.ActionForWard |
name |
转发路径的逻辑名, 此项时必ȝ |
path |
指定或者重定向的URI?此项时必ȝQ?必须?#8221;/”开?/span> |
redirect |
此项是trueQ表C是执行重定向的操作Q?此项是falseӞ 表示h转发?/span> |
xml 代码
如果jsp1.jsp把请求{发给Action1,可以使用以下代码Q?/span>
xml 代码
或?/span>
xml 代码
如果Action1的executeQ)Ҏ把请求{发给JSP2.jspQ可以用一下代码:
return(mapping.findForward(“forward2”)) |
(5)元素
元素包含零个或者多个元素。元素描qC从特定的h路径到相应的Actioncȝ映射?
(6)元素
元素用于配置ActionServlet?
(7)< message-resources>元素
元素用于配置Resource BundleQResource Budle用于存放本地化消息文件?
Structs标签
HTML标签
标签?描述
base 包装HTML的base元素
button 包装HTML?buttoncd的input元素
cancel 包装HTML cancel 按钮
checkbox 包装HTML checkbox cd的输入域
errors 有条件地昄一些error消息Q显CActionErrors信息
file 包装HTML文g上传输入?
form 定义HTML form 元素
frame 包装HTML frame 元素
hidden 包装HTML hidden 输入?
html 包装 HTML中的 html 元素
image 包装 "image"cd的输入域
img 包装HTML?img 元素
javascript 包装ҎValidatorPlugIn提供的校验规则所提供的javascript校验脚本
link 包装链?
messages 有条件地昄一些提CZ息,昄ActionMessages信息
multibox 包装多选输入框
option 包装一个选择输入?
options 包装一扚w择输入?
optionsCollection 包装一扚w择输入框集
password 包装密文输入?
radio 包装单选输入框
reset 包装“重置”功能的按?
rewrite 包装一个URL
select 包装一个选择输入?
submit 包装一个提交按?
text 包装一个文本输入框
textarea 包装一个备注输入框
ActionForm
ActionForm 的要?
创徏一个ActionForm q不困难Q但是你的类必须W合一些要求:
ActionForm 必须扩展自org.apache.struts.ActionForm。基cActionForm 是不能实
例化的?
ActionForm 必须为每个应该从h中收集的HTML控g定义一个公共属性?
(Struts 1.0 要求每个属性都要mutator 和accessor 。Struts 1.1 则没有如此严?
ActionFormq可能要W合一些可选的要求:
如果你要求ActionForm 在传递属性到Action之前校验它们Q你必d现validate
ҎQ如果想在组装前初始化属性,必须实现reset , 它在ActionForm l装前被调用?
动态ActionForm
ActionForm 作ؓcd转换?
ActionForm的一个强制点是应该用String 和boolean属性。实际上Q这意味着属?
必须得从一U{换到另一U类型。大部分应用也需要一些属性,比如电话L或者数量,以一U格式化的方式出现?
核心Java 包提供一些工h做这U事情,但是要清楚地他们集成到应用中仍然是一个挑战?
Struts开发h员经常在ActionForm中包含helperҎQ来q行cd转换。helper Ҏ
可以有很多种实现方式?
5.2.6 ActionForm 作ؓ防火?
当请求提交时QActionServlet 使用一个自动组装机制来从请求参C讄h?
ActionForm属性。这让你可以通过控制哪个ActionForm 属性被暴露来控制哪个请求参?
是可接受的。这也意味着如果你的ActionForm 的粗心设计你可能失去控制哪个参数可以接受的能力。ActionForm一定不能包含看h像是一个JavaBean属性,但不能从HTTPh讄的属性方法?
5.3.4 ActionForm 可以嵌套其它bean
因ؓStruts标签扩展和自动组装机刉支持点号语法来从ActionForm讉K其它bean。这是一个方便的方式Q可以通过ActionForm来组装存在的bean。在JSP面,你可以象q样引用一个嵌套的beanQ?/span>
xml 代码
5.7.2 分发QDispatch Q?
Struts 开发h员通常使用同一个Action处理相关的操作。一个通常做法来选择操作是在
HTML表单中用隐藏属性。BaseForm 的dispatch 属性也可用作这个目的:
public void setDispatch(String dispatch); public String getDispatch(); |
Struts 配置提供q个U别嵌套的ActionForward:
Global Q全局Q?ActionForwardҎ个应用中的所有Action 对象均有效;
Local Q局部) ActionForward 则在ActionMapping 元素中定义?
仅对那些在这个ActionMapping中调用的Action对象有效。从Action 对象内部来看Qforward 通常像这h选择Q?/span>
ActionForward forward = mapping.findForward("continue"); |
原来把JSP中的字符~码设ؓUTF-8,再把整个工程的编码设为UTF-8可以了.
在tomcat5.5中已l好?不知道其它的服务器怎么?
q以为需要在拦截器或filter中设|呢.
做项目都应该加上字符~码的filterQ?
例如Q(下面是用到spring里面的filterQ?
<!-- 用于解决h~码q问题 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>