Servlet 를 이용한 파일 업로드를 간단하게 완성 시켰습니다.
사진과 글이 <Form> 태그를 통해 온 것을 파싱 할 수 있는 MultipartRequest 를 사용했습니다.
1. cos.jar 를 다운 받아 주세요.
http://www.servlets.com/cos/ 접속해서 받거나 아래 아이콘을 클릭해서 받으면 된다.
2. 파일업로드 서블릿을 생성하고 web.xml파일에 Servlet를 추가해주세요.
public class UploadServlet extends HttpServlet{
public UploadServlet() {
super();
}
public void init() throws ServletException {}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
FileManager fileManager = new FileManager(req);
}
3. FileManager class 를 만들어서 File을 관리할 수 있도록 했습니다.
MultipartRequest Class를 이용하면 File 복사가 되고, 파일명을 바꾸고 싶으면 마지막 파라미터를 주의 깊게 보시면 됩니다.
public class FileManager {
private MultipartRequest mRequest;
private int postMaxSize = 10 * 1024 * 1024; //10MB
private String encoding = "UTF-8";
public FileManager(final HttpServletRequest req) throws IOException {
mRequest = new MultipartRequest(req, 이미지저장 Path, postMaxSize, encoding, new FileAlteration());
}
}
4. 마지막 파라미터에 FileAlteration 이라는 class를 inner class 로 생성 했습니다.
class FileAlteration implements FileRenamePolicy {
@Override
public File rename(File file) {
String parentDir = file.getParent();
String fileName = file.getName();
//Get the extension if the file has one
String fileExt = "";
int i = -1;
if(( i = fileName.indexOf(".")) != -1){
fileExt = fileName.substring(i);
fileName = fileName.substring(0,i);
}
//Add the timestamp and user ID
String userId = (String) req.getSession().getAttribute("id");
newFileName = /*fileName + "_"+ */userId +("_"+( new Date( ).getTime( ) / 1000)) + fileExt;
//piece together the filename
newFileFullName = parentDir +
System.getProperty("file.separator") + newFileName;
file = new File(newFileFullName);
mimeType = new MimetypesFileTypeMap().getContentType(file);
return file;
}
}
위 소스를 보시면 쉽게 이해하실 수 있을거 같습니다.
파일작성자의 아이디와 TimeStamp 값을 이용해서 새롭게 생성될 파일의 이름을 만들어 주면 됩니다.
아래와 같이 파일이 저장됩니다.
단순한 업로드가 완성 되었습니다.
지금 하고 있는 모바일웹프로젝트에 글과+사진이 함께 전송하도록 하기 위해 한 것입니다.
파일업로드 뿐만 아니라
게시판테이블에 글 정보 삽입, 방금 삽입된 레코드의 INDEX 를 가져오는 루틴,
파일정보를 담은 테이블에 정보 삽입, 게시판 테이블 UPDATE 까지 고려해야 합니다.
'좋은 설계자 & 좋은관리자 & 좋은개발자 > Design Pattern & Modeling' 카테고리의 다른 글
Arraylist vector 공통점/ 차이점 (0) | 2014.01.02 |
---|---|
Java System.getProperty() (0) | 2013.12.23 |
Java 4대 중첩 클래스 (instance class, static class, local class, anonymous class) (0) | 2013.12.19 |
동기, 비동기(방식), blocking, non-blocking(함수) (0) | 2013.12.19 |
동기식 비동기식 차이 (0) | 2013.12.19 |
제가 알고 있는 장점은thread context switching을
제가 알고 있는 장점은
thread context switching을 줄일 수 있다는 겁니다.
프로세스 보다야 낫겠지만 쓰레드도 컨텍스트 스위칭에 오버 헤드가 있기 때문에 이걸 줄일 수 있다면 좋습니다. 특히 소켓 수가 많고, 소켓 통신이 빈번하게 이루어지는 상황이라면 이 오버 헤드도 무시 못할 게 되죠.
대신에 코딩하기 귀찮아진다는 (무시 못할 ㅋㅋ) 단점이 있지만요.
추가로 소켓을 쓰레드에 분배하거나, 쓰레드끼리 데이타를 주고 받을 필요가 발생해서 생기는 오버 헤드도 있을 수 있습니다.
select나 poll을 사용하였을 때의 장점은 performance나
select나 poll을 사용하였을 때의 장점은 performance나 scale면에서는 큰 장점은 없는 것 같습니다.
하지만,
- thread를 여러개 만드는 것보다는 select를 사용하는 것이 메모리 사용면에서 효율 적이고
- 다른 io event와 같이 기다릴 수 있다
는 장점이 있을 것 같습니다.
저 같은 경우에는 두번째의 용도로 많이 씁니다. 예를 들어 소켓 통신 중 중단 시키려는 경우 빨리 깔끔하게 뒷처리를 하도록 하기 위해서는 blocking인 경우 thread를 바로 깨워줘야 하는데 이를 위한 방법이 없어서요.
제가 주로 사용하는 것이 RTOS인데 unix는 이런 경우에 깨울수 있는 방법이 있나요?
throughput 과 response time 간 trade off 관
throughput 과 response time 간 trade off 관계인데요.
일단 이거 단일 프로세스라는 가정에서 이야기를 하면
throughput 은 select 가 좋습니다.
kane 님께서 말씀 하셨듯이 컨텍스트 스위칭, 쓰레드 스케줄링, 크리티컬섹션의 뮤텍스 처리등이 쓰레드를 이용하면 생기는 부하들인데 이런 것들이 없기때문에 전체 성능은 좋아집니다.
하지만 select 는 (쓰레드와 비교해 상대적으로) response time 이 떨어집니다. 클라이언트 입장에서는 다른 클라이언트가 서버에 먼저 뭔가 요구했다면 그 작업이 끝날때까지 기다렸다가 내 차례가 오기때문이죠.
위와 같은 상황은 커널이 프로세스 스케줄링할때 어떤 알고리즘을 사용하느냐 그리고 한 프로세스에 한번에 주는 cpu 시간의 크기에 따라 throughput 과 response time 이 trade off 관계인것 과 같은 것이지요.
또한 쓰레드를 쓰면 각각의 쓰레드 생성 오버헤드도 있고 각 쓰레드의 스택세그먼트 공간을 생각하면 메모리 낭비가 문제지요.
그럼 쓰레드는 뭐가 좋냐? 위에 말씀 드린 것 처럼 response time 이 짧고 (클라이언트 입장에서 보면 서버의 throughput 은 자기완 전혀 상관없고, response time 이 중요하죠), 크리티컬섹션을 제외한다면 코드도 select 보다 간단하고, 멀티 프로세서일때 필요하다면 모든 프로세서를 동시에 병렬로 이용해서 단일 프로세서의 select 보다 더 좋은 throughput 을 낼 수도 있습니다.
Context Switch 의 Overhead 가 있었군요!!이런이런
Context Switch 의 Overhead 가 있었군요!!
이런이런~ 가장 기본적인것을 놓치다니.. 역시 내공이 부족합니다.
답변주신 세분 감사합니다.
삽질의 대마왕...
NonBlock IO를 쓰는 가장 큰 이유는 소켓의 데이터 처리에 대한
NonBlock IO를 쓰는 가장 큰 이유는 소켓의 데이터 처리에 대한 스케쥴링을 OS나 일반적인 라이브러리에 맡기지 않고, 스스로 구현한 스케쥴링을 사용하겠다는 것입니다.
그리고, OS의 다른 overhead인 process/thread의 스케쥴링 비용(요것이 소켓 100개정도만 넘어가도 상당한 비용이 됩니다.)을 없애겠다는 것입니다.
윗분들이 언급하지 않은 것 하나는 select 또한 소켓수가 100개 이상되면 비용이 작은 것이 아닙니다. select는 각 소켓의 버퍼에 WATER MARK 이상의 값이 있는지에 대해 반응하는 것입니다. 대개 WATER MARK 값은 1로 설정되어 있고, 그 값보다 크게 데이터들이 들어와 있는지를 일일이 비교합니다. 즉 data의 level에 따라 select되는 것이고, 매번 I/O로부터 데이터가 올라왔을 때 바로 반응하는 epoll 을 사용하는 것이 좋습니다.
---
coolengineer.com