캠핑과 개발

<mvc:annotation-driven>은 @MVC 스타일의 컨트롤러에서 자주 사용되는 validator, conversionService, messageConverter를 자동으로 등록해주는 간편 빈 설정용 태그이다.

이 태그에 의해서 자동으로 등록되는 기능들에 대해서는 3.0.1의 보강된 레퍼런스 문서에 다음과 같이 잘 나와있다.

  1. Support for Spring 3′s Type ConversionService in addition to JavaBeans PropertyEditors during Data Binding. A ConversionService instance produced by the org.springframework.format.support.FormattingConversionServiceFactoryBean is used by default. This can be overriden by setting the conversion-service attribute.
  2. Support for formatting Number fields using the @NumberFormat annotation
  3. Support for formatting Date, Calendar, Long, and Joda Time fields using the @DateTimeFormat annotation, if Joda Time is present on the classpath.
  4. Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath. The validation system can be explicitly configured by setting the validator attribute.
  5. Support for reading and writing XML, if JAXB is present on the classpath.
  6. Support for reading and writing JSON, if Jackson is present on the classpath.

그런데 과연 이게 전부일까?

아니다.

<mvc:annotation-driven>이 등록해주는 빈이 한가지 더 있다. 바로 MappedInterceptor이다. 정확히 말하자면 모든 경로에 대해서 적용되는 ConversionServiceExposingInterceptor를 가진 MappedInterceptor이다.

아직 많은 개발자들에게는 MappedInterceptor도 3.0에서 새로 추가된 것이라 생소할 것이다. 기존 HandlerInterceptor는 핸들러 매핑의 프로퍼티로 등록된다. 이 때문에 두 가지 단점이 있는데, 첫 째는 핸들러 매핑 전략을 두 개 이상을 병행해서 사용하면 인터셉터를 일일히 핸들러 매핑마다 등록해줘야 한다는 점이다. 둘 째는 핸들러 매핑에 등록한 인터셉터는 그 핸들러 매핑이 처리하는 모든 요청에 적용된다는 점이다. URL에 따라 적용 인터셉터를 선별하려면 인터셉터 안에서 URL을 필터링 하는 작업을 해야 한다.

MappedInterceptor는 이 두가지 단점을 보완해주는 새로운 인터셉터 적용방식이다. MappedInterceptor를 빈으로 등록하고 path와 interceptor를 지정해주면 해당 경로패턴에 일치하는 URL에 대해서는 어떤 핸들러 매핑을 이용하든 상관없이 지정한 인터셉터를 적용해준다. 일종의 글로벌 스마트 인터셉터 레지스트리라고나 할까. 이 MappedInterceptor의 등장으로 앞으로는 핸들러 매핑에 인터셉터를 등록해서 사용할 일은 없을 듯 하다.

아무튼, <mvc:annotation-driven>는 뜬금없이 이 MappedInterceptor를 등록해버린다. 그것도 모든 경로에 대해서 적용한다. 추가된 인터셉터는 ConversionServiceExposingInterceptor라는 단순한 것인데, ConversionService 오브젝트를 request의 애트리뷰트에 등록해주는 간단한 작업을 수행한다. ConversionService라면 AnnotationMethodHandlerAdapter에 의해서 @ModelAttribute에 바인딩할 때 사용할 오브젝트이다. <mvc:annotation-driven>에서는 conversion-service 애트리뷰트에 의해서 재구성한 ConversionService를 지정할 수 있다.

<mvc:annotation-driven>는 바로 이 ConversionService를 request 스코프 애트리뷰트에 등록한다. 도데체 어디서 써먹으려는 것일까?

 

용도는 바로 <spring:eval>이다. 새롭게 추가된 <spring:eval>은 JSP에서 JSP EL을 대신해서 초강력 SpEL을 사용할 수 있도록 추가된 태그이다. 바로 이 <spring:eval>이 모델 오브젝트의 프로퍼티 값을 텍스트로 변환할 때 ConversionServiceExposingInterceptor에 의해서 등록된 ConversionService가 적용되는 것이다.

<mvc:annotation-driven>을 사용하지 않아서 ConversionService가 등록되지 않았다면 <spring:eval>은 기본적인 타입변환만 지원하는 StandardTypeConverter을 사용한다. 그보다는 ConversionServiceExposingInterceptor을 통해서 등록되는 FormattingConversionService가 훨씬 강력할 것이다. 모델에 @NumberFormat이나 @DateTimeFormat같은 포맷터가 달려있다면 <spring:eval>만으로도 이 포맷팅이 적용된다는 뜻이다.

기존에는 PropertyEditor가 적용되는 폼에서나 포맷을 가진 프로퍼티 바인딩을 적용할 수 있었다. 단순 출력을 필요로 하는 곳에서는 JSP EL을 사용해야 했기에 모델 오브젝트 프로퍼티의 포맷을 지정하려면 지저분한 <fmt:formatNumber> 따위의 태그를 사용해야만 했다. 그것도 몇가지 종류의 포맷밖에 지원이 안된다.

하지만 이제 3.0.1부터는 <spring:eval>을 사용해서 ConversionService의 막강한 타입변환-포맷팅 기능을 적용할 수 있다.

 

아직 레퍼런스나 API문서 등에도 공개되지 않은 내용인데.. 이런 중요한 정보를 미리미리 알려주지 않다니!

3.0.1의 막강한 @MVC와 ConversionService, Formatter, JSR-303 Bean Validation, Message Converter, AJAX 등등등을 활용한 편리한 웹 개발에 대해서 자세히 알고 싶다면 조만간 출시 예정인 스프링 3.0 책을 참고하도록… 



출처 : http://toby.epril.com/?p=989

얼마전 뽐뿌 이벤트 게시판에 초고속 충전기 체험단을 모집한다는 소식을 듣고 체험단 신청을 했습니다.

당연히 안되겠지 해서 체험단 신청을 자주 하지는 않지만

이번에는 당첨이 되었네요.


 충전케이블과 충전기가 필요했는데.

충전기 체험단 이벤트에서 케이블도 같이 왔습니다. 




박스 개봉후 

충전기 외관은 일반 충전기와 그리 달라보이지 않네요.

하지만 동봉된 충전케이블은 튼튼해 보입니다.

충전기 뒷 부분에 보니 제품 정보가 나와 있습니다.



정격출력이 DC 9V라고 되어 있네요.

일반적인 스마트폰 충전기를 보니 DC 5V라고 되어 있습니다.

출력이 9V가 되니 충전이 엄청나게 빠르게 될꺼 같아요..


그래도 사용설명서는 잘 읽어봐야겠지요..

해당 제품은 Quick Charge 2.0을 지원하는 스마트폰에서만 고속 충전 기능을 발휘한다고 되어 있습니다.

그렇다면 그 9V를 지원하지 않는 스마트폰에서 사용하면 어떻게 될까요?


다행이 미지원 스마트폰은 자동으로 5V전압으로 바꾸어 충전을 시켜주는 똑똑한 기능을 가지고 있다고 하니 

아무 스마트폰에 사용하면 될꺼 같아요.


제가 사용하고 있는 스마트폰은 아이폰입니다.

불행히 고속 충전 기능을 제공하진 않네요.



 충전은 정상적으로 됩니다.

그리고 기분탓인지 제법 충전 속도가 빠르네요.

아쉽게도 아이폰에는 고속 충전기능을 사용할 수 없다니 너무 너무 아쉬웠습니다.



다행이 처남이  고속충전기능을 가지고 있는 스마트폰을 가지고 있어서 충전을 해봤습니다.

삼성 스마트폰인데 모델명은 잘 모르겠습니다.

최최신형인데...

삼성폰엔 관심이 그리 없다보니..


오오~~



어쨌든 두둥..

사랑한지 1051이라고 합니다. 


다시.. 

고속 충전 중 이라는 메세지가 나오며 약 36분 후 충전이 완료된다고 나오네요..

충전잭을 꽂아 놓고 잠깐 있었는데 충전이 어마어마하게 충전이 됩니다.


일반 충전기 대비 75% 빠르다고 하니 상당히 빠르게 충전이 되네요..

장사를 하지는 않지만 일반 식당 같은데서 여러개 사두면 엄청난 서비스 효과를 볼수 있지 않을까 생각드네요.

아직 며칠 써보지는 않았지만 고속 충전을 지원하는 스마트폰에서는 정말 괜찮은 아이템이라고 보이네요.


홈페이지 및 상세한 기능 설명은 아래 링크 및 이미지를 참고해주세요. 

홈페이지 바로가기


hsqldb 사용하기

개발2016. 7. 23. 08:15

hsqldb 서버 실행

java -cp hsqldb-2.2.9.jar org.hsqldb.server.Server --database.0 file:/User/test/hsqldb/testDb --dbname.0 testDb --remote_open true


데이터베이스 메니저 실행

java -cp hsqldb-2.2.9.jar org.hsqldb.util.DatabaseManager

'개발' 카테고리의 다른 글

IDE 단축키  (0) 2018.11.28
로컬 jar 파일 maven porject에 추가하는 법  (0) 2017.04.25
windows에 있는 AppData 폴더란?  (0) 2015.07.30
Git  (0) 2013.12.30
dxf file format  (0) 2012.08.16


인천지하철 2호선이 오는 7월 30일 첫 운행을 한다고 합니다.

무인지하철로 차량은 초기 2량으로 운행되며, 승객이 많을 경우 4량까지 운행 할 수 있다고 합니다.


좀 더 상세한 내용은 다음과 같아요.

영업개시 : 2016.7.30(토) 첫차부터

구간 : 검단오류 ~ 운연(27개역) 29.1km

시간 : 05:30~익일 01:00

운행 시간

 평 일

 출근시

07:00 ~ 09:00

3분 간격 

 퇴근시

 16:00 ~ 20:00

 평시

출.퇴근시간 이외 

6~10분 간격 

 토,일요일/공휴일

 

 6~8분 간격

 

배차 간격은 보통 6~10 분이며 출퇴근 시간은 3분으로 한다고 하니 제법 자주 자주 있네요.


집이 주안역인데 이제 인천대공원 가기도 편리할꺼 같아요. 

인천국제공항도 검암역에서 갈아타면 되니, 비행기 탈일은 많지 않지만 좋네요.

  




좀더 상세한 내용은 인천광역시 도시철도건설본부를 참고해주세요.


최근 윈도우를 사용하다가 보니 C:\나 D:\에 알수 없는 폴더가 생성이 되어있습니다.

바이러스를 의심하여 V3를 돌려보니 바이러스도 잡히지 않습니다.


원인이 뭔가 싶어 검색을 해보니 PC 문제는 아니고 일종의 백신 프로그램에서 제공되는 미끼였습니다.

사용중인 PC에는 V3가 백신이 설치 되었는데, 랜섬웨어 방지를 위해 V3에서 생성한 폴더이며, 정상적으로 생성된 폴더와 파일이라고 합니다.


 

첨부한 이미지를 보면 다음과 같은 폴더가 생성이 되었습니다.


정말 알수도 없는 그런 폴더입니다. 누가 봐도 먼가 문제가 발생되지 않았나 싶은 기분이 들게 만드네요..

그럼 해당 폴더에는 뭐가 있는지 한번 들어가봤습니다.



달랑 이름도 알수 없는 이미지 파일이 하나 있네요.

하지만 다른 PC에서 봤을때는 다수의 파일이 존재했으며, doc, pdf등의 여러 파일 확장자를 가지고 있었습니다.


해당 파일은 이미지 파일인데 이미지 뷰어로 열어보니 열리지 않네요..

그래서 메모장으로 한번 열어봤습니다.

그러니 파일이 열리네요.



파일 내용은 안랩에서 제공한 정상적인 파일로 랜섬웨어를 만든 디코이 파일이라고 합니다.


디코이(decoy)란 사냥에서 들새나 들짐승을 사정거리 안으로 유인하기 위해 만든 모형새라고 하네요..

한마디로 랜섬웨어를 유인하기 위한 미끼라고 하는거 같아요.


정상이라고 하나 그래도 폴더 이름이 마음에 들지 않는군요..



*랜섬웨어

몸값을 뜻하는 ransom과 제품을 뜻하는 ware의 합성어로, 사용자의 동의 없이 컴퓨터에 불법으로 설치되어서, 컴퓨터의 정상적인 이용을 방해하고, 이를 해제하기 위해 을 요구하는, 사용자의 파일을 인질로 잡는 악성 프로그램을 말한다


 




 


'일상 > 낙서장' 카테고리의 다른 글

9V 스마트폰 고속 충전기 네오퀵 사용기  (0) 2016.07.26
인천지하철 2호선 노선도  (0) 2016.07.18
주안역 미용실 DASS헤어  (0) 2016.05.30
2012-05-28 부처님 오신날 춘천 청평사  (0) 2012.05.30
봐야할 웹툰  (0) 2012.05.17

계곡 


1. 수락산 폭포상회


2. 홍천 용오름마을


3. 백운계곡


4. 횡성 병지방계곡


5. 고선계곡





'일상 > 여행' 카테고리의 다른 글

[비발디파크]겨울에도 역시 오션월드  (0) 2019.01.20
[javacafe O.T] O.T 사진  (1) 2008.04.07
javacafe O.T 롤링 페이퍼  (0) 2008.03.24

웹 제작시 필요한 아이콘을 무료로 제공해줍니다.


홈페이지는  

http://www.alessioatzeni.com/metrize-icons/

 

다운로드를 받으시면 해당 압축파일 안에 해당 아이콘이 있으며 

PSD(Single Shape Layer), SVG(Single Icon 512 * 512), EPS, AI, PDF, Web Front

과 같은 형태의 파일로 들어있습니다.


PSD 파일이 존재하니 다른 형태로 추가 아이콘을 제작할 수도 있으며 매우 유용한 사이트입니다.




Metrize_Icons.zip



PDF 문서를 웹상에서 표출 할 수 있게 해주는 플로그인입니다.

일반적으로 바로 링크를 걸면 브라우저에서 볼 수는 있지만 아래와 같이 UI및 간단한 기능을 제공해주는 사이트도 있습니다.



1. PDF.js

- site : http://mozilla.github.io/pdf.js/

- demo : http://mozilla.github.io/pdf.js/web/viewer.html


2. PDFObject

- site : https://pdfobject.com/

- demo : https://pdfobject.com/#examples


java를 이용하여 텍스트 파일을 읽고 쓰는 예제입니다.

사용법은 매우 간단하지만 매번 찾아 보고 쓰게 되어 간단한 샘플을 포스팅합니다.


파일쓰기는 일반 텍스트형식과 바이너리 형식으로 쓰는 방법을 기록하며 순서는 다음과 같습니다.

1. 텍스트 파일 읽고 쓰기

2. 바이너리 파일 읽고 쓰기

3. 텍스트 파일 라인번호 읽기



1. 텍스트 파일 읽고 쓰기


  1. package test;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.BufferedWriter;
  5. import java.io.File;
  6. import java.io.FileNotFoundException;
  7. import java.io.FileReader;
  8. import java.io.FileWriter;
  9. import java.io.IOException;
  10.  
  11. public class FileTextWriteReadExample {
  12.    
  13.     public static void main(String[] args){
  14.        
  15.         File inFile = new File("C:\\Users\\Public""in.txt");
  16.         File outFile = new File("C:\\Users\\Public""in.txt");
  17.        
  18.         //==========================//
  19.         // 텍스트 파일 쓰기
  20.         //==========================//
  21.         BufferedWriter bw = null;
  22.         try {
  23.             bw = new BufferedWriter(new FileWriter(outFile));
  24.             bw.write("테스트 합니다.");
  25.             bw.newLine();
  26.             bw.write("테스트 합니다.1");
  27.             bw.flush();
  28.         } catch (IOException e) {
  29.             e.printStackTrace();
  30.         }finally {
  31.             if(bw != null) try {bw.close()} catch (IOException e) {}
  32.         }
  33.        
  34.         //==========================//
  35.         // 텍스트 파일 읽기
  36.         //==========================//
  37.         BufferedReader br = null;
  38.         try {
  39.             br = new BufferedReader(new FileReader(inFile));
  40.             String line;
  41.             while ((line = br.readLine()) != null) {
  42.                 System.out.println(line);
  43.             }
  44.         } catch (FileNotFoundException e) {
  45.             e.printStackTrace();
  46.         } catch (IOException e) {
  47.             e.printStackTrace();
  48.         }finally {
  49.             if(br != null) try {br.close()} catch (IOException e) {}
  50.         }
  51.     }
  52. }
  53.  


2. 바이너리 파일 읽기 쓰기

바이너리 파일은 알맞은 데이터형에 맞도록 쓰게되며 쓴 형식을 알지 못하면 읽는것 조차 힘듭니다.

규칙적인 형식으로 파일을 썼다면 DataInputStream객체의 available() 메서드를 이용하여 반복문으로 읽어들여서 처리할 수 있습니다.

소스 코드상에 48라인에 주석처리 되어 있습니다.


  1. package test;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.BufferedOutputStream;
  5. import java.io.DataInputStream;
  6. import java.io.DataOutputStream;
  7. import java.io.File;
  8. import java.io.FileInputStream;
  9. import java.io.FileNotFoundException;
  10. import java.io.FileOutputStream;
  11. import java.io.IOException;
  12.  
  13. public class FileBinaryWriteReadExample {
  14.  
  15.     public static void main(String[] args) {
  16.  
  17.         File inOutFile = new File("C:\\Users\\Public""in.bin");
  18.  
  19.         // ==========================//
  20.         // 바이너리 파일 쓰기
  21.         // ==========================//
  22.         DataOutputStream dos = null;
  23.         try {
  24.            
  25.             dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(inOutFile)));
  26.             dos.writeInt(1);
  27.             dos.writeUTF("안녕하세요");
  28.             dos.flush();
  29.        
  30.         } catch (IOException e) {
  31.             e.printStackTrace();
  32.         } finally {
  33.             if (dos != null) try { dos.close()} catch (IOException e) {}
  34.         }
  35.  
  36.         // ==========================//
  37.         // 바이너리 파일 쓰기
  38.         // ==========================//
  39.         DataInputStream dis = null;
  40.         try {
  41.            
  42.             dis = new DataInputStream(new BufferedInputStream(new FileInputStream(inOutFile)));
  43.            
  44.             System.out.println(dis.readInt());
  45.             System.out.println(dis.readUTF());
  46.            
  47.             /* 파일을 기록할 때 int 형식으로만 입력 한 경우 반복문을 통해서 읽는다.
  48.             while(dis.available() > 0){
  49.                 dis.readInt();
  50.             }*/
  51.            
  52.         } catch (FileNotFoundException e) {
  53.             e.printStackTrace();
  54.         } catch (IOException e) {
  55.             e.printStackTrace();
  56.         } finally {
  57.             if (dis != null) try {dis.close()} catch (IOException e) {}
  58.         } 
  59.     } 
  60. } 



3. 텍스트 파일 라인번호 읽기

이게 왜 필요한가 싶을지도 모르겠다. 그냥 lineCount 라는 변수를 하나 만들고 증가값을 1씩 증가하면 될텐데 말이다..

그래도 필요할지 모르니.. 일단 포스팅..


  1. package test;
  2.  
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7. import java.io.LineNumberReader;
  8.  
  9. public class FileLineNumberReaderExam {
  10.  
  11.     public static void main(String[] args) {
  12.         String path = "C:\\Users\\mjhwang\\Desktop";
  13.         String fileName = "test.txt";
  14.         LineNumberReader reader = null;
  15.         try {
  16.             reader = new LineNumberReader(new FileReader(new File(path, fileName)));
  17.             String line = null;
  18.             while ((line = reader.readLine()) != null){
  19.                 System.out.println("Line Number " + reader.getLineNumber() + " : " + line);
  20.             }
  21.         } catch (FileNotFoundException e) {
  22.             e.printStackTrace();
  23.         } catch (IOException e) {
  24.             e.printStackTrace();
  25.         }finally {
  26.             try{ if(reader != null) reader.close()}catch(IOException e){}
  27.         }
  28.     }
  29. }