package com.skyline.wo.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.imagine.core.ImageInfo;
import net.imagine.core.ImageOperations;
import net.imagine.core.ResultState;
import net.imagine.core.engine.ImageEngine;
import net.imagine.provider.skyline.ImageCropResult;
import net.imagine.provider.skyline.ImageCutter;
import net.imagine.provider.skyline.ImageResizeResult;
import net.imagine.provider.skyline.MultipartImageResizeTask;
import net.imagine.provider.skyline.SkylineImageCropTask;
import net.imagine.provider.skyline.SkylineImagineUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.skyline.common.util.Constant;
import com.skyline.common.util.WebHelper;
import com.skyline.spot.model.Spot;
import com.skyline.spot.service.SpotService;
import com.skyline.user.model.User;
import com.skyline.user.service.PersonalInfoService;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.AlbumService;
/**
* SWF批量文件上传用到的上传类,不能使用SpringMVC,会返回406<br/>
* 必须由Spring来管理,且beanId必须为uploadAction<br/>
* 具体请参见imagine框架
*
* @author wuqh
* */
@Component("uploadAction")
public class UploadController {
private static final Log LOGGER = LogFactory.getLog(UploadController.class);
private static final String URL_SUFFIX = "html";
private ObjectMapper objectMapper = new ObjectMapper();
@Value("${imagine.localStorePath}")
private String basePath;
@Value("${album.uploadphoto.filesize}")
private long maxSizePerFile;
@Autowired
private ImageEngine imagine;
@Value("${imagine.baseSize1},${imagine.baseSize2}")
private int[] baseSizes;
@Autowired
private ImageOperations operations;
@Autowired
private ImageCutter crop;
@Value("${imagine.protraitSize}")
private int portraitSize;
@Autowired
private PersonalInfoService personalInfoService;
@Autowired
private SpotService spotService;
@Autowired
private AlbumService albumService;
public void batchUpload(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String albumIdStr = request.getParameter("albumid");
String userIdStr = request.getParameter("userid");
if (!"POST".equals(request.getMethod())) {
response.sendRedirect(buildRecirectPath(request, "/album/bupload/" + albumIdStr, null));
}
long userId = Long.parseLong(userIdStr);
long albumId = Long.parseLong(albumIdStr);
MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
// 本地存放路径生成
if (file == null) {
Map<String, Object> jsonMap = resultToJsonMap(ResultState.NO_FILE_EXIST, null);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
File localFile = generateLocalFile(userId, albumId, file.getOriginalFilename());
// 保存文件
ResultState result = storeFileInLocal(localFile, file);
// 输出结果
Map<String, Object> jsonMap = resultToJsonMap(result, localFile.getAbsolutePath());
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
}
public void delUploaded(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String filePath = request.getParameter("photo_file");
if ("GET".equals(request.getMethod())) {
filePath = URLDecoder.decode(filePath, "UTF-8");
}
Map<String, Object> jsonMap = null;
OutputStream out = response.getOutputStream();
File file = null;
if(StringUtils.hasLength(filePath)) {
file = new File(filePath);
}
if (file == null || !file.exists()) {
jsonMap = toJsonMap(false, "文件不存在");
outputJsonResult(out, jsonMap);
return;
}
try {
FileUtils.forceDelete(file);
} catch (IOException e) {
LOGGER.warn("删除图片文件失败", e);
jsonMap = toJsonMap(false, "删除失败");
outputJsonResult(out, jsonMap);
return;
}
jsonMap = toJsonMap(true, "成功");
outputJsonResult(out, jsonMap);
}
/**
* 此功能必须和应用位于同一个session中
*
* */
public void uploadPortrait(HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (!"POST".equals(request.getMethod())) {
response.sendRedirect(buildRecirectPath(request, "/user/photoupload", null));
}
User user = (User) WebHelper.getSessionAttribute(request, Constant.SESSION_USER);
Map<String, Object> jsonMap = null;
if (user == null) {
jsonMap = toJsonMap(false, "修改照片描述必须登录");
jsonMap.put("logined", Boolean.FALSE);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
try {
long userId = user.getId();
Album album = albumService.getUserPortraitAlbum(userId);
long albumId = album.getId();
MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
if (file == null) {
jsonMap = resultToJsonMap(ResultState.NO_FILE_EXIST, null);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
MultipartImageResizeTask resizeTask = new MultipartImageResizeTask(file, baseSizes,
null, false);
resizeTask.setAlbumId(albumId);
resizeTask.setUserId(userId);
resizeTask.setSupportMulitFrame(false);
ImageResizeResult processResult = imagine.processSingleImage(basePath, resizeTask);
ResultState resultState = processResult.getResultState();
if (resultState != ResultState.SUCCESS) {
jsonMap = resultToJsonMap(resultState, null);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
Photo portrait = albumService.createPortraitPhoto(user, album, processResult);
String smallFile = portrait.getSmallFile();
String ext = portrait.getExt();
String remoteFileKey = smallFile + '.' + ext;
SkylineImageCropTask cropTask = new SkylineImageCropTask(remoteFileKey, portraitSize);
cropTask.setAlbumId(albumId);
cropTask.setUserId(userId);
ImageCropResult cropResult = crop.processImage(basePath, cropTask);
String portraitFile = cropResult.getFileKey();
personalInfoService.changeUserPortrait(userId, portraitFile);
user.setPortrait(portraitFile);
WebHelper.setSessionAttribute(request, Constant.SESSION_USER, user);
jsonMap = toJsonMap(true, "上传头像成功");
jsonMap.put("fileKey", remoteFileKey);
} catch (Exception e) {
LOGGER.warn("上传头像失败", e);
jsonMap = toJsonMap(false, "上传头像失败,请稍候重试");
}
jsonMap.put("logined", Boolean.TRUE);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
}
public void uploadSpotPortrait(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String spotIdStr = request.getParameter("spotId");
String albumIdStr = request.getParameter("albumId");
if (!"POST".equals(request.getMethod())) {
response.sendRedirect(buildRecirectPath(request, "/spot/spotId/editPortrait", null));
}
long spotId = Long.parseLong(spotIdStr);
long albumId = Long.parseLong(albumIdStr);
User user = (User) WebHelper.getSessionAttribute(request, Constant.SESSION_USER);
Map<String, Object> jsonMap = null;
if (user == null) {
jsonMap = toJsonMap(false, "修改照片描述必须登录");
jsonMap.put("logined", Boolean.FALSE);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
try {
Album album =albumService.getAlbumById(albumId);
Spot spot=spotService.getSpot(spotId);
MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
if (file == null) {
jsonMap = resultToJsonMap(ResultState.NO_FILE_EXIST, null);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
MultipartImageResizeTask resizeTask = new MultipartImageResizeTask(file, baseSizes,
null, false);
resizeTask.setAlbumId(albumId);
resizeTask.setUserId(spotId);
resizeTask.setSupportMulitFrame(false);
ImageResizeResult processResult = imagine.processSingleImage(basePath, resizeTask);
ResultState resultState = processResult.getResultState();
if (resultState != ResultState.SUCCESS) {
jsonMap = resultToJsonMap(resultState, null);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
return;
}
/**
* 构造一个spot的user
*/
User tempuser=new User();
tempuser.setId(spot.getId());
tempuser.setNickname(spot.getName());
tempuser.setPortrait(spot.getPortrait());
Photo portrait = albumService.createPortraitPhoto(tempuser, album, processResult);
String smallFile = portrait.getSmallFile();
String ext = portrait.getExt();
String remoteFileKey = smallFile + '.' + ext;
SkylineImageCropTask cropTask = new SkylineImageCropTask(remoteFileKey, portraitSize);
cropTask.setAlbumId(albumId);
cropTask.setUserId(spotId);
ImageCropResult cropResult = crop.processImage(basePath, cropTask);
String portraitFile = cropResult.getFileKey();
spotService.updateSpotPortrait(spotId, portraitFile);
spot.setPortrait(portraitFile);
//WebHelper.setSessionAttribute(request, Constant.SESSION_USER, user);
jsonMap = toJsonMap(true, "上传头像成功");
jsonMap.put("fileKey", remoteFileKey);
} catch (Exception e) {
LOGGER.warn("上传头像失败", e);
jsonMap = toJsonMap(false, "上传头像失败,请稍候重试");
}
jsonMap.put("logined", Boolean.TRUE);
OutputStream out = response.getOutputStream();
outputJsonResult(out, jsonMap);
}
private void outputJsonResult(OutputStream out, Map<String, Object> jsonMap)
throws JsonGenerationException, JsonMappingException, IOException {
// JsonEncoding encoding =
// getEncoding(outputMessage.getHeaders().getContentType());
JsonGenerator jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(out,
JsonEncoding.UTF8);
objectMapper.writeValue(jsonGenerator, jsonMap);
}
private Map<String, Object> resultToJsonMap(ResultState result, String filePath) {
switch (result) {
case SUCCESS:
return toJsonMap(true, "成功", filePath);
case FILE_TO_LARGE:
return toJsonMap(false, "文件过大", filePath);
case STORE_FAILED:
return toJsonMap(false, "保存失败", filePath);
case NOT_IMAGE:
return toJsonMap(false, "不是图片", filePath);
case EXCEED_MAX_CAPACITY:
return toJsonMap(false, "超过容量", filePath);
case UNKOWN_FAILED:
return toJsonMap(false, "未知错误", filePath);
default:
return toJsonMap(false, "未知错误", filePath);
}
}
private Map<String, Object> toJsonMap(boolean isSuccess, String errMsg) {
return toJsonMap(isSuccess, errMsg, null);
}
// private Map<String, Object> toJsonMap(boolean isSuccess, String errMsg,
// Map<String, Object> jsonMap) {
// return toJsonMap(isSuccess, errMsg, null, jsonMap);
// }
private Map<String, Object> toJsonMap(boolean isSuccess, String errMsg, String filePath) {
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("success", Boolean.valueOf(isSuccess));
jsonMap.put("errmsg", errMsg);
if (isSuccess && StringUtils.hasLength(filePath)) {
jsonMap.put("file", filePath);
}
return jsonMap;
}
// private Map<String, Object> toJsonMap(boolean isSuccess, String errMsg,
// String filePath,
// Map<String, Object> jsonMap) {
// if (jsonMap == null) {
// jsonMap = new HashMap<String, Object>();
// }
// jsonMap.put("success", Boolean.valueOf(isSuccess));
// jsonMap.put("errmsg", errMsg);
// if (isSuccess && StringUtils.hasLength(filePath)) {
// jsonMap.put("file", filePath);
// }
// return jsonMap;
// }
private File generateLocalFile(long userId, long albumId, String oriFilename) {
String baseName = FilenameUtils.getBaseName(oriFilename);
String ext = FilenameUtils.getExtension(oriFilename);
String filePath = SkylineImagineUtils.generateFilePath(basePath, userId, albumId,
oriFilename);
File localFile = new File(filePath);
int num = 0;
while (localFile.exists()) {// 处理同名文件
StringBuffer tempFilename = new StringBuffer(baseName);
tempFilename.append('(').append(num).append(')').append('.').append(ext);
filePath = SkylineImagineUtils.generateFilePath(basePath, userId, albumId, tempFilename
.toString());
localFile = new File(filePath);
num++;
}
return localFile;
}
private ResultState storeFileInLocal(File localFile, MultipartFile file) {
// 判断文件是否过大
long actualSize = file.getSize();
if (actualSize > maxSizePerFile) {
return ResultState.FILE_TO_LARGE;
}
// TODO 判断是否到达容量上限
// 保存到本地文件
try {
FileOutputStream out = FileUtils.openOutputStream(localFile);
IOUtils.copy(file.getInputStream(), out);
} catch (IOException e) {
LOGGER.warn("写入本地临时文件失败", e);
return ResultState.STORE_FAILED;
}
// 判断文件是否为图片格式
ImageInfo info = operations.showImageInfo(localFile.getAbsolutePath());
if (info == null) {
try {
FileUtils.forceDelete(localFile);
} catch (IOException e) {
LOGGER.warn("删除非图片文件失败", e);
}
return ResultState.NOT_IMAGE;
}
return ResultState.SUCCESS;
}
protected String buildRecirectPath(HttpServletRequest request, String baseUrl, String paramStr) {
if (StringUtils.hasLength(paramStr)) {
return request.getContextPath() + baseUrl + URL_SUFFIX + "?" + paramStr;
} else {
return request.getContextPath() + baseUrl + URL_SUFFIX;
}
}
}