??xml version="1.0" encoding="utf-8" standalone="yes"?> 目前支持的类型有Q?
M提供两类功能Q?
1. 字W串转换为指定类型;
2. 注册、注销和查询类型{换器Q?/font> Q意的实例转变?font face='"Times' New Roman">StringQ用法非常简单。在试的过E中Q感觉与调用实例上的toString()Ҏ的效果一P不知道是不是在这个方法内仅仅是调用了传入实例?font face='"Times' New Roman">toString()Ҏ?/font> ps:需要读源代码才能清楚?/font> 字W串value转换?font face='"Times' New Roman">clazz的一个实例;如果p|的话Q就?font face='"Times' New Roman">String的Ş式返?font face='"Times' New Roman">value?
q个Ҏ是对前一Ҏ的加强版Q将数组中的每个value都进行{换,最后以Objectq回。(数组也是Object啊)
注销转换器,前者将所有的转换器注销掉,后者只注销对应?font face='"Times' New Roman">clazz的{换器。注销在这里不是彻底删除了Q而是{换器变ؓ默认的{换器Q?font face='"Times' New Roman">apache commons提供的)?/font> 获取指定cdclazz的{换器. 为指定类?font face='"Times' New Roman">clazz注册转换?font face='"Times' New Roman">converter。如?font face='"Times' New Roman">clazz已经存在一个对应的转换器,那么converterQ将覆盖原来的{换器。也是_我们可以?font face='"Times' New Roman">String,Double创徏自定义的cd转换器,q在注册后进行用?/font> ps:apache的类定义明确Q描q非常清楚,所以就不脓Z子了。当然这只是到达可以正常使用的阶D,如果要进行改造或者创qConvertUtilsQ那可能需要更多的旉Q因要去参?font face='"Times' New Roman">ConvertUtilsBeanQ这里就不详qC?br />
[摘要]:校验框架配置、客L校验
[关键字]:曦视频QStruts2应用开发系列,WebWorkQApacheQvalidation
[环境]:struts-2.1.6、JDK6、MyEclipse7、Tomcat6
[作者]:Winty (wintys@gmail.com) http://www.aygfsteel.com/wintys
[正文]:
Struts校验框架提供了一U不用编写代码,只需修改配置文g卛_对输入进行校验的功能。代码方式校验,即重写validate()Ҏ。实际应用中Q?strong>validate()与校验框架一般只选其一?br />
1、校验框枉|?br />
在RegisterAction.java相同目录新徏校验框架配置文gRegisterAction-validation.xml。RegisterAction-validation.xml的DTD可以复制struts自带的示例struts2-mailreader-2.1.6中的DTD:
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
xwork-validator-1.0.2.dtd:
<!--
XWork Validators DTD.
Used the following DOCTYPE.
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-->
<!ELEMENT validators (field|validator)+>
<!ELEMENT field (field-validator+)>
<!ATTLIST field
name CDATA #REQUIRED
>
<!ELEMENT field-validator (param*, message)>
<!ATTLIST field-validator
type CDATA #REQUIRED
short-circuit (true|false) "false"
>
<!ELEMENT validator (param*, message)>
<!ATTLIST validator
type CDATA #REQUIRED
short-circuit (true|false) "false"
>
<!ELEMENT param (#PCDATA)>
<!ATTLIST param
name CDATA #REQUIRED
>
<!ELEMENT message (#PCDATA)>
<!ATTLIST message
key CDATA #IMPLIED
>
RegisterAction-validation.xml:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<!--
与field{h的validator
<validator type="requiredstring">
<param name="fieldName">name</param>
<param name="trim">true</param>
<message>name required</message>
</validator>
<validator type="stringlength">
<param name="fieldName">name</param>
<param name="trim">true</param>
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>name length range : ${minLength} ~ ${maxLength}</message>
</validator>
-->
<field name="name">
<field-validator type="requiredstring" >
<param name="trim">true</param>
<message>name required</message>
</field-validator>
<field-validator type="stringlength">
<param name="trim">true</param>
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>name length range : ${minLength} ~ ${maxLength}</message>
</field-validator>
</field>
<field name="age">
<field-validator type="conversion" short-circuit="true">
<message>the field age conversion error</message>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<message>age range: ${min} ~ ${max}</message>
</field-validator>
</field>
<field name="birthday">
<field-validator type="required">
<message>birthday required</message>
</field-validator>
<field-validator type="date">
<param name="min">2009-01-01</param>
<param name="max">2009-12-31</param>
<message>birthday range: ${min} ~ ${max}</message>
</field-validator>
</field>
<field name="email">
<field-validator type="email">
<message>invalid email address</message>
</field-validator>
</field>
</validators>
说明:
a.校验框架有两U校验方?field和validator?br />
field校验:先指定需要校验的属性,再指定校验方式。validator校验:先指定校验方式,再指定需要校验的属性。两U方式是{h的?br />
field校验:
<field name="name">
<field-validator type="requiredstring" >
<param name="trim">true</param>
<message>name required</message>
</field-validator>
<field-validator type="stringlength">
<param name="trim">true</param>
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>name length range : ${minLength} ~ ${maxLength}</message>
</field-validator>
</field>
validator校验:
<validator type="requiredstring">
<param name="fieldName">name</param>
<param name="trim">true</param>
<message>name required</message>
</validator>
<validator type="stringlength">
<param name="fieldName">name</param>
<param name="trim">true</param>
<param name="minLength">6</param>
<param name="maxLength">10</param>
<message>name length range : ${minLength} ~ ${maxLength}</message>
</validator>
b.<field-validator type="requiredstring" >中的type及其对应的xworkcd以在xwork-2.1.2.jar/com.opensymphony.xwork2.validator.validators/default.xml中查扑ֈ?br />
default.xml:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<!-- START SNIPPET: validators-default -->
<validators>
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
</validators>
<!-- END SNIPPET: validators-default -->
c. 对于校验<field-validator type="requiredstring" >:String用requiredstringQ其它类型用required?br />
d. 验证错误默认生FieldError?br />
e. short-circuit="true" : 一个校验失败,是否是l执行后l校验?br />
f. 对于相同属性的FieldErrorQvalidate()Ҏ中的验证和RegisterAction-validation.xml中的验证都会执行,q且FieldError都会昄?br />
执行序: RegisterAction-validation.xml => validate()?br />
2、特定于业务逻辑的局部校?
对于struts.xml?lt;action>的method="register"指定的业务方法register()Q用校验RegisterAction-register-validation.xml(与RegisterAction.java在同一目录?。同ӞRegisterAction-validation.xml会被执行。执行顺? RegisterAction-validation.xml => RegisterAction-register-validation.xml
3、Struts2客户端校?br />
讄struts标签<s:form>中validate="true"。这样就会根据RegisterAction-validation.xml生成面JavascriptQ在客户端执行校验?br />
注意:
a.struts标签不能使用simple主题?br />
b.Struts2客户端校验功能较弱,一般不用?br />
4、FieldError和ActionError的实?br />
a.真正存放fieldU别错误信息的对象是LinkedHashMap?br />
b.该LinkedHashMap的key是Stringcd的,value是ArrayListcdQ所以同一个key可以对应多个错误消息?br />
c.对于ActionU别的错误信息,实际上是攄在ArrayList中的?br />
[参考资料]:
《浪曦视频之Struts2应用开发系列?br />
]]>
convert(java.lang.Object value)
convert(java.lang.String value, java.lang.Class clazz)
convert(java.lang.String[] values, java.lang.Class clazz)
deregister()?a href_cetemp='http://www.itepub.net/html/kaifajingcui/Java/2006/0514/"file:///F:/software/apache/commons/commons-beanutils-1.7.0/docs/api/org/apache/commons/beanutils/ConvertUtils.html#deregister()"'>deregister(java.lang.Class clazz)
lookup(java.lang.Class clazz)
register(Converter converter, java.lang.Class clazz)
以下Z用convertUtils的一个DATEcd的例子(该例子来源于学堂视屏)
1.定义converter
package com.bjsxt.oa.web;
2
3import java.text.ParseException;
4import java.text.SimpleDateFormat;
5import java.util.Date;
6
7import org.apache.commons.beanutils.Converter;
8
9public class UtilDateConverter implements Converter {
10
11 private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
12
13 public Object convert(Class type, Object value) {
14 if (value == null) {
15 return value;
16 }
17 if (value instanceof Date) {
18 return value;
19 }
20 if (value instanceof String) {
21 try {
22 return format.parse((String)value);
23 } catch (ParseException e) {
24 e.printStackTrace();
25 }
26 }
27 return null;
28 }
29
30}
31
package com.bjsxt.oa.web;
2
3import java.util.Date;
4
5import javax.servlet.ServletException;
6import javax.servlet.http.HttpServlet;
7
8import org.apache.commons.beanutils.ConvertUtils;
9
10public class UtilDateConverterInitServlet extends HttpServlet {
11
12 @Override
13 public void init() throws ServletException {
14 ConvertUtils.register(new UtilDateConverter(), Date.class);
15 }
16
17}
18
<servlet>
2 <servlet-name>utilDateConverter</servlet-name>
3 <servlet-class>com.bjsxt.oa.web.UtilDateConverterInitServlet</servlet-class>
4 <load-on-startup>3</load-on-startup>
5 </servlet>
]]>
BeanUtils提供?Java反射和自省API的包装。其主要目的是利用反机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,?多情况下Q对JavaBean的处理导致大量get/set代码堆积Q增加了代码长度和阅M码的隑ֺ?br />
二、用法:
BeanUtils是这个包里比较常用的一个工LQ这里只介绍它的copyProperties()Ҏ。该Ҏ定义如下Q?br />
public static void copyProperties(java.lang.Object dest,java.lang.Object orig)
throws java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException
?果你有两个具有很多相同属性的JavaBeanQ一个很常见的情况就是Struts里的PO对象Q持久对象)和对应的ActionFormQ例?Teacher和TeacherForm。我们一般会在Action里从ActionForm构造一个PO对象Q传l的方式是用类g面的语句对属性?个赋|
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋?br />
teacher.setName(teacherForm.getName());
teacher.setAge(teacherForm.getAge());
teacher.setGender(teacherForm.getGender());
teacher.setMajor(teacherForm.getMajor());
teacher.setDepartment(teacherForm.getDepartment());
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);
而用BeanUtils后,代码大大改观了Q如下所C:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋?br />
BeanUtils.copyProperties(teacher,teacherForm);
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);
?果Teacher和TeacherForm间存在名UC相同的属性,则BeanUtils不对q些属性进行处理,需要程序员手动处理。例?Teacher包含modifyDateQ该属性记录最后修Ҏ期,不需要用户在界面中输入)属性而TeacherForm无此属性,那么在上面代码的 copyProperties()后还要加上一句:
teacher.setModifyDate(new Date());
?么样Q很方便吧!除BeanUtils外还有一个名为PropertyUtils的工LQ它也提供copyProperties()ҎQ作用与 BeanUtils的同名方法十分相|主要的区别在于后者提供类型{换功能,卛_C个JavaBean的同名属性ؓ不同cdӞ在支持的数据cd范围 内进行{换,而前者不支持q个功能Q但是速度会更快一些。BeanUtils支持的{换类型如下:
* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp
q里要注意一点,java.util.Date是不被支持的Q而它的子cjava.sql.Date是被支持的。因此如果对象包含时间类型的属性,且希望被转换的时候,一定要使用java.sql.Datecd。否则在转换时会提示argument mistype异常?br />
三、优~点Q?br />
Apache Jakarta Commons目非常有用。我曑֜许多不同的项目上或直接或间接C用各U流行的commonslg。其中的一个强大的lg是BeanUtils。我 说明如何用BeanUtilslocal实体bean转换为对应的value 对象Q?br />
BeanUtils.copyProperties(aValue, aLocal)
?面的代码从aLocal对象复制属性到aValue对象。它相当单!它不localQ或对应的valueQ对象有多少个属性,只管q行复制。我们假?local对象?00个属性。上面的代码使我们可以无需键入臛_100行的冗长、容易出错和反复的get和setҎ调用。这太棒了!太强大了Q太有用 了!
现在Q还有一个坏消息Q用BeanUtils的成本惊人地昂贵Q我做了一个简单的试QBeanUtils所p的时间要过取数 据、将其复制到对应?value对象Q通过手动调用get和setҎQ,以及通过串行化将其返回到q程的客h的时间d。所以要心使用q种威力Q?
该文章的原文地址为:http://lifejava.spaces.live.com/Blog/cns!A666C33543221640!158.entry
]]>
pg:pager【这个标{来设|分늚M参数】重要参数说明:
url:分页的链接根地址Qpager标签会在q个链接的基上附加分参?br />
items:总记录数Qpager标签正是Ҏq个值来计算分页参数?br />
maxPageItems:每页昄的行敎ͼ默认?0
maxIndexPages:在@环输出页码的时候,最大输出多个늠Q默认是10
pg:first【第一늚标签】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址Q最重要的export参数Q?br />
pageNumber - 늠
firstItem - 首页W一行的索引?br />
lastItem - 首页最后一行的索引?br />
pg:pre【上一|{】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址Q最重要的export参数Q?br />
pageNumber - 늠
firstItem - 前页W一行的索引?br />
lastItem - 前页最后一行的索引?br />
pg:next【下一|{】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址Q最重要的export参数Q?br />
pageNumber - 늠
firstItem - 下页W一行的索引?br />
lastItem - 下页最后一行的索引?br />
pg:last重要参数说明Q?br />
export变量的意义:
pageUrl - 分页链接URL地址Q最重要的export参数Q?br />
pageNumber - 늠
firstItem - NW一行的索引?br />
lastItem - N最后一行的索引?br />
pg:pages【这个标{来@环输出页码信息】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址Q最重要的export参数Q?br />
pageNumber - 늠
firstItem - pageNumberq个늠指定的那一늚W一行的索引?br />
lastItem - pageNumberq个늠指定的那一늚最后一行的索引?br />
pager-taglib-2.0下蝲
http://www.aygfsteel.com/Files/wx886104/pager-taglib-2.0.rar
]]>
* 在struts-config.xml文g中加入:<message-resources parameter="MessageResources" />
2、提供不同版本的国际化资源文Ӟ中文需要采用native2ascii转换成unicode
3、在jsp中采?lt;bean:message>标签来读取国际化消息文本
4、了解利用struts默认locale攑ֈsession中的Ҏ,完成采用~程的方式切换语a讄
* 参见QChangeLanguageAction.java
5、消息文本的国际化处理,共有三个步骤Q?br />
* 创徏国际化消?br />
* 传递国际化消息
* 昄国际化消?br />
如何创徏国际化消息?
理解ActionMessage和ActionMessages两个对象的区?br />
如何传递国际化消息Q?br />
* 调用saveMessage()传递普通消息,调用saveErrors传递错误消?br />
如何昄国际化消息?
通过<html:messages>标签昄消息Q可以显C普通消息和错误消息Q?br />
通过<html:errors>昄消息Q只能显C错误消息)
当将国际化资源文件放入到一个包Ӟ在struts-config.xml文g中加入:<message-resources parameter="包名.MessageResources" />
ChangeLanguageAction.java
所需资源Q?
ReadCookieAction.java- d Cookie 集合Q如果找到对?Cookie Q写?Session Q?
Login.jsp- d用页面;
LoginSubmit.java- 记录d信息Qƈ写入 Session Q?
LoginOk.jsp- d Session Qƈ昄?
?Cookie 的方?Q?
Cookie[] cookies = request.getCookies();
if (cookies != null ) {
for ( int i=0; i<cookies. length ; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals( "userInfo" )) {
String value = cookie.getValue();
String[] info = value.split( "_" );
UserForm userForm = new UserForm();
userForm.setUserName(info[0]);
userForm.setUserPassword(info[1]);
request.getSession().setAttribute( "userForm" , userForm);
return mapping.findForward( "ok" );
}
}
}
?Cookie 的方法:
Cookie c = new Cookie( "userInfo" ,userForm.getUserName()+ "_" +userForm.getUserPassword());
c.setComment( "A test cookie" );
c.setMaxAge(120);
response.addCookie(c);
首先建立一个FileAction
package com.action;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import com.actionForm.FileActionForm;
import org.apache.struts.actions.DispatchAction;
import java.util.Date;
import java.text.*;
import org.apache.struts.upload.FormFile;
import java.io.*;
import java.net.URLEncoder;
import com.dao.*;
public class FileAction extends DispatchAction {
private JDBConnection connection =new JDBConnection();
//以下Ҏ实现文g的上?/span>
public ActionForward upLoadFile(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws
Exception {
ActionForward forward=null;
Date date = new Date();
FileActionForm fileActionForm = (FileActionForm) form;
//FormFile用于指定存取文g的类?br />
FormFile file = fileActionForm.getFile(); //获取当前的文?/span>
// 获得pȝ的绝对\?/span> String dir = servlet.getServletContext().getRealPath("/image");
//我上传的文g没有攑֜服务器上。而是存在D:D:\\loadfile\\temp\\
String dir="D:\\loadfile\\temp\\";
int i = 0;
String type = file.getFileName();
while(i!=-1){
//扑ֈ上传文g的类型的位置Q这个地方的?.'
i = type.indexOf(".");
/* System.out.println(i);*/
/*截取上传文g的后~?此时得到了文件的cd*/
type = type.substring(i+1);
}
// 限制上传cd为jpg,txt,rar;
if (!type.equals("jpg") && !type.equals("txt")&& !type.equals("bmp"))
{//当上传的cd不ؓ上述cdӞ跌{到错误页面?/span>
forward=mapping.findForward("error");
}
else
{
// 上传时间加入文件名Q这个地方的是毫U数Q?nbsp;
String times = String.valueOf(date.getTime());
//l合?time.type
String fname = times + "." + type;
//InInputStream是用以从特定的资源读取字节的Ҏ?br />
InputStream streamIn = file.getInputStream(); //创徏d用户上传文g的对?br />
//得到是字节数Q即byte,我们可以直接用file.getFileSize(),也可以在创徏d对象时用streamIn.available();
// int ok=streamIn.available();
int ok=file.getFileSize();
String strFee = null;
//q个地方是处理上传的为M单位计算Ӟ下一个是以kb,在下一个是byte;
if(ok>=1024*1024)
{
float ok1=(((float)ok)/1024f/1024f);
DecimalFormat myformat1 = new DecimalFormat("0.00");
strFee = myformat1.format(ok1)+"M";
System.out.println(strFee+"M");
}
else if(ok>1024 && ok<=1024*1024)
{
double ok2=((double)ok)/1024;
DecimalFormat myformat2=new DecimalFormat("0.00");
strFee = myformat2.format(ok2)+"kb";
System.out.println(strFee+"kb");
}
else if(ok<1024)
{
System.out.println("aaaaaaaaa");
strFee=String.valueOf(ok)+"byte";
System.out.println(strFee);
}
System.out.println( streamIn.available()+"文g大小byte");
//q个是io包下的上传文件类
File uploadFile = new File(dir); //指定上传文g的位|?br />
if (!uploadFile.exists() || uploadFile == null) { //判断指定路径dir是否存在Q不存在则创\?br />
uploadFile.mkdirs();
}
//上传的\?文g?br />
String path = uploadFile.getPath() + "\\" + fname;
//OutputStream用于向某个目标写入字节的抽象c,q个地方写入目标是pathQ通过输出FileOutputStreamd
OutputStream streamOut = new FileOutputStream(path);
int bytesRead = 0;
byte[] buffer = new byte[8192];
//数据读入byte数组的一部分Q其中读入字节数的最大值是8192Q读入的字节存储到Qbuffer[0]到buffer[0+8190-1]的部分中
//streamIn.readҎq回的是实际d字节数目.如果d末尾则返?1.如果bytesReadq回?则表C没有读取Q何字节?br />
while ((bytesRead = streamIn.read(buffer, 0, 8192)) != -1) {
//写入buffer数组的一部分Q从buf[0]开始写入ƈ写入bytesRead个字节,q个writeҎ发生阻塞直臛_节写入完成?br />
streamOut.write(buffer, 0, bytesRead);
}
// 关闭输出输入?销毁File?br />
streamOut.close();
streamIn.close();
file.destroy();
String paths=path;
System.out.println(paths);
String fileName = Chinese.toChinese(fileActionForm.getFileName()); //获取文g的名U?/span>
//String fileSize = String.valueOf(file.getFileSize());
String fileDate = DateFormat.getDateInstance().format(date);
String sql = "insert into tb_file values('" + fileName + "','" +
strFee + "','" + fileDate + "','" + paths + "')";
connection.executeUpdate(sql);
connection.closeConnection();
forward=mapping.findForward("upLoadFileResult");
}
return forward;
}
//实现文g的下?br />
public ActionForward downFile(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws
Exception {
String path = request.getParameter("path");
System.out.println(path+"111");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
OutputStream fos = null;
InputStream fis = null;
//如果是从服务器上取就用这个获得系l的l对路径Ҏ?nbsp; String filepath = servlet.getServletContext().getRealPath("/" + path);
String filepath=path;
System.out.println("文g路径"+filepath);
File uploadFile = new File(filepath);
fis = new FileInputStream(uploadFile);
bis = new BufferedInputStream(fis);
fos = response.getOutputStream();
bos = new BufferedOutputStream(fos);
//q个就是弹Z载对话框的关键代?/span>
response.setHeader("Content-disposition",
"attachment;filename=" +
URLEncoder.encode(path, "utf-8"));
int bytesRead = 0;
//q个地方的同上传的一栗我׃多说了,都是用输入流q行先读Q然后用输出去写,唯一不同的是我用的是~冲输入输出?br />
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
fis.close();
bis.close();
fos.close();
bos.close();
return null;
}
}
FileActionForm
package com.actionForm;
import org.apache.struts.action.*;
import org.apache.struts.upload.*;
public class FileActionForm extends ActionForm {
private String fileName;//上传文g的名U?br />
private String fileSize;//上传文g的大?br />
private String filePath;//上传文g到服务器的\?br />
private String fileDate;//上传文g的日?br />
private FormFile file;//上传文g
public String getFileName() {
return fileName;
}
public FormFile getFile() {
return file;
}
public String getFileSize() {
return fileSize;
}
public String getFilePath() {
return filePath;
}
public String getFileDate() {
return fileDate;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setFile(FormFile file) {
this.file = file;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public void setFileDate(String fileDate) {
this.fileDate = fileDate;
}
}
index.jsp 此位|的form是javabeen的对象,q个javabeen中存取的囄的相关信?/span>
<table width="264" height="81" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="115" rowspan="4" align="center"><img src="<%=form.getFilePath()%>" width="100" height="100"></td>
<td width="133" align="center">囄名称Q?lt;%=form.getFileName()%></td>
</tr>
<tr align="center">
<td>囄大小Q?lt;%=form.getFileSize()%></td>
</tr>
<tr align="center">
<td>上传日期:<%=form.getFileDate()%></td>
</tr>
<tr>
<td align="center"><a href="fileAction.do?method=downFile&path=<%=form.getFilePath()%>" ><img src="priture/bottond.jpg"></a>
</td>
</tr>
</table>
<html:form action="fileAction.do?method=upLoadFile" enctype="multipart/form-data" onsubmit="return Mycheck()">
<table height="52" border="0" align="center" cellpadding="0" cellspacing="0">
<tr align="center">
<td width="60" height="26">囄名称:</td>
<td width="160"> <html:text property="fileName"/> </td>
<td width="60">囄路径:</td>
<td width="198"> <html:file property="file"/> </td>
</tr>
<tr align="right">
<td height="26" colspan="4"> <html:submit>上传</html:submit> </td>
</tr>
</table>
</html:form>
struts-config.xml
<?xml version="1.0" encoding="UTF-8"?> <struts-config>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "
<form-beans>
<form-bean name="fileActionForm" type="com.actionForm.FileActionForm" />
</form-beans>
<action-mappings>
<action name="fileActionForm" parameter="method" path="/fileAction" scope="request" type="com.action.FileAction" validate="true">
<forward name="upLoadFileResult" path="/result.jsp"/>
<forward name="error" path="/fail.jsp"></forward>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources" />
</struts-config>
转自javaEye http://www.javaeye.com/topic/219585
]]>