上次利用SpringMVC实现图片上传,这个是客户端将图片和其他字段一起上传然后一起处理的。(有什么坏处暂时也没有想到)总之这次的希望能够将图片存储的服务独立出来,暂时用Jersey实现一个接口(老大说按道理应该用WebService来实现,但我在这里没觉得两者有什么不同呀=。=),然后在SpringMVC中将图片提交到Jersey接口,完成存储。
这个是独立出来的图片存储项目结构
config.xml配置文件中只添加了一个绝对路径和一个虚拟路径
<config>
<root>D:\\recommend\\images\\</root>
<uriRoot>/static/image/recommendation/</uriRoot></config>
springcontext.xml配置文件中将需要注入的东西配好即可
<context:component-scan base-package="com.xxx.upload">
RestFulApplication.java中注册必要的类
public RestFulApplication(){
register(RequestContextFilter.class);
// Add additional features such as support for Multipart.
register(MultiPartFeature.class);
//load Resource
register(RecommendationPictureResource.class);
}
RecommendationPictureResource.java
private final Log logger = LogFactory.getLog(RecommendationPictureResource.class);
@Autowired
@Qualifier("pictureService")
PictureService pictureService;//存储图片的服务类
@Autowired
@Qualifier("xmlUtils")
XMLUtils xmlUtils;//封装org.apache.commons.configuration.XMLConfiguration的一个xml文件解析工具类,用来读取config.xml配置文件
@POST
@Path("/upload")
@Produces("application/json;charset=UTF-8")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String loadPic(
@FormDataParam("type") String type,
@FormDataParam("resourceId") String resourceId,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition contentDispositionHeader){
ObjectNode result = new ObjectMapper().createObjectNode();
if (type==null || resourceId == null || fileInputStream == null) {
result.put("ret_code", 10001);
result.put("ret_msg", "Illegal Parameters");
return result.toString();
}
String fileName = contentDispositionHeader.getFileName();
String path = type + File.separatorChar + resourceId + File.separatorChar + fileName;
//存储路径
String dstFilePath = xmlUtils.getString("root") + path;
pictureService.saveFile(fileInputStream, dstFilePath);
logger.info("success save pic file, dstFilePath = " + dstFilePath);
String uriPath = xmlUtils.getString("uriRoot") + path;
logger.info("uriPath = " + uriPath);
result.put("uriPath", uriPath);
return result.toString();
}
@POST
@Path("/delete")
@Produces("application/json;charset=UTF-8")
public void deletePic(@FormParam("uriPath") String uriPath){
String uriRoot = xmlUtils.getString("uriRoot");
String path = uriPath.substring(uriRoot.length());
String dstFilePath = xmlUtils.getString("root") + path;
pictureService.deleteFile(dstFilePath);
}
PictureService.java接口
public void saveFile(InputStream fileInputStream, String dstFilePath);
public void deleteFile(String dstFilePath);
PictureServiceImpl.java实现类
private final Log logger = LogFactory.getLog(PictureServiceImpl.class);
@Override
public void saveFile(InputStream fileInputStream, String dstFilePath) {
OutputStream outputStream = null;
try {
File file = new File(dstFilePath);
if(!file.exists()){
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
outputStream = new FileOutputStream(new File(
dstFilePath));
int read = 0;
byte[] bytes = new byte[1024];
outputStream = new FileOutputStream(new File(dstFilePath));
while ((read = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}else{
logger.info("the pic already exist.");
}
} catch (IOException e) {
logger.error(e);
e.printStackTrace();
}finally{
try {
fileInputStream.close();
outputStream.flush();
outputStream.close();
} catch (IOException e) {
logger.error("close stream defeat");
e.printStackTrace();
}
}
}
@Override
public void deleteFile(String dstFilePath) {
File file = new File(dstFilePath);
file.delete();
file.getParentFile().delete();
}
删除这儿还有问题,就是利用上述Jersey接口上传好的图片一直被JVM占用,导致无法删除,但我现在仍然看不破哪儿的资源没有释放~~
对应的SpringMVC中通过调用上述Jersey接口的部分代码
try {
String upload_host = "localhost:8080";
String pic_upload_uri = "http://" + upload_host + "/xxx/upload";
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();//org.apache.http.entity.mime.MultipartEntityBuilder
//type和contentId在上述接口中用来生成存储路径
entityBuilder.addTextBody("type", type);
entityBuilder.addTextBody("resourceId", contentId);
ContentType contentType = ContentType.parse(poster.getContentType());
String fileName = poster.getOriginalFilename();
entityBuilder.addBinaryBody("file", poster.getInputStream(), contentType, fileName);
HttpClient client = new HttpClient();//自己封装好的Http工具类
String loadResult = client.post(pic_upload_uri, entityBuilder.build());//上传成功的话返回json格式字符串,其中包含一个uriPath
//利用Jackson解析返回结果
JsonNode node = new ObjectMapper().readTree(loadResult);
uriPath = node.get("uriPath").asText();
logger.info("load pic success! uriPath = " + uriPath);
} catch (Exception e) {
logger.error("load pic error ! reason:" + e.getMessage());
}
以上,实现图片上传服务,基本与业务无关,但调用的方式还是不太好,url路径不好配置,直接写在了代码中,还需要改。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。