上一节我们做完了添加和更新商品的功能,这两个部分里有涉及到商品图片的上传,并没有详细解说。为此,这篇文章详细介绍一下Struts2实现文件上传的功能。
1. 封装文件信息
我们首先得有一个Model来封装文件的信息,这个Model里需要有三个属性:文件、文件类型和文件名。针对我们要传的图片,我们新建一个Model如下:
- public class FileImage {
- private File file;
- private String contentType;
- private String filename;
- public File getFile() {
- return file;
- }
- public String getContentType() {
- return contentType;
- }
- public String getFilename() {
- return filename;
- }
- public void setUpload(File file) { //set方法可以不用和属性名一样,但是前台传进来时的参数得和set方法名相同。即前台传的参数为fileImage.upload
- this.file = file;
- }
- public void setUploadContentType(String contentType) {
- this.contentType = contentType;
- }
- public void setUploadFileName(String filename) {
- this.filename = filename;
- }
- }
public class FileImage {
private File file;
private String contentType;
private String filename;
public File getFile() {
return file;
}
public String getContentType() {
return contentType;
}
public String getFilename() {
return filename;
}
public void setUpload(File file) { //set方法可以不用和属性名一样,但是前台传进来时的参数得和set方法名相同。即前台传的参数为fileImage.upload
this.file = file;
}
public void setUploadContentType(String contentType) {
this.contentType = contentType;
}
public void setUploadFileName(String filename) {
this.filename = filename;
}
}
这样Model就写好了,考虑到文件上传的逻辑不是单个Action所特有的,所以我们将文件上传的逻辑写到工具类中,这样可供所有的Action调用。所以我们新建一个文件上传工具类(为了面向接口编程,我们也将工具类抽出个接口):
2. 完成文件上传工具类
- //文件上传工具类接口
- public interface FileUpload {
- //实现文件上传的功能,返回上传后新的文件名称
- public abstract String uploadFile(FileImage fileImage);
- }
- //文件上传工具类具体实现
- @Component(“fileUpload”)
- public class FileUploadUtil implements FileUpload {
- private String filePath;
- @Value(“#{prop.filePath}”)
- //@Value表示去beans.xml文件中找id=”prop”的bean,它是通过注解的方式读取properties配置文件的,然后去相应的配置文件中读取key=filePath的值
- public void setFilePath(String filePath) {
- System.out.println(filePath);
- this.filePath = filePath;
- }
- //1. 通过文件名获取扩展名
- private String getFileExt(String fileName) {
- return FilenameUtils.getExtension(fileName);
- }
- //2. 生成UUID随机数,作为新的文件名
- private String newFileName(String fileName) {
- String ext = getFileExt(fileName);
- return UUID.randomUUID().toString() + “.” + ext;
- }
- //实现文件上传的功能,返回上传后新的文件名称
- @Override
- public String uploadFile(FileImage fileImage) {
- //获取新唯一文件名
- String pic = newFileName(fileImage.getFilename());
- try {
- FileUtil.copyFile(fileImage.getFile(), new File(filePath, pic));//第一个参数是上传的文件,第二个参数是将文件拷贝到新路径下
- return pic;
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- fileImage.getFile().delete();
- }
- }
- }
//文件上传工具类接口
public interface FileUpload {
//实现文件上传的功能,返回上传后新的文件名称
public abstract String uploadFile(FileImage fileImage);
}
//文件上传工具类具体实现
@Component("fileUpload")
public class FileUploadUtil implements FileUpload {
private String filePath;
@Value("#{prop.filePath}")
//@Value表示去beans.xml文件中找id="prop"的bean,它是通过注解的方式读取properties配置文件的,然后去相应的配置文件中读取key=filePath的值
public void setFilePath(String filePath) {
System.out.println(filePath);
this.filePath = filePath;
}
//1. 通过文件名获取扩展名
private String getFileExt(String fileName) {
return FilenameUtils.getExtension(fileName);
}
//2. 生成UUID随机数,作为新的文件名
private String newFileName(String fileName) {
String ext = getFileExt(fileName);
return UUID.randomUUID().toString() + "." + ext;
}
//实现文件上传的功能,返回上传后新的文件名称
@Override
public String uploadFile(FileImage fileImage) {
//获取新唯一文件名
String pic = newFileName(fileImage.getFilename());
try {
FileUtil.copyFile(fileImage.getFile(), new File(filePath, pic));//第一个参数是上传的文件,第二个参数是将文件拷贝到新路径下
return pic;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
fileImage.getFile().delete();
}
}
}
上面有个@Value注解,是从properties文件中获取文件要存入的路径的,具体可参见:Spring获取配置文件信息 。
3. 在Action中注入封装文件类和工具类
写好了文件封装类和上传文件工具类后,我们需要将这两个对象注入到我们的Action中,这样就可以在Action中实现文件上传的功能了:
- @Controller(“baseAction”)
- @Scope(“prototype”)
- public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {
- //封装了图片信息的类
- protected FileImage fileImage;
- //上传文件工具类
- @Resource
- protected FileUpload fileUpload;
- public FileImage getFileImage() {
- return fileImage;
- }
- public void setFileImage(FileImage fileImage) {
- this.fileImage = fileImage;
- }
- //省略其他无关代码……
- }
@Controller("baseAction")
@Scope("prototype")
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {
//封装了图片信息的类
protected FileImage fileImage;
//上传文件工具类
@Resource
protected FileUpload fileUpload;
public FileImage getFileImage() {
return fileImage;
}
public void setFileImage(FileImage fileImage) {
this.fileImage = fileImage;
}
//省略其他无关代码……
}
4. 实现文件的上传
好了,现在我们可以在ProductAction中去实现文件上传了,工具类写好的话,在Action中的代码量就很少了,这也是封装带来的优点。
- @Controller(“productAction”)
- @Scope(“prototype”)
- public class ProductAction extends BaseAction<Product> {
- //省略其他无关代码……
- public void save() throws Exception {
- //fileUpload工具类被抽取了,uploadFile方法直接接受一个fileImage对象,返回新的图片名
- String pic = fileUpload.uploadFile(fileImage);
- model.setPic(pic);
- model.setDate(new Date());
- System.out.println(model);
- //商品信息入库
- productService.save(model);
- }
- public void update() {
- String pic = fileUpload.uploadFile(fileImage);
- model.setPic(pic);
- model.setDate(new Date());
- System.out.println(model);
- //更新商品
- productService.update(model);
- }
- }
@Controller("productAction")
@Scope("prototype")
public class ProductAction extends BaseAction<Product> {
//省略其他无关代码……
public void save() throws Exception {
//fileUpload工具类被抽取了,uploadFile方法直接接受一个fileImage对象,返回新的图片名
String pic = fileUpload.uploadFile(fileImage);
model.setPic(pic);
model.setDate(new Date());
System.out.println(model);
//商品信息入库
productService.save(model);
}
public void update() {
String pic = fileUpload.uploadFile(fileImage);
model.setPic(pic);
model.setDate(new Date());
System.out.println(model);
//更新商品
productService.update(model);
}
}
这样我们就完成了从前台上传文件的功能。
相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html
整个项目的源码下载地址:http://blog.csdn.NET/eson_15/article/details/51479994
_____________________________________________________________________________________________________________________________________________________
—–乐于分享,共同进步!
<div id="digg" articleid="51366384">
<dl id="btnDigg" class="digg digg_enable" onclick="btndigga();">
<dt>顶</dt>
<dd>5</dd>
</dl>
<dl id="btnBury" class="digg digg_enable" onclick="btnburya();">
<dt>踩</dt>
<dd>0</dd>
</dl>
</div>
<div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank"> </a> </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank"> </a></div>
<script type="text/javascript">
function btndigga() {
$(".tracking-ad[data-mod='popu_222'] a").click();
}
function btnburya() {
$(".tracking-ad[data-mod='popu_223'] a").click();
}
</script>
<div style="clear:both; height:10px;"></div>
<div class="similar_article" style="">
<h4>我的同类文章</h4>
<div class="similar_c" style="margin:20px 0px 0px 0px">
<div class="similar_c_t">
<label class="similar_cur">
<span style="cursor:pointer" onclick="GetCategoryArticles('6228418','eson_15','foot','51366384');">● 框架技术<em>(45)</em></span>
</label>
<label class="">
<span style="cursor:pointer" onclick="GetCategoryArticles('6183974','eson_15','foot','51366384');">------【Struts2】<em>(5)</em></span>
</label>
<label class="">
<span style="cursor:pointer" onclick="GetCategoryArticles('6228419','eson_15','foot','51366384');">● 项目实战<em>(29)</em></span>
</label>
<label class="">
<span style="cursor:pointer" onclick="GetCategoryArticles('6214186','eson_15','foot','51366384');">------【SSH网上商城】<em>(29)</em></span>
</label>
</div>
<div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
<a href="http://blog.csdn.net" style="display:none" target="_blank">http://blog.csdn.net</a>
<ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/52270046" id="foot_aritcle_52270046undefined0470181063495545" target="_blank" title="【MyBatis】MyBatis分页插件PageHelper的使用">【MyBatis】MyBatis分页插件PageHelper的使用</a><span>2016-08-21</span><label><i>阅读</i><b>4952</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51743514" id="foot_aritcle_51743514undefined5058691526682662" target="_blank" title="【SpringMVC学习10】SpringMVC对RESTfull的支持">【SpringMVC学习10】SpringMVC对RESTfull的支持</a><span>2016-06-26</span><label><i>阅读</i><b>6414</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51736495" id="foot_aritcle_51736495undefined6858319986819688" target="_blank" title="【SpringMVC学习08】SpringMVC中实现文件上传">【SpringMVC学习08】SpringMVC中实现文件上传</a><span>2016-06-24</span><label><i>阅读</i><b>6064</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51725470" id="foot_aritcle_51725470undefined5983996170976444" target="_blank" title="【SpringMVC学习06】SpringMVC中的数据校验">【SpringMVC学习06】SpringMVC中的数据校验</a><span>2016-06-22</span><label><i>阅读</i><b>11339</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51700519" id="foot_aritcle_51700519undefined6075530957100506" target="_blank" title="【SpringMVC学习04】Spring、MyBatis和SpringMVC的整合">【SpringMVC学习04】Spring、MyBatis和SpringMVC的整合</a><span>2016-06-20</span><label><i>阅读</i><b>10295</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51694684" id="foot_aritcle_51694684undefined7738787089286265" target="_blank" title="【MyBatis学习15】MyBatis的逆向工程生成代码">【MyBatis学习15】MyBatis的逆向工程生成代码</a><span>2016-06-17</span><label><i>阅读</i><b>6096</b></label></li> </ul>
<ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51749880" id="foot_aritcle_51749880undefined5883359728929796" target="_blank" title="【SpringMVC学习11】SpringMVC中的拦截器">【SpringMVC学习11】SpringMVC中的拦截器</a><span>2016-06-28</span><label><i>阅读</i><b>6498</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51742864" id="foot_aritcle_51742864undefined40309340261560367" target="_blank" title="【SpringMVC学习09】SpringMVC与前台的json数据交互">【SpringMVC学习09】SpringMVC与前台的json数据交互</a><span>2016-06-25</span><label><i>阅读</i><b>7613</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51731567" id="foot_aritcle_51731567undefined4715729002159086" target="_blank" title="【SpringMVC学习07】SpringMVC中的统一异常处理">【SpringMVC学习07】SpringMVC中的统一异常处理</a><span>2016-06-23</span><label><i>阅读</i><b>13709</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51718633" id="foot_aritcle_51718633undefined9325877791308825" target="_blank" title="【SpringMVC学习05】SpringMVC中的参数绑定总结">【SpringMVC学习05】SpringMVC中的参数绑定总结</a><span>2016-06-21</span><label><i>阅读</i><b>10912</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51699103" id="foot_aritcle_51699103undefined5090026526294114" target="_blank" title="【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结">【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结</a><span>2016-06-19</span><label><i>阅读</i><b>7781</b></label></li> </ul>
<a href="http://blog.csdn.net/eson_15/article/category/6228418" class="MoreArticle">更多文章</a></div>
</div>
</div>
<script type="text/javascript">
$(function () {
GetCategoryArticles('6228418', 'eson_15','foot','51366384');
});
</script>