http://wireframes.linowski.ca/category/samples/

괜찮다 미뎌쿼리나 이런것들이 많이 이슈가 되고 있는 지금 이렇게 먼저 손으로 그려보고 떠올리고

http://proto.io/

이것두! 

지난번에 면접때문에 한번.. IR기법을 찾아보고 써보았는데.
음 모바일의 경우 IR으로 할경우 background사이즈를 어떻게 할까?
px로 늘려서 사용하나.
현재 다음이나 네이버등 iphone 3gs사용할땐 전혀몰랐는데
4s로 갈아타고 나서 이미지 늘어진것들이 굉장히거슬린다.흠

정말 초당 수억개의 서버로의 요청이 없는한은(예를들면 포털)
ir기법은 꼭 필요한곳에만 쓰고 이미지로 대체할수 있는곳은 이미지 element를 사용하는게 좋을법싶다.  
a{display:block;overflow:hidden;width:145px;height:14px;text-overflow:ellipsis;-o-text-overflow:ellipsis}
a,x:-moz-any-link,x:default{white-space:normal;word-wrap:break-word} /* Firefox 에서 줄 바꿈이 가능하도록 변경 */
*+html a{white-space:nowrap} /* 위 행이 IE7에도 적용되므로 IE7에만 줄 바꿈이 불가능하도록 다시 복원 */
해볼까용 ?
 
출처 - http://alones.kr/blog/852


몇 년 동안 Java를 손에서 놓았고 C++을 하다 최근 다시 Java를 하려니 적응하기가 힘들다. Eclipse와 함께 너무나 편안하고 설계까지 깔끔하게 잘되었다고 생각이 들면서도 가끔 어떤 부분들은 (생각해보고 또 생각해보면 맞지만) 이해가 쉽지 않은 부분도 있다.


아무튼 std::map을 대처하기 위해 HashMap을 쓸 것인가? Hashtable을 쓸 것인가?

예전에 별생각도 안 하고 먼저 떠오르는 데로 쓴 것 같다.


결론부터 말하면 (예전에 그랬던 것처럼) 별생각 없이 쓴다면 HashMap을 쓰면 될 것이다.


그리고 HashMap과 Hashtable의 Java Doc을 보고 정리하면,


HashMap 기준에서 Hashtable과 비교하면

1. HashMap은 key와 value에 null을 허용하지만 Hashtable은 그렇지 않다.

2. HashMap은 thread safe하지 않고 (not synchronized) Hashtable은 그렇다 (synchronized). 진정한 Java인이라면 미래를 위해 Hashtable을 쓰는 게 맞을 것 같기도 하다.
HashMap 자체는 not synchronized하기 때문에 다음과 같이 Collection.synchronizedMap을 이용해서 synchronized하게 만들 수 있다.

Map m = Collections.synchronizedMap(new HashMap(...));

3. HashMap은 bucket에 element들을 흩어뿌리기 때문에 get/put과 같은 기본 동작들이 동일한 시간 (constant-time performance) 에 수행된다.


HashMap과 Hashtable에서 둘 다 고려할 사항은

1. capacity와 load factor

Capacity는 bucket의 수이고 load factor는 bucket의 element가 얼만큼 찼을 경우 rehash를 발생 시킬 것인지를 정하는 것이다. rehash의 경우는 bucket의 수가 두 배로 늘어나고 각 element에 대해서 hash가 다시 일어나는 것을 의미하기 때문에 이 것은 시간-공간의 trade-off가 있다.

Load factor는 0.75를 HashMap과 Hashtable에서 둘다 ideal number로 권장하고 default value이다.

Capacity는 HashMap은 default value가 16이고 Hashtable은 11이다.

생성할 때 아주 많은 (얼만큼인지는 제시하지 않고 있다) element가 삽입될 것이라면 capacity를 초기에 높게 잡는게 좋을 것 같다.


2. ConcurrentModificationException

Iterator를 얻은 후에 Iterator를 통하지 않고 외부에서 element가 삭제되거나 추가되면 ConcurrentModificationException이 발생한다 (fail-fast라고 한다. 문제가 생기면 바로 보고하는 것으로 fail-stop이라고 한다). 당연한 말이겠지만, fail-fast로 인한 exception handling을 통해 기능을 수행하는 코드를 작성하지 말고 말 그대로 bug를 찾기 위해 이를 이용해라고 한다.


아무튼 오래 만에 JavaDoc을 자세히 읽어 본거 같다. 프로그램에서 많은 것들이 중요할 것이고 그 중 자료 구조 (특히 자바와 같은 언어에서)도 많은 것을 고려해야 하기에 포스트를 지루하게 써보았다.

"별 생각 없이 쓴다" 라는 말 자체를 이미 거론해 버렸지만 그리고 그 목적으로 HashMap을 거론했지만, "별 생각 없이 쓴다" 라는 말 자체는 (그리고 그 "별 생각 없이 쓴 것"들이 많아 질 수록) 미래의 재앙을 키워가는 것이기 때문에 지양 해야 할 것이다.


[Ref]

HashMap Java Doc SE6: http://java.sun.com/javase/6/docs/api/java/util/HashMap.html

Hashtable Java Doc SE6: http://java.sun.com/javase/6/docs/api/java/util/Hashtable.html

Fail-fast (Fail-stop): http://en.wikipedia.org/wiki/Fail-fast

2008/03/30 22:56 2008/03/30 22:56

이번에 파일업로드를 만들면서!


--------------

* 강좌를 시작하기전에....

- 기존의 jspSmartUpload를 대체해 가고 있는 MultipartRequest에 대한 간단한 사용법에 대해 강의 합니다.
JSP만을 사용하는 강좌이며 Beans, Servlet은 다루지 않습니다.

- MultipartRequest는 COS 패키지에 포함되어 있는 파일 업로드 컴포넌트 입니다.

- COS 에서는 한글등(non-Latin-1)의 언어를 지원하지 않았었습니다. 그러한 이유로 이아스(이창신)님 께서 배포한 COSI(COS International) 를 주로 사용 하였으나, 이아스님의 노력에 힘입어 2002년 5월 9일 자 COS에서는 한글을 포함한 non-Latin-1 계열의 언어를 지원하게 되었습니다. 근 2년간의 국제화를 위한 투쟁이 비로서 결실을 맺는 순간이었습니다.
이에 따라 본 강좌의 내용도 COS 맞추어 약간의 수정을 했습니다.

COS 공식 사이트 : http://www.servlets.com/cos/index.html


* MultipartRequest는....

필자는 기존에 jspSmartUpload를 주로 사용하여 업로드를 구현했었다. 하지만 jspSmartUpload는 로직자체에 상당한 문제점(업로드된 파일을 메모리에 올리고 작업하여 그로인해 파생되는 문제점들)이 있음이 밝혀 졌고, 그로인해 jspSmartUpload의 사용은 급속히 줄어 들었다.

사실 jspSmartUpload에서는 편리한 많은 메소드를 지원해주고 있어 MultipartRequest를 사용하는것 보다 훨씬 쉽게 원하는 기능을 구현 할수 있는 것이 사실이다. 하지만 jspSmartUpload는 문제점이 발견 되었으므로 가능한사용을 자제하는 것이 좋겠다.

MultipartRequest는 아주 간단한 메소드를 몇개 지원한다. 하지만 이 메소드들 만으로도 왠만한 기능은 전부 구현이 가능하니 실망하지 말자. getFile() 메소드를 이용하면 java.io.File 객체를 얻어 낼수 있으니 이를 이용하면 될것이다.


* 설치하기

MultipartRequest는 oreilly에서 배포하며, http://www.servlets.com/cos/index.html에서 다운로드 받아도 되고, 필자의 홈페이지(http://aboutjsp.com)의 자료실에도 업로드를 해놓았으니 다운받아 사용해 보기 바란다.

설치 하는 방법은 다운로드 받아서 압축을 푼뒤, classes 디렉토리 아래를 톰캣의 classes 디렉토리에 통째로 복사한다. (예.ROOT/WEB-INF/classes) 혹은 cos.jar를 lib에 복사해도 된다.

COS 패키지기에는 MultipartRequest 말고도 유용한 많은 클래스들이 많이 존재하므로, 여기의 API문서를 참고하여 사용하기 바란다


* 업로드 구현

간단한 예제를 통해서 알아 보도록 하자.

wirte.htm
<html> <body> <form action="up.jsp" enctype="multipart/form-data" method="post"> 이름 : <input type="text" name="userName"> <br /> 파일 : <input type="file" name="upfile"> <input type="submit" value="Upload"> </form> <script type="text/javascript">(function($) { $(document).ready(function() { lightbox.options.fadeDuration = 200; lightbox.options.resizeDuration = 200; lightbox.options.wrapAround = false; lightbox.options.albumLabel = "%1 / %2"; }) })(tjQuery);</script> <div style="margin:0; padding:0; border:none; background:none; float:none; clear:none; z-index:0"></div> <script type="text/javascript" src="https://tistory1.daumcdn.net/tistory_admin/userblog/tistory-717c7b1234a0a46519d1483dc3db06322985d92c/static/script/common.js"></script> <script type="text/javascript">window.roosevelt_params_queue = window.roosevelt_params_queue || [{channel_id: 'dk', channel_label: '{tistory}'}]</script> <script type="text/javascript" src="//t1.daumcdn.net/midas/rt/dk_bt/roosevelt_dk_bt.js" async="async"></script> <script type="text/javascript" src="https://tistory1.daumcdn.net/tistory_admin/userblog/tistory-717c7b1234a0a46519d1483dc3db06322985d92c/static/script/menubar.min.js"></script> <script>window.tiara = {"svcDomain":"user.tistory.com","section":"기타","trackPage":"글뷰_보기","page":"글뷰","key":"235273","customProps":{"userId":"0","blogId":"235273","entryId":"null","role":"guest","trackPage":"글뷰_보기","filterTarget":false},"entry":null,"kakaoAppKey":"3e6ddd834b023f24221217e370daed18","appUserId":"null"}</script> <script type="module" src="https://t1.daumcdn.net/tistory_admin/frontend/tiara/v1.0.0/index.js"></script> <script src="https://t1.daumcdn.net/tistory_admin/frontend/tiara/v1.0.0/polyfills-legacy.min.js" nomodule="true" defer="true"></script> <script src="https://t1.daumcdn.net/tistory_admin/frontend/tiara/v1.0.0/index-legacy.js" nomodule="true" defer="true"></script> </body> </html>

up.jsp
<%@ page contentType="text/html;charset=UTF-8" 
%><%@ page import="com.oreilly.servlet.MultipartRequest,
                   com.oreilly.servlet.multipart.DefaultFileRenamePolicy,
                   java.util.*" 
%><%
 String savePath="/usr/local/tomcat/webapps/ROOT/test/upload"; // 저장할 디렉토리 (절대경로)

 int sizeLimit = 5 * 1024 * 1024 ; // 5메가까지 제한 넘어서면 예외발생

 try{

	MultipartRequest multi=new MultipartRequest(request, savePath, sizeLimit, new DefaultFileRenamePolicy());
 	Enumeration formNames=multi.getFileNames();  // 폼의 이름 반환
	String formName=(String)formNames.nextElement(); // 자료가 많을 경우엔 while 문을 사용
	String fileName=multi.getFilesystemName(formName); // 파일의 이름 얻기

	if(fileName == null) {   // 파일이 업로드 되지 않았을때
		out.print("파일 업로드 되지 않았음");
	} else {  // 파일이 업로드 되었을때
		fileName=new String(fileName.getBytes("8859_1"),"UTF-8"); // 한글인코딩 - 브라우져에 출력
		out.print("User Name : " + multi.getParameter("userName") + "<BR>");
		out.print("Form Name : " + formName + "<BR>");
		out.print("File Name  : " + fileName);
	} // end if

 } catch(Exception e) {
	out.print("예외 상황 발생..! ");
 } 
%>
				

위의 예제 소스를 보면 대부분이 이해가 잘 갈것이라 생각되지만.. 하나씩 살펴 보도록 하겠다. 우선 write.htm 에서는 폼에서 method="post" 형식으로 해야 하며 ecntype="multipart/form-data" 를 꼭 붙여 주어야 한다.

다음으로 up.jsp를 하나 하나 살펴 보자. MultipartRequest 클래스를 import 하고, java.util.* 는Enumeration 객체를 사용하기 위해서 import 한다..

savePath 는 저장될 실제 디렉토리(시스템상의 절대 경로)를 적으면 된다. sizeLimit 에서는 제한 용량을 셋팅하는데, 위와같은방법으로 메가바이트 단위로 지정할 수 있다.

그 다음줄에서는 MultipartRequest 객체가 생성됨과 동시에 업로드가 이루어져 지정한 디렉토리에 저장된다. 이때 MultipartRequest의 여러 생성자들중 하나를 이용하면 되는데, 기존에는 새성자로 한글 "UTF-8"을 줬어야 했는데, 어쩐일인지 이제는 주지 않아아 한글 이름의 파일이 잘 저장되느는 것을 볼수 있다. 또한 가장 오른쪽의 'new DefaultFileRenamePolicy' 는 는 파일 이름 중복처리에 관한 것으로 넣을수도 있고, 뺄수도 있다. 필요하지 않다고 생각된다면 빼버리도록 하자.

그아래에 if 문을 보면, 파일이 업로드 되었을때와 업로드 되지 않았을때의 처리를 나누어서 할수 있도록 하고 있다.

if 문 위의 3라인은 파일의 이름을 얻기위한 로직으로 Enumeration 객체로 받은 폼의 이름을 이용하고 있다. 만약 폼이 여러개가 있을 경우엔 적절한 자료형을 이용하여 폼의 이름을 통해서 파일의 이름들을 얻어 낼수 있을 것이다. 만약 파일 업로드를 Beans로 구현할 경우엔 반드시 이러한 로직을(Enumeration 객체를 이용한 loop구문)사용해야 할 것이다.

사실 위의 예제에서는 굳이 Enumerration 객체를 가지고 구현할 필요는 없지만, 해당 메소드의 사용법을 보여주기 위해서 사용하였다. 이러한 방법을 사용하지 않을 경우에는 if 위에 3라인을 삭제하고 아래의 내용을 추가 하면다.

String fileName=multi.getFilesystemName("upfile");


* FileRenamePolicy 에 관해서...

이번 버젼의 MultipartRequest 에서 부터는 파일 중복처리 인터페이스가 추가 되었고, 위의 예제 소스는 그러한 내용이 반영되어있다. DefaultFileRenamePolicy는 FileRenamePolicy Interface 를 구현한 것으로, 중복된 파일 이름뒤에 숫자를 붙여 주고 있다. ( abcd.zip , abcd1.zip, abcd2.zip, abcd3.zip ....... )

DefaultFileRenamePolicy Class를 바탕으로 새로운 RenamePolicy class 를 만들면 자신이 원하는 FileRenamePolicy 를 적용할수 있다.

또한 getFilesystemName()메소드를 이용하여 변경된 파일 이름을 얻을수 있고, getOriginalFileName()메소드는 변경되기 이전의 파일이름을 넘겨준다.


* multi.getParameter()

write.htm 에서 서정한바와 같이 enctype="multipart/form-data" 로 지정하면, request.getParameter()로는 아무러 값도 받아 올수가 없게된다. 그러한 이유로 대부분의 파일업로드 컴포넌트에서는 getParameter() 메소드를 지원하는데, MultipartRequest에서도 이러한 메소드를 지원한다. 지원하는 메소드는 아래와 같으며, 사용법은 request.getParameter() 등과 동일하다.

String getParameter(String name)
Enumeration getParameterNames()
String[] getParameterValues(String name)


* 한글관련 문제 처리법

MultipartRequest multi=new MultipartRequest(request, savePath, sizeLimit, new DefaultFileRenamePolicy());

위를 아래와 같이 수정한다.

MultipartRequest multi=new MultipartRequest(request, savePath, sizeLimit, "UTF-8", new DefaultFileRenamePolicy());

"UTF-8" 부분엔 "ksc5601", "ms949" 등 자신의 환경에 알맞는 캐릭터셋을 넣어 주면 된다.

각 메소드들에 대한 자세한 사용법은 아래의 API문서를 참고 하기 바란다.

http://aboutjsp.com/docs/cos/



펌 : http://aboutjsp.com/lec/multipart.jsp





<%
 String DB_URL = "jdbc:mysql://localhost/testdb";
 String DB_USER = "root";
 String DB_PASSWORD = "1111";
 Connection conn;
 Statement stmt;
 String query = "SELECT * FROM brain";
 ResultSet rs = null;
 try {
  Class.forName("org.gjt.mm.mysql.Driver");
  conn = DriverManager
    .getConnection(DB_URL, DB_USER, DB_PASSWORD);
  stmt = conn.createStatement();
  rs = stmt.executeQuery(query);
  while (rs.next()) {
   out.println("name : " + rs.getString("name"));
  }

  rs.close();
  conn.close();
  stmt.close();
  out.println("mysql jdbc test : connection ok!!");
 } catch (Exception e) {
  out.println("실패" + e.getMessage());
 }
%>


우홍홍 성공.
이제 컨트롤러로~ ㅋㅋ


잡아슥흐립트북

캉진님이 나에게준 JQuery in Action
준거맞지요...ㅋㅋㅋㅋ

Jquery 왜씁니까 뭘 할수 있습니까?
이 책에 나와있다.
JQuery()함수로
페이지 구성을 향상시키고 코드 유연성을 높일수 있도록 동장을 구조에서 분리시킬수 있다고 했다.
뭐라는거야..............
여튼.
jquery를 이제 써봅세다래~ :)

+ Recent posts