0. 

윈도우 10을 깔고, 개발환경을 구축하고 있습니다.

이곳저곳 기웃거리며 mysql 수동설치를 찾는데, 16/02/11기준 mysql 최신 버전이라 그런것인지 설치 방법이 조금씩 달랐습니다.

에러들을 처리하고 나서 정리하는 겸 적습니다.


1. 

http://dev.mysql.com/downloads/mysql/

에서 mysql-5.7.10-winx64을 다운

(Windows 10 64 bit을 사용할 경우)




2.

다운 후 원하는 경로에 압축풀기.

전 d:\mysql에 풀었습니다.

폴더 안에 my-default.ini 를 열고 수정합니다.

아래처럼 수정하시고 my.ini로 같은 폴더에 "다른이름으로 저장" 해주세요.

 1) basedir, datadir, port 앞에 주석(#)을 삭제한다.

 2) basedir에는 mysql 압축을 푼 폴더를 작성. (폴더경로는 백슬래시(\)가 아닌 슬래시로(/)

 3) datadir은 mysql압축을 푼 폴더 안에 data폴더

 4) port를 3306

 5) 수정 후, 다른 이름으로 저장 .. 이름을 my.ini로 같은 폴더에 저장합니다.

=>결과



3.

제어판에 환경변수에서 mysql 환경 변수를 등록해줍시다. 윈도우 키 누르시고 환경변수 검색하시면 바로 찾으실 수 있습니다.

전 설치한 경로가 d:\mysql이므로 MYSQL_HOME을 그곳으로 등록하였습니다.




이후, Path에 MYSQL_HOME\bin 폴더를 추가해줍니다.

%MYSQL_HOME%\bin 으로 적어야 합니다. MYSQL_HOME 양 옆에 %를 붙여주세요.

bin 전에는 \넣어주세요.





4.

 관리자 권한으로 명령 프롬프트를 실행합니다.

윈도우 키 누르시고 명령 프롬프트 검색 후 오른쪽 클릭, 관리자 권한으로 실행 혹은

윈도우 + x 키를 누르고 명령 프롬프트(관리자)를 찾으실 수 있습니다.


실행하시고 mysqld --initialize 를 입력


끝나고 명령 프롬프트엔 아무것도 안 나옵니다.

d:\mysql\data 폴더에(my.ini에 datadir로 입력하신 폴더) 데이터가 들어가는 것을 보실 수 있습니다.

(도중 문제가 생기셨다면, data 폴더 안에 내용을 비우고 다시 mysql --initialize 합니다.)


5.

 mysql을 서비스에 등록

"mysql 경로\bin\mysqld" --install

"d:\mysql\bin\mysqld" --install

(혹시나 안되시면, mysqld.exe로 

"d:\mysql\bin\mysqld.exe" --install)

=>path를 등록하였기 때문에 mysqld --install해도 서비스는 등록되지만, 실행하시면 에러가 발생합니다.

서비스 경로가 c드라이브의 mysql이 설치되는 기본 폴더로 지정되있게 되고, 이를 찾지 못해서 에러가 발생합니다.

=>삭제는 --remove입니다.


등록에 성공하였으면, 서비스를 시작해봅시다.

서비스 시작은 꼭 명령 프롬프트가 관리자 권한으로 실행되어야 합니다.

net start mysql

=> 서비스 중지는 net stop mysql


6.

서비스가 잘 시작되면, 루트 계정으로 접속해봅니다.

mysql -u root -p

그럼 또 에러가 납니다.

이유는 잘 모르겠지만, root의 비밀번호가 다르다고 접속할 수 없습니다. 지정한 적 없다 이놈아.

그래서 root의 비밀번호를 바꿔주어야 합니다.

일단, mysql에 root로 비밀번호가 없더라도 접속할 수 있어야 합니다.


 1)

 관리자 권한 명령 프롬프트로, 서비스를 멈춥시다.

 net stop mysql


 2)

 비밀번호를 생략하도록 서비스를 다시 시작합시다.

 mysqld --skip-grant-tables

 입력하면, 해당 명령 프롬프트는 서비스를 실행하느라 사용할 수 없습니다.


 3)

 다른 명령 프롬프트를 열고, mysql에 접속합니다.

 (새로 연 명령 프롬프트)

 mysql -u root -p

 비밀번호 입력하는데 엔터 눌러도 접속됩니다.


 4)

 use mysql;

 update user set authentication_string = password('새로운 비밀번호') where user = 'root'; 

 flush privileges;


 5)

 비밀번호를 생략했던 서버를 종료시키고, 새로운 비밀번호로 접속해봅시다.

 mysqld --skip-grant-tables 를 실행했던 명령 프롬프트를 종료합시다.

 윈도우키 + x 를 눌러 작업관리자(T)를 실행시키고, 백그라운드 프로세스에 있는 mysqld.exe를 종료시킵니다.


 6)

 명령 프롬프트를 관리자 권한으로 실행시키고, mysql 서비스를 시작합니다.

 net start mysql


 7)

 mysql -u root -p

 를 입력하고,

 새로운 비밀번호를 입력하면 접속할 수 있습니다.

 다만 사용하려면 root 비밀번호를 다시 설정하라는 알림이 뜹니다.

 alter user 'root'@'localhost' identified by '새로운 비밀번호';

 를 다시 입력해주셔야 정상적으로 사용 가능합니다.


7. 마치며

제가 한 방법이 정석이 아닐 수 있습니다. 전 제가 헤맨 과정을 그대로 적었습니다. 더 좋은 방법이 있다면, 댓글로 달아주시면 감사하겠습니다.

설치를 완료한 후 기억에 의존하여 적은 것이라, 혹시나 잘못된 점이 있다면 댓글 부탁드립니다.




+추가 database 와 datebase 내의 테이블은 다르므로 

그냥 root 계정내의 테이블을 추가해줬음

구지 new 계정을 추가하고 권한을 부여하고싶다면

http://ourcstory.tistory.com/45

여기서 권한부여 하면됨


+추가

차셋이 

mysql 내에서 

show variables like 'char%' 로 보면

euc-kr 이라서 utf-8 이안들어감 근데 my.ini 파일에서 수정하면 된다는데 때려 죽여도 못찾겠음.

https://stackoverflow.com/questions/22572558/how-to-set-character-set-database-and-collation-database-to-utf8-in-my-ini


이걸 참고해서 데이터베이스 별로 utf-8로 바꿔줄수있음 



추신

원본출처 : http://bombay.tistory.com/3

Scenario: 인터넷의 이미지 파일들을 저장해서, 이 이미지들의 파일명으로 DB의 프로필 파일이름을 변경시키려고 했다.


Solution: 아닛!! 이렇게 쉬운방법이



▲ 그럼 위와 같이 하면 됩니다.
dir /b >list.txt 로 지정을 하면...  자동으로 list.txt 의 파일을 생성해서 파일목록을 딱 넣어 줍니다.
물론, 파일이름은 임의로 지정할수 있습니다. 꼭 list로 해야하는거 아닙니다.^^



Scenario: 

┌ Include nav.jspf (login bar, 여기서 bootstrap jsp,css 갖고있음)

 main body.jsp (list)

└ Include Child.jspf (modal)


이런구조로된 jsp 프로젝트에서 body안에 있는 모달에서


모달관련 함수가 절대 안먹는것이었다.

문제는

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 이게 충돌이 먹어서였는데


어째서인지 body.jsp에서는 드롭다운도 잘되고 딴것도 다 잘되는데 modal 관련 함수만 전혀 안먹는거였다 (단순히 모달 fade in out은 잘됨)


딱 한순간 문제를 해결 할 수있엇는데, child.jspf에서 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 해주면

모달관련 함수는 먹었지만 문제는 body와 nav에서 부트스트랩관련 함수가 전혀 안먹었다(drop dwon 등등)


특히 이런 모달 콜백 함수가 전혀 안먹는게 나를 미치게 만들었다..

$('#genieModal').on('show.bs.modal',function (e) {

});


콜백을 안쓰면 엄청난 노가다를 해주어야했기에, 모든 방법을 동원해서 찾았지만 결국 안되는 것이엇다.



solution: 그 찰나  jQuery.noConflict(); 라는 기적적인 마법의키워드를 검색으로 알게되었다.


child 관련 <script> 안에 저키워드를 한번 써주니까 모든 충돌이 해결되었다.




문자열 간의 최단거리 찾기
 

***Scenario:데이터 활용시 사람간의 매칭 기능을 만드려고 참고한 내용

(주관식 설문지를 작성할경우) 예를들어 혈액형을 입력하라고 하자.
A임, A형,  A형임,

이 3답변은 실질적으로 같은답변이지만 단순히 Like 를 사용해서 쿼리를 작성할경우 찾을 수 가 없다.

그렇다면 어떻게 하면 3개의 답변이 비슷하다고 가정 할 수있을까?? 원래는 DAO에서 모든 데이터를 불러온다음 자료구좋에 넣어 파싱을 해서 검색을 하려고했다.

그러나 오버헤드가 너무 클 것같았다. 고민하던중 다음과 같은 포스팅을 찾을 수있엇다


두 개의 문자열 사이에 유사도가 가까울수록 같은 계열의 값으로 판단할 수 있을것이다.

이러한 기능을 수행하려면 모든 데이터 값들간의 조인이 일어나야하는데 사용자 정의 함수를 사용하면

최적화 되지 않는 경우가 많기 때문에 프로젝트에서 결과값을 얻기 쉽지가 않다.

Oracle 11g에서의 new feature가 있는데 아주 유용한 기능으로 소개하기로 한다.

DROP TABLE match_tab;

CREATE TABLE match_tab (
  id   NUMBER,
  col1 VARCHAR2(50),
  col2 VARCHAR2(50),
  CONSTRAINT match_tab_pk PRIMARY  KEY (id)
);

INSERT INTO match_tab VALUES (1, 'Peter Parker', 'Pete Parker');
INSERT INTO match_tab VALUES (2, 'Peter Parker', 'peter parker');
INSERT INTO match_tab VALUES (3, 'Clark Kent', 'Claire Kent');
INSERT INTO match_tab VALUES (4, 'Wonder Woman', 'Ponder Woman');
INSERT INTO match_tab VALUES (5, 'Superman', 'Superman');
INSERT INTO match_tab VALUES (6, 'The Hulk', 'Iron Man');

INSERT INTO match_tab VALUES (11, '환자입원일시', '환자입원일');
INSERT INTO match_tab VALUES (12, '슈퍼맨', '슈퍼 맨');
INSERT INTO match_tab VALUES (13, '슈퍼맨', '슈퍼맨');
INSERT INTO match_tab VALUES (14, '슈퍼맨', '아이언맨');
INSERT INTO match_tab VALUES (15, '동창생', '도차생');
INSERT INTO match_tab VALUES (16, '일반 환자 격리', '일반환자격리');
INSERT INTO match_tab VALUES (17, '트러블 메 이 커', '트메이크');

COMMIT;

SELECT col1,
       col2,
       UTL_MATCH.edit_distance(col1, col2) AS ed,
       UTL_MATCH.edit_distance_similarity(col1, col2) AS eds,
       UTL_MATCH.jaro_winkler(col1, col2) AS jw,
       UTL_MATCH.jaro_winkler_similarity(col1, col2) AS jws
FROM   COMP_TABLE
ORDER BY id;

우리가 눈여겨 볼만한것은 유사도입니다. EDS, JWS

영문과 한글일때의 유사도의 차이는 조금 다르지만 문자열에 대한 유사도를 찾을수 있는

좋은 기능입니다.

잘만 응용하면 좋은 TIP이 될수 있을것입니다.


출처:http://www.dator.co.kr/newyemac/894089


Scenario: 이번 프로젝트를 할때 설문조사를 실행하여 사람과 사람간의 유사한답변을 찾은사람끼리 매칭시켜주는 기능을 만들고자 했었다.


Solutions: 맨처음에는 주관식을 하여 단어간의 유사성을 찾아 매칭시켜줄려고 했지만, 객관식으로 하는것이 더 깔끔 할 것같아서 바꿈


1.테이블 구조(간단함)

SQL 0.19 KB
  1. CREATE TABLE MBER_TQ
  2. (  
  3.     TQ_IDX         NUMBER  PRIMARY KEY,
  4.     MBER_EMAIL      varchar2(50) NULL,
  5.     TQ_QUESTION     NUMBER NULL,
  6.     TQ_ANSWER       NUMBER NULL,
  7.   DEL_FLAG varchar2(5) DEFAULT 'N'
  8. );


2.설문조사를 시작하자마자 수행되는 쿼리

SQL 0.63 KB
  1. --같은사용자가 재 설문조사를할경우 Init해주는 쿼리(시작하기전에 한번 실행)
  2. UPDATE MBER_TQ
  3. SET DEL_FLAG = 'Y'
  4. WHERE MBER_EMAIL = '1@gmail.com';
  5.  
  6.  
  7. --답변을 선택할때마다 동적으로 실행되는 인서트쿼리
  8. INSERT INTO MBER_TQ VALUES(SEQ_MBER_TQ_IDX.NEXTVAL ,'97@gmail.com' ,1,2,'N');
  9. INSERT INTO MBER_TQ VALUES(SEQ_MBER_TQ_IDX.NEXTVAL ,'98@gmail.com' ,1,1,'N');
  10. INSERT INTO MBER_TQ VALUES(SEQ_MBER_TQ_IDX.NEXTVAL ,'99@gmail.com' ,1,3,'N');
  11. INSERT INTO MBER_TQ VALUES(SEQ_MBER_TQ_IDX.NEXTVAL ,'100@gmail.com' ,1,4,'N');
  12. INSERT INTO MBER_TQ VALUES(SEQ_MBER_TQ_IDX.NEXTVAL ,'101@gmail.com' ,1,2,'N');



3.핵심쿼리(내가 선택한 답변을 db에서 다른사람이 선택한 답변과 비교하여 상위 4명을 잘라서 보여줌)

SQL 0.77 KB
  1. SELECT MBER_NAME, MBER_IMG, MBER_INFO_IDX, MBER_SKILL, MBER_INTRODUCE, MI.MBER_EMAIL, SCORE
  2. FROM(SELECT MBER_EMAIL, SCORE
  3.      FROM  
  4.       (SELECT A.MBER_EMAIL ,SUM(B.SCORE) AS SCORE
  5.        FROM MBER_TQ A JOIN
  6.         (SELECT  MBER_EMAIL, TQ_QUESTION, TQ_ANSWER, 1 SCORE
  7.          FROM MBER_TQ
  8.          WHERE MBER_EMAIL='a@GMAIL.COM'
  9.          AND DEL_FLAG != 'Y') B
  10.        ON A.TQ_QUESTION = B.TQ_QUESTION
  11.        AND A.TQ_ANSWER = B.TQ_ANSWER
  12.        AND A.MBER_EMAIL != 'a@GMAIL.COM'
  13.        AND DEL_FLAG != 'Y'
  14.        AND SCORE IS NOT NULL
  15.        GROUP BY A.MBER_EMAIL
  16.        ORDER BY SUM(B.SCORE) DESC)
  17.        WHERE ROWNUM <= 4) GENIE, MBER_INFO MI ,MBER
  18. WHERE GENIE.MBER_EMAIL = MI.MBER_EMAIL
  19. AND MBER.MBER_EMAIL = MI.MBER_EMAIL
  20. ORDER BY GENIE.SCORE DESC;


Scenario: 이미지 파일첨부를 하려는데 기존 소스는 다중 파일첨부 였다, (multipartHttpServletRequest 리스트를 받아서 리스트를 돌리는 구조의 코드였음.) 이것을 살짝 변형 시켜서 단일 파일첨부구조와 재활용성이 가능하게 바꾸려고 고쳐보았다.


Solutions: 다음



1. 가장먼저 Multipart 객체를 받아서 파일과, 함께보내진 폼 요소를 파싱해줄  자바의 파일유틸부터 만들어줌

  1.     //파일 하나만 업로드시킬려고만듬 FileUtil.java (클래스가 없을경우 만들어 줘야함)
  2.     public Map<String,Object> parseInsertFileInfoOne(Map<String,Object> map, HttpServletRequest request) throws Exception{
  3.        
  4.         MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
  5.         Iterator<String> iterator = multipartHttpServletRequest.getFileNames();
  6.        
  7.         MultipartFile multipartFile = null;
  8.         String originalFileName = null;
  9.         String originalFileExtension = null;
  10.         String storedFileName = null;
  11.        
  12.         Map<String, Object> FileInfoMap = null;
  13.        
  14.        
  15.         //폴더가 없으면 해당 폴더 생성
  16.         File file = new File(CommonUtils.filePath);
  17.         if(file.exists() == false){
  18.             file.mkdirs();
  19.         }
  20.        
  21.         while(iterator.hasNext()){
  22.             multipartFile = multipartHttpServletRequest.getFile(iterator.next());
  23.             if(multipartFile.isEmpty() == false){
  24.                 originalFileName = multipartFile.getOriginalFilename();
  25.                 originalFileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
  26.                 storedFileName = CommonUtils.getRandomString() + originalFileExtension;
  27.                
  28.                 file = new File(CommonUtils.filePath + storedFileName);
  29.                 multipartFile.transferTo(file);
  30.                
  31.                 FileInfoMap = new HashMap<String,Object>();
  32.                 //인터셉트 맵 자체를 리턴해줄 파일맵에다 넣어줌. 그렇다면 구지 뉴 객체를 생성안해도 될듯
  33.                 FileInfoMap = map;
  34.                
  35.                 FileInfoMap.put("ORIGINAL_FILE_NAME", originalFileName);
  36.                 FileInfoMap.put("STORED_FILE_NAME", storedFileName);
  37.                 FileInfoMap.put("FILE_SIZE", multipartFile.getSize());
  38. //              FileInfoMap.put("REFER_IDX", (String)map.get("IDX"));
  39. //              FileInfoMap.put("NAME", (String)map.get("NAME"));
  40. //              FileInfoMap.put("PJT_SCH_TITLE", (String)map.get("PJT_SCH_TITLE"));
  41. //              FileInfoMap.put("PJT_SCH_CONTENT", (String)map.get("PJT_SCH_CONTENT"));
  42.             }
  43.         }
  44.         return FileInfoMap;
  45.     }


2.Service 객체에서 쓰는방법 예시 (컨트롤러에서 서비스로 보내준뒤 서비스에서 파일유틸 호출)

Java 0.27 KB
  1.     //serviceImpl.java
  2.     @Override
  3.     public void insertProjectSchedule(Map<String, Object> map, HttpServletRequest request) throws Exception {
  4.         Map<String, Object> resultMap = fileUtils.parseInsertFileInfoOne(map, request);
  5.         projectDAO.insertProjectSchedule(resultMap);
  6.     }


3.마이바티스 예시 (많은 파일 속성을 갖고있지만, 이 프로젝트에선 저장된 파일명만 쓴다고 가정

SQL 0.32 KB
  1.         <!-- 예시 sql -->
  2.         INSERT INTO PJT_SCHEDULE
  3.         (
  4.             PJT_SCH_IDX,
  5.             PJT_IDX,
  6.             SCH_TITLE,
  7.             SCH_CONTENT,
  8.             CREA_DATE,
  9.             DEL_FLAG,
  10.             IMG_NAME
  11.         )
  12.         VALUES
  13.         (
  14.             PJT_SCHEDULE_IDX_SEQ.NEXTVAL,
  15.             #{REFER_IDX},
  16.             #{PJT_SCH_TITLE},
  17.             #{PJT_SCH_CONTENT},
  18.             SYSDATE,
  19.             'N',
  20.             #{STORED_FILE_NAME}
  21.         )



4.로컬에 저장된 사진들을 띄울때. (파일패스 경로 전역변수는 적절한곳에 추가해줌)

Java 1.01 KB
  1.  
  2.     /* 이미지 파일불러올때 */
  3.     //Commoncontroller.java
  4.     //이미지 파일 띄울때 컨트롤러를 경유해서 로컬 저장소에 접근하는 것
  5.     @RequestMapping(value="common/getImage.do")
  6.     protected void getImageFile(CommandMap commandMap, HttpServletResponse response) throws Exception
  7.     {
  8.         String fileName = (String) commandMap.get("IMG_NAME");
  9.  
  10.         if(!fileName.isEmpty())
  11.         {
  12.             File file = new File(CommonUtils.filePath+fileName);
  13.             response.setHeader("Content-Type""image/*");
  14.             response.setHeader("Content-Length"String.valueOf(file.length()));
  15.             response.setHeader("Content-Disposition""inline; filename=\"" + file.getName() + "\"");
  16.             Files.copy(file.toPath(), response.getOutputStream());
  17.            
  18.             response.getOutputStream().flush();
  19.             response.getOutputStream().close();
  20.         }
  21.     }
  22.  
  23.  
  24.     //common utils.java에 변수추가(파일패스)
  25.     public static final String filePath = "C:\\dev\\upload\\";



Scenario: 동적으로 생성된 a 태그(컨텐츠 제목) 을 클릭하면 삭제를 할 수 있게 하려고했다. on(click,function()) 키워드로 했는데 아무리 해도 안먹는 것이었다. 그래서 차선책으로 동적으로 생성시킬때 onclick='fn_delete(this)' 이런식으로 줘서 삭제를 시키려고했더니, fn_delete 함수에까지는 접근을 하는데 this obj를 죽어도 못찾는 것이었다. 좌절의 연속..





Solutions: 방법은 아주 간단했다 ㅡㅡ;; on 대신 live 키워드를 써주면 된다.


  1.     $('#schedule_area').empty();
  2.     $.ajax({
  3.         type : "POST",
  4.         url : "??????",
  5.         data : "IDX="+pjtId,
  6.         dataType: "json",
  7.         async: false,
  8.         success : function(data, textStatus, xhr) {
  9.             $.each(data, function(key, val){
  10.                 var dayForm = "<div class='media regi-item'>" +
  11.                                 "<a class='thumb-left' name='sch_title_thumb' href='#this' >" +
  12.                                     "<img src='/mobiza/common/getImage.do?IMG_NAME="+val['IMG_NAME']+"' alt='$TITLE'>" +
  13.                                 "</a>" +
  14.                                 "<div class='media-body'>" +
  15.                                     "<h4 class='rs day_detail'>" +
  16.                                         "<a class='be-fc-orange fw-b' id='sch_title' name='sch_title' href='#this' onfocus='this.blur()' '>"+val['SCH_TITLE']+"</a>" +
  17.                                     "</h4>" +
  18.                                     "<p class='rs comment-content'>"+val['SCH_CONTENT']+"</p>" +
  19.                                     "<input id='SCH_IDX' name='SCH_IDX' type='hidden'  value='"+val['PJT_SCH_IDX']+"'>" +
  20.                                 "</div>" +
  21.                                "</div>";               
  22.                
  23.                 $('#schedule_area').append(dayForm)
  24.             });
  25.         },
  26.         error : function(request,status,error) {  
  27.            alert("code:"+request.status+"\n"+"error:"+error);
  28.         }
  29.      });

쿼리 결과에따라 동적으로 태그를 생성하는 ajax


text 0.19 KB
  1.         $("a[name='sch_title'],a[name='sch_title_thumb']").live("click", function(e){ //제목 이나 섬네일 클릭시
  2.             e.preventDefault();
  3.             fn_schDelete($(this));
  4.         });

해결 script

Scenario: 이미지를 웹페이지에서 업로드 후 업로드된 폴더에서 img 태그를 써서 꺼내올려고했는데 여러가지 문제가있었다.

Solutions: 맨처음에는 배포 프로젝트 폴더에만 넣어놓으면 되는줄 알았는데, 생각보다 복잡하다 reponsegetOutputstream 을써주어야한다.



****

9
5985
#224322 Q&A java jsp

이미지 업로드 후 view 할 때 질문입니다.


이클립스+톰캣으로 작업중에 있습니다.

프로젝트가 완료된 후 서비스를 할 때는 war를 뽑아서 톰캣에 디플로이시켜서 구동할 생각입니다.

현재 게시판에시 이미지를 업로드 할 때 진행중인 프로젝트의 workspace에 파일이 업로드 되도록 하였습니다.

업로드경로는 c:/eclipseWorkspace/ProjectName/WebContent/files/
에 올라가도록 하였습니다.

현재 파일 업로드는 정상적으로 되고 있습니다.

한가지 문제가 발생했는데 이미지가 업로드된 게시물을 선택해서 볼 때
그림이 나오지 않더군요. 그런데 이클립스에서 Project Explorer에서 F5를 해주고 나서 다시 게시물을 보면 업로드된 이미지가 잘 나타납니다.

게시물을 올리거나, 수정하고나, 삭제할 때 항상 지금처럼 이클립스 Project Explorer에서 F5를 해주어야 하는건지....

아니면 뭔가 다른 방법이 있다면 알려주셨으면 합니다.
0
1
  • 답변 9

  •  **** 

    흐음... 개발서버의 톰캣에 war 디플로이해서 해봤는데 여기서는 그런거없이 바로바로 되네요.
    이클립스로 톰캣 구동해서 테스트 하는 개발pc에서는 계속 새로고침 해줘야되는건가요?
    0
  •  ****

     

    프로젝트는 WAS의 배포경로에서 실행되게 됩니다.
    이클립스 + 톰캣으로 개발시
    workspace의 소스가 바로 실행되는 것처럼 느껴지지만
    실제로는 이클립스가 소스 변경이 감지될 때마다 자동으로 톰캣 배포 경로로 소스를 복사(배포)해주고
    배포 경로에서 소스가 실행되는 겁니다.
    workspace의 경로와 톰캣에 배포된 소스의 경로는 다르고요.

    그러니까 현재 상황은
    로컬에서는 실행되는 경로(배포 경로)와 업로드 경로(workspace)가 다르기 때문에
    이미지를 찾지 못하는 것이고요,

    개발서버에 올렸을 때는 업로드 경로를 배포 경로 밑의 files로 지정하셨을테니
    이미지가 제대로 보이는 것이겠죠.
    0
  •  ****
     
    아 그리고 로컬에서 실행시
    업로드 후 이클립스의 소스를 새로고침 하면 그 때부터는 제대로 보이는 이유도
    이클립스가 새로고침 하면서 workspace/files에 저장된 이미지를 배포 경로쪽으로 복사해주기 때문에
    그때부터는 제대로 보이는 겁니다.
    0
  •  ****
     
    NG님//답변 감사합니다 ^^. 그 경로를 찾아봐야겠네요!!!
    0
  •  ****

     

    말씀하신대로 경로 찾아내서 거기에 업로드 되도록 했더니 바로바로 됩니다.
    감사합니다!!!
    0
  •  ****

     

    워크스페이스 경로/.metadata/.plugins/org.eclipse.wst.server.core

    톰캣 플러그인의 배포경로입니다.
    요 경로 밑에서 찾아보세요.

    그리고 로컬에서 테스트할 때는 배포되거나 clean할 때마다
    기존에 업로드된 이미지들은 지워질거에요.
    0
  •  ****

     

    NG님//네 말씀하신대로 수정되서 자동으로 reload??하거나 하니까 없어지네요.
    서버에서 war가 새로 디플로이될때도 없어지는데... 이건 방법이 없는 건가요?
    0
  •  ****

     

    그럴 경우
    파일 업로드/다운로드처럼 아예 별도의 디렉토리에 저장하게 한 뒤
    이미지를 response.getOutputStream()에 담아주는 서블릿을 만들어서 불러다 쓰는 방법이 있습니다.

    img 태그의 src 값도 /files/img.jpg 이런식이 아니라
    /imgLoad.do?imgName=img.jpg 처럼 서블릿을 호출하는 식으로 바꾸고요.

    이 방법이 어려우면 배포하기 전에 이미지 업로드 디렉토리를 백업해뒀다가
    배포 후 덮어씌우는 식으로 해야할 겁니다.
    0
  •  ****

     

    NG님//그렇군요. 흐으... 아는게 없다보니 힘들군요. 더 연구해봐야겠습니다.
    0


response 객체를 써서 이미지를 꺼내오는 방법. 좀더 연구를 해봐야 알 듯하다.

Java 0.70 KB
  1. @WebServlet("/files/*")
  2. public class FileServlet extends HttpServlet {
  3.  
  4.     @Override
  5.     protected void doGet(HttpServletRequest request, HttpServletResponse response)
  6.         throws ServletException, IOException
  7.     {
  8.         String filename = URLDecoder.decode(request.getPathInfo().substring(1)"UTF-8");
  9.         File file = new File("/path/to/files", filename);
  10.         response.setHeader("Content-Type", getServletContext().getMimeType(filename));
  11.         response.setHeader("Content-Length"String.valueOf(file.length()));
  12.         response.setHeader("Content-Disposition""inline; filename=\"" + file.getName() + "\"");
  13.         Files.copy(file.toPath(), response.getOutputStream());
  14.     }
  15.  
  16. }






Scenario: 게시판을 만들고나서 이제 글내용을 불러와보니 엔터등 <br> 인식이 안되는 치명적인 현상이 있엇다.

 db에서 불러올때 엔터를 <br>로 인식하게 하는 util은 쉽게 가져올수 있엇는데, 

 <%= utils.getContent(String)%> 이런식으로 써야했다. 나는 db에서 Content를 불러올때 ${dto.content} 이런식으로 불러오는데

 아무리 짱구를 굴려봐도 <%= utils.getContent( ${dto.content} )%> 이런식으로 쓸 수 가 없었다.

그래서 custom el function을 만들기로 했다 (처음엔 1시간이면 만들줄 알았지....)



solution: (아래)


1.먼저 Util파일을 만든다 (이 유틸은 디비에서 글을 불러올때 엔터를 <br>로 대입해주는 유틸이다)

주의점: 만약 bean을 사용하면 메소드를 static으로 선언해줄 필요가 없지만, 우리는 custom el funtion을 만들어야 하기때문에 무조건 static으로 만들어야한다

ContentForm.java

Java 0.56 KB
  1. public class ContentForm {
  2.     public static String getContent(String comment) {
  3.         return br(" ""<br>", comment);
  4.     }
  5.  
  6.     public static String br(String first, String brTag, String comment) {
  7.         StringBuffer buffer = new StringBuffer();
  8.         StringTokenizer st = new StringTokenizer(comment, "\n");
  9.         int count = st.countTokens();
  10.         buffer.append(first);
  11.         int i = 1;
  12.         while (st.hasMoreTokens()) {
  13.             if (== count) {
  14.                 buffer.append(st.nextToken());
  15.             } else {
  16.                 buffer.append(st.nextToken() + brTag);
  17.             }
  18.             i++;
  19.         }
  20.         return buffer.toString();
  21.     }
  22. }


2.tld 파일을 만들어준다

el-funtion.tld

XML 0.82 KB
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2.  
  3. <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  5.    version="2.0">
  6.  
  7.     <description>CommonUtil functions library</description>
  8.     <display-name>CommonUtil functions</display-name>
  9.     <tlib-version>1.1</tlib-version>
  10.     <short-name>mobizaUtil</short-name>
  11.     <uri>tld/el-funtion.tld</uri>
  12.  
  13.     <function>
  14.         <description>글내용 엔터 등, 줄바꿈 인식하게하기</description>
  15.         <name>getContent</name>
  16.         <function-class>경로.ContentForm</function-class>
  17.         <function-signature>java.lang.String getContent(java.lang.String)</function-signature>
  18.     </function>
  19. </taglib>


3. web.xml에 uri와 tld 파일 경로를 맵핑시켜준다 (생략가능)

web.xml

XML 0.25 KB
  1.     <!-- Custom UL TAG을 쓰기위함이다 -->
  2.     <jsp-config>
  3.         <taglib>
  4.             <taglib-uri>
  5.               tld/el-funtion.tld
  6.             </taglib-uri>
  7.             <taglib-location>
  8.              {프로젝트상 실제경로}/el-function.tld
  9.             </taglib-location>
  10.         </taglib>
  11.     </jsp-config>


4.jsp 페이지 내에서 사용예

만약 web.xml에서 맵핑을 하지 않는다면

<%@ taglib uri="WEB-INF/tld/el-funtion.tld" prefix="moutil" %>

이런식으로 실제 파일이 위치한 경로를 맵핑시켜주어도 무방하다.

ex.jsp

  1. HTML 0.12 KB
  1. <%@ taglib uri="tld/el-funtion.tld" prefix="moutil" %>
  2.  
  3.  
  4. <body>
  5.     내용:${moutil:getContent(dto.bContent) }
  6. <body>


Scenario: Instargram 에서 처럼 파일 업로드 메뉴이미지만 누르면 파일첨부 창이뜨고 내이미지를 첨부할려고했다


Solutions:(아래)

myprofile.jsp (html코드 생략)

jQuery 0.98 KB
  1. $(function() {
  2.     //이미지 클릭시 업로드창 실행
  3.     $('#profile_file_add').click(function() {
  4.         console.log('fileadd');
  5.         $("input[name='fileProfile']").click();
  6.        
  7.     })
  8.     //업로드 파일체인지가 됬을경우 실행되는 이벤트  form태그에 fileProfile은 hidden으로 넣어줌
  9.     $("input[name='fileProfile']").change(function(e){
  10.        
  11.         $( "#frm_profile_img" ).submit();
  12.         $("input[name='fileProfile']").val();
  13.         var frm = document.getElementById('profile_file_add');
  14.         frm.method = 'POST';
  15.         frm.enctype = 'multipart/form-data';
  16.         var fileData = new FormData(frm);
  17.      
  18.         // ajax
  19.         $.ajax({
  20.             type:'POST',
  21.             url:'/BoardProject/profileUpdate.ref',
  22.             data:fileData,
  23.             processData: false,
  24.             contentType: false,
  25.             success : function(data, textStatus, xhr) {
  26.                 console.log('success');
  27.             },
  28.             error : function(request,status,error) {  
  29.                alert("code:"+request.status+"\n"+"error:"+error);
  30.             }
  31.         });
  32.     })
  33. })



service 영역.java

Java 1.25 KB
  1. public class ProfileUploadCommand implements BoardCommand {
  2.  
  3.     @Override
  4.     public void execute(HttpServletRequest request, HttpServletResponse response) {
  5.         DAO dao = new DAO();
  6.         HttpSession session = request.getSession();
  7.         String mid=(String)session.getAttribute("mid");
  8.         String contents ="";
  9.         String fileName = "";
  10.         //String profimg = ""; //프로필 이미지
  11.         //**************** File 추가부분****************//
  12.         String pathname = "C:\\dev\\profile";
  13.         File f = new File(pathname);
  14.         if (!f.exists()) {
  15.             // 폴더가 존재하지 않으면 폴더 생성
  16.             f.mkdirs();
  17.         }
  18.         String encType = "UTF-8";
  19.         int maxFilesize = 5 * 1024 * 1024;
  20.  
  21.         // MultipartRequest(request, 저장경로[, 최대허용크기, 인코딩케릭터셋, 동일한 파일명 보호 여부])
  22.         try {
  23.             MultipartRequest mr = new MultipartRequest(request, pathname, maxFilesize, encType, new DefaultFileRenamePolicy());
  24.             fileName = mr.getFilesystemName("fileProfile");
  25.             System.out.println("upload profile mid@@@@@@"+mid);
  26.             System.out.println("upload profile filename@@@@@@"+fileName);
  27.         } catch (IOException e) {
  28.             e.printStackTrace();
  29.         }
  30.         dao.profileUpdate(mid, fileName);
  31.     }
  32.  
  33. }



-----------------------------------------------보너스---------------------------------------------------------

Scenario: db와의통신 없이 내가 첨부한 이미지를 미리보기 할 수 있는기능 추가


Solutions: 아래

파일첨부 폼.html

HTML 5 0.25 KB
  1.     <form  action="write.ref" method="post" enctype="multipart/form-data">
  2.         <input type="file" name="files">
  3.         <div id="holder"></div>
  4.         <textarea rows="5" cols="100" name="contents"></textarea><br>
  5.         <input type="submit" value="글쓰기">
  6.     </form>



  1. <script>
  2. $("input[name='profile_img']").change(function(e){
  3.     e.preventDefault();
  4.  
  5.     var file = this.files[0];
  6.         reader = new FileReader();
  7.    
  8.     reader.onload = function (event) {
  9.         var img = new Image();
  10.         img.src = event.target.result;
  11.         if (img.width > 700 || img.height > 500) { // holder width
  12.           img.width = 700;
  13.           img.height = 500;
  14.         }
  15.         $('#holder').empty();
  16.         $('#holder').append(img);
  17.     };
  18.     reader.readAsDataURL(file);
  19.    
  20.     return false;
  21. });
  22. </script>
  23.  
  24. <!-- 2. DY가 짠 첨부파일 미리보기 소스-->

  25. <script>
  26. var upload = document.getElementsByTagName('input')[0],
  27.     holder = document.getElementById('holder');
  28.  
  29. upload.onchange = function (e) {
  30.     e.preventDefault();
  31.    
  32.     var file = upload.files[0],
  33.         reader = new FileReader();
  34.    
  35.    
  36.     reader.onload = function (event) {
  37.         var img = new Image();
  38.         img.src = event.target.result;
  39.         if (img.width > 700 || img.height > 500) { // holder width
  40.           img.width = 700;
  41.           img.height = 500;
  42.         }
  43.         holder.innerHTML = '';
  44.         holder.appendChild(img);
  45.     };
  46.     reader.readAsDataURL(file);
  47.    
  48.     return false;
  49. };
  50. </script>


+ Recent posts