검색결과 리스트
글
JSP 이미지 파일 리사이즈
이미지를 받는데 파일 용량이 커서 서버 용량에 부담을 줘서 알게된 방법이다.
-
<form name="frmSearch" method="post" action="db처리할 경로" enctype="multipart/form-data" target="PopFrame" onSubmit="return opningReception()">
<input type="file" name ="agent1" >
<input type="submit" name="sbm" value=" 등 록 " class="btn1">
</form>
//하나의 form이 있다고 가정합니다.
//등록 버튼을 누를 경우에 multipart로 파일을 서버에 올리게 됩니다.
//아래는 back단 작업입니다.
<%@ page import="java.util.*, java.net.*, spacenet.func, java.io.*"%>
<%@ page import="spacenet.util.MultipartRequest" %>
<%@ page import="java.awt.geom.AffineTransform"%>
<%@ page import="java.awt.image.BufferedImage"%>
<%@ page import="java.awt.image.AffineTransformOp"%>
<%@ page import="javax.imageio.ImageIO"%>
<%!
protected void ThumbNail(File image, String convFile) throws Exception
{
String destFileName = convFile;
try
{
int wSize = 0, hSize=0;
BufferedImage bufferedImage = ImageIO.read(image);
int imageWidth = bufferedImage.getWidth();
int imageHeight = bufferedImage.getHeight();
int componentWidth = 0;
int componentHeight = 0;
if(imageWidth >= imageHeight )
{
wSize = 700;
if(imageWidth > wSize )
{
componentWidth = wSize;
componentHeight = (int)Math.round(imageHeight * (wSize / componentWidth));
}
else
{
componentWidth = imageWidth;
componentHeight = imageHeight;
}
}
else
{
hSize = 700;
if(imageHeight > hSize )
{
componentHeight = hSize;
componentWidth = (int)Math.round(imageWidth * (hSize / componentHeight));
}
else
{
componentWidth = imageWidth;
componentHeight = imageHeight;
}
}
double scale = -1;
if(true)
{
double heightScale = ((double)componentWidth) / ((double)imageWidth);
int scaledHeight = (int)(((double)imageHeight) * heightScale);
double widthScale = ((double)componentHeight) / ((double)imageHeight);
int scaledWidth = (int)(((double)imageWidth) * widthScale);
if ( scaledWidth <= componentWidth ) scale = widthScale;
else scale = heightScale;
}
// Now create thumbnail
AffineTransform affineTransform = AffineTransform.getScaleInstance(scale,scale);
AffineTransformOp affineTransformOp = new AffineTransformOp(affineTransform, null);
BufferedImage scaledBufferedImage = affineTransformOp.filter(bufferedImage,null);
// Now do fix to get rid of silly spurious line
int scaledWidth = scaledBufferedImage.getWidth();
int scaledHeight = scaledBufferedImage.getHeight();
int expectedWidth = (int)(imageWidth * scale);
int expectedHeight = (int)(imageHeight * scale);
if ( scaledWidth > expectedWidth || scaledHeight > expectedHeight )
{
scaledBufferedImage = scaledBufferedImage.getSubimage(0,0,expectedWidth,expectedHeight);
}
ImageIO.write(scaledBufferedImage,"PNG", new File(destFileName));
}
catch (Exception ee)
{
throw ee;
}
}
%>
int sizeLimite = 100 * 1024 * 1024; // 업로드 된 파일 용량이 100M로 지정
MultipartRequest Mrequest = new MultipartRequest(request, "/data/File/", sizeLimite);
//데이터를 저장할 경로("/data/File/")와 용량 리미트를 정해 줍니다.
//제가 작업할때 sizeLimite 를 지정 안해주면 10M 로 되더군요.
String agent1 = UTF_8(func.NVL(Mrequest.getFilesystemName("agent1"))); //이미지
File reFile_1 =null;
reFile_1 = Mrequest.getFile("agent1");
ThumbNail(reFile_1, dir+Mrequest.getFilesystemName("agent1"));
//이런식으로 ThumbNail 호출 하면 이미지 크기가 정해진대로 조정 되면서 용량이 줄더군요.
//참고로
//파일 이름을 바꾸려면
reFile_1.renameTo( new File(dir + File.separator + 바꿀이름) );
//이런식으로 해주면 됩니다.
//아래는 MultipartRequest의 자바 소스 입니다.
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.lang.SecurityException;
import org.apache.log4j.Category;
public class MultipartRequest extends HttpServlet {
private static final int DEFAULT_MAX_POST_SIZE = 1024 * 10240; // 10 Meg
private static final String NO_FILE = "unknown";
private static int FILE_NO = 1;
private static Category logs = Category.getInstance(MultipartRequest.class.getName());
private HttpServletRequest req;
//private HttpServletResponse res;
private File dir;
private int maxSize;
private Hashtable parameters = new Hashtable(); // name - Vector of values
private Hashtable files = new Hashtable(); // name - UploadedFile
//Hashtable 클래스
//키(key)와 값(value)의 쌍으로 이루어진 요소(element)를 저장하는 자료구조
//생성자 Hashtable() Hashtable(int size) Hashtable(int size, float fillRatio) size :
//생성될 Hashtable 객체의 크기 fillRatio : 0.0-1.0사이의 값으로 load factor로 사용.
//즉 해쉬 테이블의 크기보다 저장될 요소가 많을 경우 fillRatio로 지정된 값이 키값에 곱해져서 사용되게 된다
public MultipartRequest(HttpServletRequest request,
String saveDirectory) throws IOException {
this(request, saveDirectory, DEFAULT_MAX_POST_SIZE);
}
//maxPostSize 는 파일크기를 미리설정 해놓는다.
public MultipartRequest(HttpServletRequest request,
String saveDirectory,
int maxPostSize) throws IOException {
// Sanity check values
FILE_NO = 1;
if (request == null)
throw new IllegalArgumentException("request cannot be null");
if (saveDirectory == null)
throw new IllegalArgumentException("saveDirectory cannot be null");
if (maxPostSize <= 0) {
throw new IllegalArgumentException("maxPostSize must be positive");
}
// Save the request, dir, and max size
req = request;
dir = new File(saveDirectory); //저장할 디렉토리 경로 c:/Program Files/Apache Group/Apache/htdocs/uploadfiles
maxSize = maxPostSize;
// Check saveDirectory is truly a directory
if (!dir.isDirectory()) //isDirectory() 는 저장할 디렉토리가 있다면 true 없다면 false 반환
throw new IllegalArgumentException("Not a directory: " + saveDirectory);
// Check saveDirectory is writable
if (!dir.canWrite()) // canWrite()는 이 디렉토리가 쓰기 기능이 가능한지 조사 한다.
throw new IllegalArgumentException("Not writable: " + saveDirectory);
// Now parse the request saving data to "parameters" and "files";
// write the file contents to the saveDirectory
//try{
readRequest();
//}catch(IOException e){
//res.sendRedirect("http://211.235.250.230/file_error.jsp");
//}
}
public MultipartRequest(ServletRequest request,
String saveDirectory) throws IOException {
this((HttpServletRequest)request, saveDirectory);
}
public MultipartRequest(ServletRequest request,
String saveDirectory,
int maxPostSize) throws IOException {
this((HttpServletRequest)request, saveDirectory, maxPostSize);
}
public Enumeration getParameterNames() {
return parameters.keys();
}
public Enumeration getFileNames() {
return files.keys();
}
public int getFileSize(){ //파일 크기
return this.req.getContentLength();
}
public String getParameter(String name) {
try {
Vector values = (Vector)parameters.get(name);
if (values == null || values.size() == 0) {
return null;
}
String value = (String)values.elementAt(values.size() - 1);
return value;
}
catch (Exception e) {
return null;
}
}
public String getRemoteAddr(){
return this.req.getRemoteAddr();
}
public String[] getParameterValues(String name) {
try {
Vector values = (Vector)parameters.get(name);
if (values == null || values.size() == 0) {
return null;
}
String[] valuesArray = new String[values.size()];
values.copyInto(valuesArray);
return valuesArray;
}
catch (Exception e) {
return null;
}
}
public String getFilesystemName(String name) {
try {
UploadedFile file = (UploadedFile)files.get(name);
return file.getFilesystemName(); // may be null
}
catch (Exception e) {
return null;
}
}
public String getContentType(String name) {
try {
UploadedFile file = (UploadedFile)files.get(name);
return file.getContentType(); // may be null
}
catch (Exception e) {
return null;
}
}
public File getFile(String name) {
try {
UploadedFile file = (UploadedFile)files.get(name);
return file.getFile(); // may be null
}
catch (Exception e) {
return null;
}
}
String getFileExtention(String fileName){
String extension = "";
int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
if (i > p) {
extension = fileName.substring(i+1);
}
return extension;
}
String getFileNameWithoutExtention(String fileName){
String ret = "";
int i = fileName.lastIndexOf('.');
if(i>=0)
ret = fileName.substring(0,i);
return ret;
}
protected void readRequest() throws IOException {
// Check the content type to make sure it's "multipart/form-data"
// Access header directly to work around WebSphere 2.x oddity
String type = req.getHeader("Content-Type");
if (type == null ||
!type.toLowerCase().startsWith("multipart/form-data")) {
throw new IOException("Posted content type isn't multipart/form-data");
}
// Check the content length to prevent denial of service attacks
int length = req.getContentLength();
if (length > maxSize) {
throw new IOException("Posted content length of " + length +
" exceeds limit of " + maxSize);
}
// Get the boundary string; it's included in the content type.
// Should look something like "------------------------12012133613061"
String boundary = extractBoundary(type);
if (boundary == null) {
throw new IOException("Separation boundary was not specified");
}
// Construct the special input stream we'll read from
MultipartInputStreamHandler in =
new MultipartInputStreamHandler(req.getInputStream(), length);
// Read the first line, should be the first boundary
String line = in.readLine();
if (line == null) {
throw new IOException("Corrupt form data: premature ending");
}
// Verify that the line is the boundary
if (!line.startsWith(boundary)) {
throw new IOException("Corrupt form data: no leading boundary");
}
// Now that we're just beyond the first boundary, loop over each part
boolean done = false;
while (!done) {
done = readNextPart(in, boundary);
}
}
protected boolean readNextPart(MultipartInputStreamHandler in,
String boundary) throws IOException {
// Read the first line, should look like this:
// content-disposition: form-data; name="field1"; filename="file1.txt"
String line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
}
else if (line.length() == 0) {
// IE4 on Mac sends an empty line at the end; treat that as the end.
// Thanks to Daniel Lemire and Henri Tourigny for this fix.
return true;
}
// Parse the content-disposition line
String[] dispInfo = extractDispositionInfo(line);
String disposition = dispInfo[0];
String name = dispInfo[1];
String filename = dispInfo[2];
// Now onto the next line. This will either be empty
// or contain a Content-Type and then an empty line.
line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
}
// Get the content type, or null if none specified
String contentType = extractContentType(line);
if (contentType != null) {
// Eat the empty line
line = in.readLine();
if (line == null || line.length() > 0) { // line should be empty
throw new
IOException("Malformed line after content type: " + line);
}
}
else {
// Assume a default content type
contentType = "application/octet-stream";
}
// Now, finally, we read the content (end after reading the boundary)
if (filename == null) {
// This is a parameter, add it to the vector of values
String value = readParameter(in, boundary);
if (value.equals("")) {
value = null; // treat empty strings like nulls
}
Vector existingValues = (Vector)parameters.get(name);
if (existingValues == null) {
existingValues = new Vector();
parameters.put(name, existingValues);
}
existingValues.addElement(value);
}
else {
// This is a file
DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
// Get the date today using Calendar object.
Date today = Calendar.getInstance().getTime();
String currentTime = df.format(today);
filename = getFileNameWithoutExtention(filename)+"_"+currentTime+"_"+FILE_NO+"."+getFileExtention(filename);
FILE_NO++;
System.out.println("para name:"+name + " original file name:"+filename);
readAndSaveFile(in, boundary, filename);
if (filename.equals(NO_FILE)) {
files.put(name, new UploadedFile(null, null, null));
}
else {
files.put(name,
new UploadedFile(dir.toString(), toKo(filename), contentType));
}
}
return false; // there's more to read
}
/**
* A utility method that reads a single part of the multipart request
* that represents a parameter. A subclass can override this method
* for a better optimized or differently behaved implementation.
*
* @param in the stream from which to read the parameter information
* @param boundary the boundary signifying the end of this part
* @return the parameter value
* @exception IOException if there's a problem reading or parsing the
* request
*/
protected String readParameter(MultipartInputStreamHandler in,
String boundary) throws IOException {
StringBuffer sbuf = new StringBuffer();
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith(boundary)) break;
sbuf.append(line + "\r\n"); // add the \r\n in case there are many lines
}
if (sbuf.length() == 0) {
return null; // nothing read
}
sbuf.setLength(sbuf.length() - 2); // cut off the last line's \r\n
return sbuf.toString(); // no URL decoding needed
}
/**
* A utility method that reads a single part of the multipart request
* that represents a file, and saves the file to the given directory.
* A subclass can override this method for a better optimized or
* differently behaved implementation.
*
* @param in the stream from which to read the file
* @param boundary the boundary signifying the end of this part
* @param dir the directory in which to save the uploaded file
* @param filename the name under which to save the uploaded file
* @exception IOException if there's a problem reading or parsing the
* request
*/
protected void readAndSaveFile(MultipartInputStreamHandler in,
String boundary,
String filename) throws IOException {
OutputStream os = null;
// A filename of NO_FILE means no file was sent, so just read to the
// next boundary and ignore the empty contents
if (filename.equals(NO_FILE)) {
os = new ByteArrayOutputStream(); // write to nowhere
}
// A real file's contents are written to disk
else {
File f = new File(dir + File.separator + toKo(filename));
////////추가 된 부분 ////////////////////////////////////////////////////////////////////////////////////
/* file anme 증가부분 막았음 by jekim
int i = 1;
int indexDot = toKo(filename).indexOf('.');
String strFileHead = toKo(filename);
String strFileExt = "";
while(f.isFile()){
if (indexDot != -1){
strFileHead = toKo(filename).substring(0, indexDot);
strFileExt = toKo(filename).substring(indexDot);
}
f = new File(dir + File.separator + strFileHead + i + strFileExt);
i++;
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////
os = new FileOutputStream(f);
}
BufferedOutputStream out = new BufferedOutputStream(os, 8 * 1024); // 8K
byte[] bbuf = new byte[100 * 1024]; // 100K
int result;
String line;
// ServletInputStream.readLine() has the annoying habit of
// adding a \r\n to the end of the last line.
// Since we want a byte-for-byte transfer, we have to cut those chars.
boolean rnflag = false;
while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
// Check for boundary
if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') { // quick pre-check
line = new String(bbuf, 0, result, "ISO-8859-1");
if (line.startsWith(boundary)) break;
}
// Are we supposed to write \r\n for the last iteration?
if (rnflag) {
out.write('\r'); out.write('\n');
rnflag = false;
}
// Write the buffer, postpone any ending \r\n
if (result >= 2 &&
bbuf[result - 2] == '\r' &&
bbuf[result - 1] == '\n') {
out.write(bbuf, 0, result - 2); // skip the last 2 chars
rnflag = true; // make a note to write them on the next iteration
}
else {
out.write(bbuf, 0, result);
}
}
out.flush();
out.close();
os.close();
}
//한글 입력을 위한 메소드를 구현합니다.
public static String toKo(String str){
try{
if(str == null) return null;
return new String (str.getBytes("8859_1"),"KSC5601");
}//try 닫기
catch(UnsupportedEncodingException ex){
ex.printStackTrace();
return "";
}//chatch 닫기
}//toKo닫기
// Extracts and returns the boundary token from a line.
//
private String extractBoundary(String line) {
// Use lastIndexOf() because IE 4.01 on Win98 has been known to send the
// "boundary=" string multiple times. Thanks to David Wall for this fix.
int index = line.lastIndexOf("boundary=");
if (index == -1) {
return null;
}
String boundary = line.substring(index + 9); // 9 for "boundary="
// The real boundary is always preceeded by an extra "--"
boundary = "--" + boundary;
return boundary;
}
// Extracts and returns disposition info from a line, as a String array
// with elements: disposition, name, filename. Throws an IOException
// if the line is malformatted.
//
private String[] extractDispositionInfo(String line) throws IOException {
//logs.debug("MultipartRequest line : "+line);
// Return the line's data as an array: disposition, name, filename
String[] retval = new String[3];
// Convert the line to a lowercase string without the ending \r\n
// Keep the original line for error messages and for variable names.
String origline = line;
line = origline.toLowerCase();
// Get the content disposition, should be "form-data"
int start = line.indexOf("content-disposition: ");
int end = line.indexOf(";");
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String disposition = line.substring(start + 21, end);
if (!disposition.equals("form-data")) {
throw new IOException("Invalid content disposition: " + disposition);
}
// Get the field name
start = line.indexOf("name=\"", end); // start at last semicolon
end = line.indexOf("\"", start + 7); // skip name=\"
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String name = origline.substring(start + 6, end);
// Get the filename, if given
String filename = null;
start = line.indexOf("filename=\"", end + 2); // start after name
end = line.indexOf("\"", start + 10); // skip filename=\"
if (start != -1 && end != -1) { // note the !=
filename = origline.substring(start + 10, end);
// The filename may contain a full path. Cut to just the filename.
int slash =
Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
if (slash > -1) {
filename = filename.substring(slash + 1); // past last slash
}
if (filename.equals("")) filename = NO_FILE; // sanity check
}
// Return a String array: disposition, name, filename
retval[0] = disposition;
retval[1] = name;
retval[2] = filename;
return retval;
}
// Extracts and returns the content type from a line, or null if the
// line was empty. Throws an IOException if the line is malformatted.
//
private String extractContentType(String line) throws IOException {
String contentType = null;
// Convert the line to a lowercase string
String origline = line;
line = origline.toLowerCase();
// Get the content type, if any
if (line.startsWith("content-type")) {
int start = line.indexOf(" ");
if (start == -1) {
throw new IOException("Content type corrupt: " + origline);
}
contentType = line.substring(start + 1);
}
else if (line.length() != 0) { // no content type, so should be empty
throw new IOException("Malformed line after disposition: " + origline);
}
return contentType;
}
}
// A class to hold information about an uploaded file.
//업로드된 파일에 대한 정보를 잡는 클래스.
class UploadedFile {
private String dir;
private String filename;
private String type;
UploadedFile(String dir, String filename, String type) {
this.dir = dir;
this.filename = filename;
this.type = type;
}
public String getContentType() {
return type;
}
public String getFilesystemName() {
return filename;
}
public File getFile() {
if (dir == null || filename == null) {
return null;
}
else {
return new File(dir + File.separator + filename);
}
}
}
// A class to aid in reading multipart/form-data from a ServletInputStream.
// It keeps track of how many bytes have been read and detects when the
// Content-Length limit has been reached. This is necessary since some
// servlet engines are slow to notice the end of stream.
//
// Mac users: The Mac doesn't like class names which exceed 32 characters
// (including the ".class") so while this class is usable from a JAR
// anywhere, it won't compile on a Mac.
//
class MultipartInputStreamHandler {
ServletInputStream in;
int totalExpected;
int totalRead = 0;
byte[] buf = new byte[8 * 1024];
public MultipartInputStreamHandler(ServletInputStream in,
int totalExpected) {
this.in = in;
this.totalExpected = totalExpected;
}
// Reads the next line of input. Returns null to indicate the end
// of stream.
//
public String readLine() throws IOException {
StringBuffer sbuf = new StringBuffer();
int result;
String line;
do {
result = this.readLine(buf, 0, buf.length); // this.readLine() does +=
if (result != -1) {
sbuf.append(new String(buf, 0, result, "ISO-8859-1"));
}
} while (result == buf.length); // loop only if the buffer was filled
if (sbuf.length() == 0) {
return null; // nothing read, must be at the end of stream
}
sbuf.setLength(sbuf.length() - 2); // cut off the trailing \r\n
return sbuf.toString();
}
// A pass-through to ServletInputStream.readLine() that keeps track
// of how many bytes have been read and stops reading when the
// Content-Length limit has been reached.
//
public int readLine(byte b[], int off, int len) throws IOException {
if (totalRead >= totalExpected) {
return -1;
}
else {
int result = in.readLine(b, off, len);
if (result > 0) {
totalRead += result;
}
return result;
}
}
}
'개발 > 코딩' 카테고리의 다른 글
[자바스크립트] 숫자만 입력 (0) | 2017.11.13 |
---|---|
특정 화면 위치로 자동 스크롤 (0) | 2017.06.05 |
아이디 입력시 특수문자 확인 (0) | 2017.04.20 |
JSP 드래그, 오른쪽 클릭 막기 (0) | 2017.01.25 |
메뉴 클릭하면 이미지 변경 (0) | 2016.03.21 |