//The MIT License // //Copyright (c) 2009 nodchip // //Permission is hereby granted, free of charge, to any person obtaining a copy //of this software and associated documentation files (the "Software"), to deal //in the Software without restriction, including without limitation the rights //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //copies of the Software, and to permit persons to whom the Software is //furnished to do so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included in //all copies or substantial portions of the Software. // //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN //THE SOFTWARE. package tv.dyndns.kishibe.qmaclone.server; import java.awt.Canvas; import java.awt.Image; import java.awt.image.AreaAveragingScaleFilter; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.servlet.Servlet; 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.FileItemFactory; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import tv.dyndns.kishibe.qmaclone.client.constant.Constant; import tv.dyndns.kishibe.qmaclone.client.packet.PacketUserData; import tv.dyndns.kishibe.qmaclone.server.database.Database; import tv.dyndns.kishibe.qmaclone.server.database.DatabaseException; import com.google.inject.Inject; @SuppressWarnings("serial") public class IconUploadServletStub extends HttpServlet implements Servlet { private static final Logger logger = Logger.getLogger(IconUploadServletStub.class.getName()); private final Database database; @Inject public IconUploadServletStub(Database database) { this.database = database; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try (InputStream inputStream = request.getInputStream(); OutputStream outputStream = response.getOutputStream()) { processRequest(request, response); } } private void processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { logger.log(Level.INFO, request.toString()); FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(64L * 1024L); List<FileItem> items = null; try { List<FileItem> temp = upload.parseRequest(request); items = temp; } catch (FileUploadException e) { writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_PARSE_REQUEST); return; } String userCode = null; BufferedImage inputImage = null; long originalFileSize = 0; for (FileItem item : items) { if (item.isFormField()) { String key = item.getFieldName(); String value = item.getString(); if (key.equals(Constant.FORM_NAME_USER_CODE)) { userCode = value; } continue; } // 画像確認 originalFileSize = item.getSize(); try (InputStream inputStream = item.getInputStream()) { inputImage = ImageIO.read(inputStream); } catch (IOException e) { writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_DETECT_IMAGE_FILE_TYPE); return; } if (inputImage == null) { writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_DETECT_IMAGE_FILE_TYPE); return; } } if (userCode == null || inputImage == null) { writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_REQUEST_FORMAT_ERROR); return; } String extension = "jpg"; String fileTitle = Utility.createFileName(); String fileName = fileTitle + "." + extension; // リサイズ // TODO(nodchip): ユーティリティクラスへ抽出 int size = Constant.ICON_SIZE * 2; ImageFilter imageFilter = new AreaAveragingScaleFilter(size, size); Image middleImage = new Canvas().createImage(new FilteredImageSource(inputImage.getSource(), imageFilter)); BufferedImage outputImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB); outputImage.createGraphics().drawImage(middleImage, 0, 0, size, size, null); // ファイル書き込み new File(Constant.ICON_FOLDER_PATH).mkdirs(); File outputFile = new File(Constant.ICON_FOLDER_PATH, fileName); ImageIO.write(outputImage, "jpg", outputFile); logger.log(Level.INFO, String.format("%d bytes -> %d bytes (%s)", originalFileSize, outputFile.length(), outputFile.getPath())); // データベース書き込み int userId = Integer.parseInt(userCode); PacketUserData userData; try { userData = database.getUserData(userId); } catch (DatabaseException e) { logger.log(Level.WARNING, "ユーザーデータの読み込みに失敗しました", e); throw new ServletException(e); } File oldFile = new File(Constant.ICON_FOLDER_PATH, userData.imageFileName); if (oldFile.isFile() && !oldFile.getName().equals(Constant.ICON_NO_IMAGE)) { oldFile.delete(); } userData.imageFileName = fileName; try { database.setUserData(userData); } catch (DatabaseException e) { logger.log(Level.WARNING, "ユーザーデータの保存に失敗しました", e); throw new ServletException(e); } // レスポンス書き込み writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_OK); } private void writeResponse(HttpServletResponse response, String message) throws IOException { response.setContentType("text/plain"); response.getOutputStream().write(message.getBytes()); } }