Programing
OS X에서 JDK7 사용할 때 한글 파일명 처리 오류
OS X에서 간단하게 코딩 테스트중이었는데
파일에 대한 접근이 계속 에러가 나서 내가 무언가 잘못 해서 그런가 보다 하고
열심히 삽질을 했다,,,
아무리 해도 안 돼서 혹시 파일명이 한글인가 싶어서 파일명을 영어로 수정했더니,,,
잘된다,,,
아무래도 내 환경 문제인 것 같아서 열심히 구글링을 했는데 몇몇 포스트들이 있었다.
JDK6 까지는 이상 없는 것 같고 JDK7에서만 발생하는 문제인 것 같다.
“JDK 1.6까지는 이클립스를 실행 시킬 때 LC_CTYPE 를 정상적으로 지정하고 실행되는데
JDK 1.7에서는 LC_CTYPE를 지정하지 않고 이클립스가 실행됩니다.”
난 intelliJ라서 될까 해서 시도했는데 상관없이 정상적으로 동작했다.
하위 코드를 시스템 설정에 추가해준다.
1 2 3 4 | sudo vi 본인사용자 경로/.bash_profile // 해당 파일을 vi로 열어서 하위 명령어 추가 export LC_CTYPE=ko_KR.UTF-8 export _JAVA_OPTIONS=-Dfile.encoding=UTF-8 |
1 2 3 4 | sudo vi /etc/launchd.conf // 해당 파일을 vi로 열어서 하위 명령어 추가 setenv LC_CTYPE ko_KR.UTF-8 setenv _JAVA_OPTIONS -Dfile.encoding=UTF-8 |
상위 설정을 해주고 intelliJ 재시작 후 다시 실행하니 동작~!
JAVA Interface, Abstract
최범균님의 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴을 보고 느낀건,,,
첫번째 역시나 내가 너무 생각없이 일했구나,,,
두번째 예전에 객체 지향, 디자인 패턴 책을 보았을 때 느낌과는 상당히 틀리구나,,,
셋째 Interface, Abstract 정의
넷째 좌절 또 좌절,,,
어찌되었건,,,
Java에는 Interface란 놈과 Abstract란 놈이 있다.
Interface 정의
– 골격만 가지고 있는 클래스
– 몸체 없는 메서드(추상 메서드)로만 이루어진 클래스
1 2 3 4 5 6 7 8 9 10 11 12 | public interface IRemoteControl{ void powerOn(); //추상 메서드 void powerOff(); //추상 메서드 void channelUp(); //추상 메서드 void channelDown(); //추상 메서드 /* public abstract void powerOn(); //추상 메서드 public abstract void powerOff(); //추상 메서드 public abstract void channelUp(); //추상 메서드 public abstract void channelDown(); //추상 메서드 */ } |
Interface 특징
– 메서드들은 abstract 메서드이기 때문에 abstract 생략 (public abstract)
– 메서드들은 구현 목적이기에 default public 속성 (일반 클래스는 default private)
– abstract 메서드를 포함하고 있기 때문에 객체 생성 불가
Interface 주의사항
– 인터페이스도 클래스의 한 종류이다.
– Interface 메서드를 모두 구현하지 않으면 Abstract가 된다.(모두 구현해야만 객체 생성 가능)
Abstract 정의
– 골격만 가지고 있는 클래스(불완전)
– 몸체 없는 메서드(추상 메서드)로만 이루어진 클래스
– 추상 메서드를 하나라도 포함하고 있으면 추상 클래스
1 2 3 4 5 | public abstract class Test{ //추상 클래스를 포함 클래스 public void sayHello(){ } // 일반 메서드 public void sayHi(){ } // 일반 메서드 public void sayHowareyou(); //몸체 없는 메서드 - 추상 메서드 } |
Abstract 특징
– 메서드, 클래스 선언부 abstract 키워드 사용
– 미완성 클래스이기 때문에 자체적(Abstract를 이용해서)으로 절대 객체 생성 출가
– 하위 클래스(extends 받은 class)에서는 상위 클래스의 추상 메서드를 하나도 빼지 말고 전부 구현해야 한다.
– Abstract를 상속한 후 추상 메서드를 하나라도 남겨 두었다면 그 자체도 Abstract가 된다.
– 상속을 통해서 추상 메서드를 전부 구현해야만 객체 생성 가능
– Abstract는 메서드의 프로토타입(Prototype)만 가지고 있다.
– 클래스 구조 잡기 위한 방법으로 사용
– 일반 클래스에 abstract 키워드 사용으로 Abstract 구현시 상속 자체만으로 완전한 클래스가 된다.
– 추상 메서드를 포함하지 않는 Abstract를 사용하는 이유(Abstract를 무조건 상속받도록 하기 위해서)
1 2 3 4 5 6 7 | /** 추상 클래스 - 2개의 추상 메서드를 포함한 추상 클래스의 예 **/ public abstract class EmptyCan { public abstract void printContent(); //추상 메서드 public abstract void printName(); //추상 메서드 } |
1 2 3 4 5 6 7 8 9 | /** 추상의 추상 - 추상 클래스의 메서드를 모두 구현하지 않은 예 **/ public abstract class InCompleteCan extends EmptyCan{ //EmptyCan의 printName() 구현 public void printName() { System.out.println("InCompleteCan에서 printName() 구현"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** 모든 추상 메서드의 구현 InCompleteCan에 남아 있던 모든 추상 메서드를 구현한 후 객체를 생성하는 예 **/ public class CompleteCan extends InCompleteCan { public void printContent(){//EmptyCan의 printContent() 구현 System.out.println("CompleteCan에서 printContent() 구현"); } public void sayHello() {//새로운 멤버 메서드 추가 System.out.println("CompleteCan에서 sayHello() 추가 구현"); } public static void main(String args[]) { CompleteCan cc = new CompleteCan(); //객체 생성 cc.printName(); cc.printContent(); cc.sayHello(); } } |
– Abstract EmptyCan는 두개의 추상 메서드를 가지고 있는데 상속받은 InCompleteCan 클래스에서 한개의 추상 메서드만 구현하였기 때문에 InCompleteCan 클래스 또한 Abstract가 된다. 그리고 InCompleteCan 클래스를 상속받은 CompleteCan에서 남은 추상 메서드를 구현했기 때문에 완전한 클래스가 되어서 객체 생성이 가능한다. InCompleteCan 클래스에서 한개의 추상 메서드만 구현하였지만 상속받은 InCompleteCan 클래스에서 구현한 추상 메서드 또한 실행가능
Abstract 주의사항
– 인터페이스도 클래스의 한 종류이다.
– Interface 메서드를 모두 구현하지 않으면 Abstract가 된다.(모두 구현해야만 객체 생성 가능)
Abstract와 Interface
– Abstract는 클래스의 일부분이 추상 메서드이다.
– Interface는 추상 메서드로만 이루어져 있다.
Abstract와 Interface 2
– 일반 클래스, Abstract는 extends를 이용해서 추상 메서드를 구현(상속)한다.
– Interface는 implements를 이용해서 추상 메서드를 구현(확장)한다.
찾아본 링크들 정리
http://www.okjsp.net/seq/235733
http://okjsp.net/bbs?seq=56298
http://okjsp.net/bbs?seq=133632
http://okjsp.net/bbs?seq=106693
http://okjsp.net/bbs?seq=114903
http://www.okjsp.net/bbs?seq=114923
http://silverktk.tistory.com/134
http://blog.naver.com/PostView.nhn?blogId=rkqnrdlrns&logNo=10177633885
http://iamreo.tistory.com/entry/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%B0%A8%EC%9D%B42
http://chester777.tistory.com/150
facebook sdk 회원정보 연동 예제
일전에 facebook sdk 연동 작업할때 작성해둔 예제인데,,,
결국 제품 오픈은 올해로 미뤄져서 묻혀버린 코드가,,,
오늘 지인과 이야기 하다가 필요하단 이야기를 듣고 문뜩 생각나서 정리해둔다,,,
작년 꽤나 삽질했던 기억이 있는데,,,지금도 동작할지는 모르겠다,,,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <script language="javascript"> // 페이스북 SDK 초기화 window.fbAsyncInit = function () { FB.init({ appId: '' // Website with Facebook Login 사이트 : 일단 test 용으로 용퓌 계정상에서 app 생성 , status: true // check login status , cookie: true // enable cookies to allow the server to access the session , xfbml: true // parse XFBML //,oauth: true }); }; // 페이스북 SDK(js) 로딩 (페이지 로딩 속도 향상을 위해 사용) (function (d) { var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; if (d.getElementById(id)) { return; } js = d.createElement('script'); js.id = id; js.async = true; //js.src = "//connect.facebook.net/en_US/all.js"; js.src = "http://connect.facebook.net/ko_KR/all.js"; ref.parentNode.insertBefore(js, ref); }(document)); // 페이스북 계정으로 회원 가입 function facebookRegist() { // 페이스북 로그인 상태 체크 FB.getLoginStatus(function (response) { if (response.status == "connected") { // 페이스북 로그인 YES! and 앱 허가 YES! handleFacebookRegist(response); } else if (response.status == "not_authorized") { // 페이스북 로그인 YES! but 앱 허가 NO! FB.login(function (response) { handleFacebookRegist(response); }, {scope: 'publish_stream, email, user_birthday, user_likes, publish_actions, read_stream'}); } else { // 페이스북 로그아웃 상태. FB.login(function (response) { handleFacebookRegist(response); }, {scope: 'publish_stream, email, user_birthday, user_likes, publish_actions, read_stream'}); } }); } // 회원가입 핸들러 function handleFacebookRegist(response) { var accessToken = response.authResponse.accessToken; var userId, userName, fbId, userBirth; FB.api('/me', function (user) { userId = user.email; // 페이스북 email userName = user.name; // 페이스북 name fbId = user.id; // 페이스북 id userBirth = user.birthday; // 페이스북 생일 : mm/dd/yyyy alert(userId); alert(userName); alert(userBirth); $('input[name=fbAccessToken]').val(accessToken); return; $.ajax({ type: "post", url: "ajax 로 호출할 url", dataType: "jsonp", jsonp: "callback", data: { userId: userId }, beforeSend: function () { $('#ajax_load_indicator').fadeIn('fast'); }, success: function (data) { if (data.result == true) { alert("이미 가입이 되어있습니다."); return; } else { if (confirm("Facebook 계정으로 가입하시겠습니까?\n\rFacebook 계정으로 가입시 추가정보를 입력하셔야 합니다.")) { //var $form = $("<form></form>"); //$form.attr("action","페이스북에서 받은 정보를 post로 넘길 url"); //$form.attr("method","post"); //$form.appendTo("body"); //$form.append("<input type="hidden" name="userName" value=""+ userName +"">"); //$form.append("<input type="hidden" name="userId" value=""+ userId +"">"); //$form.append("<input type="hidden" name="fbId" value=""+ fbId +"">"); //$form.append("<input type="hidden" name="userBirth" value=""+ userBirth +"">"); // mm/dd/yyyy 형식으로 받음.(짤라서 쓰던가 하믄 됨.) //$form.submit(); } return; } }, error: function (data, status, err) { alert("서버와의 통신이 실패했습니다."); alert(err) return; }, complete: function () { $('#ajax_load_indicator').fadeOut(); } }); }); } function fbNesFeedPost(){ //자동 포스팅 시키기 FB.api('/me/feed','post', { //method: 'feed', //feed 로 올림 //name: '테스트', // 링크가 걸리는 이름 //link: '클릭하면 넘어갈 주소', // 링크 주소 //picture: '사진 주소', // 사진 //caption: 'caption', // //description: 'description', // 컨텐츠 message: '연동테스트' // 텍스트박스 안의 글자 }, function(response){ if(!response || response.error){ FB.login(function(response) { // 자동 글 등록 실패시 권한 부여하는 창을 띄움 Log.info('FB.login callback', response); if (response.status === 'connected') {Log.info('User is logged in');} else {Log.info('User is logged out');} }, {scope: 'read_stream,publish_stream'} ); //alert("facebook 권한 허가를 누르신 후 \n다시 눌러주십시오."); }else{ alert("글 등록 성공"); //자동 글 등록 성공시 } }); } </script> </head> <body> <form name="fbForm" method="post"> <input type="text" name="fbAccessToken" value=""> <input type="button" value="Facebook 연동" onclick="facebookRegist();"> <input type="button" value="Facebook newsfeed연동" onclick="fbNesFeedPost();"> <input type="text" name="message"> </form> </body> </html> |
OS X Server에서 MySQL 과 PHP 연동 관련 해결
컴퓨터 정리를 하다가 실수로 OS X Server를 삭제 하게 되었는데,,,
삽질해가며 세팅하였던 블로그가 순식간에 날아가서 다시 세팅하였다.
- os x server 재설치
- server appliaction 에서 블로그 주소 세팅 및 PHP 웹 응용프로그램 활성화
- DB는 영향 없으니 블로그 접속 시도
그런데,,,
데이터베이스에 연결하는데 오류가 생겼습니다.
일전에 초기 세팅할 때에도 재설치 시 그런 문제가 있어서 MySQL DB와 User를 모두 날린 후 재설치 시 해결하였는데
이번에는 얼마 전에 근 한 달간을 삽질해서 세팅한 페북 플러그인과 설정들을 살려보겠다는 생각에 열심히 구글링을 하였다.
꽤 삽질을 하였다. PHP 소스에 문제가 있나 싶어서
1 2 3 4 5 6 7 8 9 10 | $db_host = "localhost"; $db_user = "test_user"; $db_passwd = "test_passwd"; $db_name = "test_name"; $conn = mysqli_connect($db_host,$db_user,$db_passwd,$db_name); if (mysqli_connect_errno($conn)) { echo "데이터베이스 연결 실패: " . mysqli_connect_error(); } else { echo "성공~!!!"; } |
상위처럼 test도 해봤다. 그런데 안된다,,,
머가 잘못일까 삽질하다 보니 default port라 인식할 거라 생각했는데 3306을 빼먹어서 연결이 안 된 상황,,,
일단 DB 연결이 되는 것을 확인한 후 다른 환경 문제일 거라 생각하고 다시 구글링,,,
그런 중 MySQL과 PHP 연동 관련된 두 가지 해결 방법을 찾았다.
첫 번째 해결방법
문제
MySQL 서버가 동작 중일 때, tmp/mysql.sock 파일이 생성된다.
그런데 PHP 설정이 var/mysql/mysql.sock 으로 되어 있어서 PHP에서 MySQL 접속이 불가능한 경우가 있다.
해결
/etc/php.ini.default 파일에서 var/mysql/mysql.sock 로 되어 있는 부분(세 군데)을 전부 tmp/mysql.sock으로 변경.
그리고 다음과 같이 php.ini 파일을 생성.
1 2 3 4 5 | cd /var sudo mkdir mysql sudo chmod 755 mysql cd mysql ln -s /tmp/mysql.sock mysql.sock |
또는
1 2 | cd /tmp ln -s /var/mysql/mysql.sock mysql.sock |
두가지 방법을 보니 문제점은 MySQL과 PHP 연동 간에 설정 부분이 문제가 있는 것으로 확인된다.
나는 두 번째 방법은 무언가 폴더를 더 생성하고 예외를 두는 것 같아서 첫 번째 php.ini 파일의 mysql.sock 의 경로명을 수정하였다.
jquery .attr() .prod() 차이
현재 운영 중인 시스템이 오래되다 보니 jquery를 정책상 사용하고 있지 않다. (물론 군데군데 쓰인 곳은 있음)
운영 정책을 지키는 편이어서 사용 안 하고 있었는데 얼마 전 jquery 기반 editor를 사용한 page 작업 중 뇌가 다시 쫀쫀해 졌다.
기존에 내가 알고 있던 속성에 대한 핸들링은 거의 .attr()을 사용하였다.
jquery 둘러보던 중에 .attr() .prod() 가 1.6버전부터 구분되어서 사용되고 있다는걸 이제 보았다. (반성하자,,,)
1.6 이전까지는 속성(attribute)과 프로퍼티(property)를 같이 사용하였지만 이후부터는 명시적으로 구분해서 사용한다.
Code | Description(return) |
elem.checked | true (Boolean) Will change with checkbox state |
$( elem ).prop( “checked” ) | true (Boolean) Will change with checkbox state |
elem.getAttribute( “checked” ) | “checked” (String) Initial state of the checkbox; does not change |
$( elem ).attr( “checked” ) (1.6) | “checked” (String) Initial state of the checkbox; does not change |
$( elem ).attr( “checked” ) (1.6.1+) | “checked” (String) Will change with checkbox state |
$( elem ).attr( “checked” ) (pre-1.6) | true (Boolean) Changed with checkbox state |
1 2 3 4 5 6 7 8 9 10 11 | <input type="checkbox" name="agreement" /> <a id="test" href="test2">주소</a> <script type="text/javascript"> alert($('[name=agreement]').prop('checked')); // true or false alert($('[name=agreement]').attr('checked')); // checked or undefined var link = $('#test'); alert(link.attr('href')); // test2 alert(link.prop('href')); // http://localhost(절대주소)/test2 </script> |
상위 코드 처럼 두개의 결과값은 다르게 나타난다.
이 두개의 메소드는 취급하는 정보가 다르다.
.attr()는HTML의 속성(attribute)을 .prop()는 JavaScript의 프로파티(property)를 취급하는 메소드이다.
그냥 “되네~!” 하고 넘어갔던 내용인데,,, 오늘도 다시 한번 반성하자.
IIS Network Drive 파일 쓰기
최근 작업 중에 이미지 에디터의 파일 생성 작업을 진행하였다.
TEST 서버는 IIS에서 D 드라이브로 작성하여 아무런 이슈가 없었는데
운영 서버 반영 이후 파일생성 시 30초가량의 시간이 소요되는 현상이 발생 되었다.
일단 타임 체크를 해보았는데 역시나 리쿼스트, 쿼리 등 모든 작업은 정상이었는데
파일 생성 시 시간이 오래 걸리는 이슈였다.
jquery 기반의 php 이미지 에디터였는데 php 내부에서도 network drive를 인식 하지 못하는 이슈도 발생
고난의 연속이었다.
1. php 에서 접근하는 경로를 k:/devenjoy/test 형식으로 되어 있던 경로를
//devenjoy.com/test 형식으로 바꿔주니 정상적으로 파일 경로는 찾을 수 있었음
2. 이미지 파일 생성 부분은 기존에는 network drive에 직접 라이트 하는 방식을 사용하였다.
1 2 3 4 5 6 7 8 9 10 11 | File tempFile = new File("k:/devenjoy/test/test.jpg"); FileOutputStream fos = new FileOutputStream( tempFile ); int chunk = 0; InputStream gifdata = result.getBinaryStream("photo_img"); while ((chunk = gifdata.read()) != -1) { fos.write(chunk); } // flush the data fos.flush(); fos.close(); |
상위 방법에서 k 드라이브의 network drive 대신 IIS의 로컬 드라이브로 바꾼후
network drive로 파일 이동 처리하니 0초에 처리
1 2 3 4 |
이렇게 삽질을 끝냈다.
linux 나 다른 OS상에서도 발생할지 모르지만 삽질할 때 짜증은 났지만 차후를 위한 유익한 경험이었다.
PHP 문자열 대소문자 변환
어쩌다 보니 최근 들어서 PHP를 사용하게 되었는데
하나씩 검색해가며 적용하는 중인데 찾아본 놈들은 정리해야겠다.
무엇보다 블로그에 정보를 올리면서 퍼가지 못하게 하신 분들이 너무 많아서
당최 이해가 가지 않아서 내 공간에 남겨야겠다는 생각이 문뜩 들었다.
1 2 3 4 5 | $str = "Hellow World"; $lowerStr = strtolower($str); echo $lowerStr; // hellow world $upperStr = strtoupper($str); echo $upperStr; // HELLOW World |