본문으로 건너뛰기

org.apache.ibatis.exceptions.PersistenceException

· 약 1분

원인​

서버 Mysql이 예전 커넥션을 그대로 가지고 있어서 발생한다.

해결​

Mybatis Config에 아래처럼 커넥션과 관련된 옵션을 추가한다.

<!-- @author http://linuxism.tistory.com/580 -->
<environments default="default">
<environment id="default">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

<!-- 동시 커넥션 수 -->
<property name="poolMaximumActiveConnections" value="20"/>
<!-- 유휴상태의 커넥션 수 -->
<property name="poolMaximumIdleConnections" value="20"/>
<!-- 커넥션 요청 후 획득까지 기다리는 시간 -->
<property name="poolMaximumCheckoutTime" value="20000"/>
<!-- 커넥션 ping 테스트 -->
<property name="poolPingEnabled" value="true"/>
<!-- 커넥션 확인 쿼리 -->
<property name="poolPingQuery" value="select 1"/>
<!-- 커넥션이 얼마동안 사용하지 않으면 닫히는지 시간 설정 -->
<property name="poolPingConnectionsNotUsedFor" value="43200"/>
<!-- 사용불가능한 커넥션을 기다리는 시간 설정 -->
<property name="poolTimeToWait" value="30000"/>
<!-- 인코딩 -->
<property name="driver.encoding" value="UTF-8"/>
</dataSource>
</environment>
</environments>

java localhost HTTPS Connection

· 약 1분

localhost 에서 Https 페이지로 httpcon 을 열면 오류가 발생한다. 인증을 받아야하기 때문인데 함수하나만 호출하면 연결이 가능해진다.

소스​

private void setTrustAllCerts() throws Exception{
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType ) {}
public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType ) {}
}
};

// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance( "SSL" );
sc.init( null, trustAllCerts, new java.security.SecureRandom() );
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(
new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
});
}
catch (Exception e) {
//We can not recover from this exception.
e.printStackTrace();
}
}

원본에서 가져왔다.

예제​

HTTPCON 전에 호출하면 인증서 없이 HTTPS 연결이 가능하다.

Google Cloud Instance 무료 사용

· 약 2분

구글 클라우드 인스턴스를 생성해 무료 서버를 만들어보자.

프로젝트 생성​

구글 클라우드 플랫폼에 로그인해 프로젝트 만들기 버튼을 클릭해 프로젝트를 생성한다. image from hexo

클라우드 서버 생성​

좌측 메뉴 > Compute Engine > VM 인스턴스 메뉴에서 인스턴스 만들기 버튼을 클릭해 인스턴스를 생성한다. image from hexo

인스턴스 생성​

이름은 하고싶은 이름으로 영역은 한국이니 아시아 데이터센터로 설정하고 머신 유형은 테스트용이니 초소형 공유 CPU를 사용하면 된다.

US 데이터 센터, 공유 CPU, **HDD 30GB↓**를 선택한다면 평생 무료로 바뀌었다. Free Tier 페이지에서 정책을 확인할 수 있다.

이미지에 원하는 OS 를 선택하면 되는데, CentOS 가 막강하니 선택해주자. 액세스 범위 영역에서 모든 Cloud API 액세스 허용을 해줘야 구글 내부 API 를 사용할 수 있다. image from hexo

돈이 나간다고 하는데 이미 무료 $300 이 있고, 6 개월간은 무료다. 기본 상품을 업그레이드 하지 않으면 과금이 발생하지 않는다.

SSH KEY 생성​

직접 생성​

ssh 접근을 위해 Git-bash 창을 열어 구글 계정으로 키를 생성한다.

ssh-keygen -t rsa -C "your google [email protected]"

Putty 로 생성​

PuTTY Key Generator를 여기서 다운로드 받고 키를 생성한다. image from hexo Key Comment에 구글 계정을 넣어주고 Generate한 뒤 Key 를 추출하자

SSH Public KEY 등록​

키 복사​

유저 디렉토리의 .ssh 폴더로 이동해 공개 키 파일(.pub) 데이터를 복사하고 등록한다.

등록​

메타데이터 메뉴에서 등록할 수 있다. image from hexo

SSH Private KEY 등록​

각자 사용하는 쉘 프로그램에 Private Key 를 저장하는 기능이 있을 것이다. image from hexo Token2Shell 을 이용해 등록 후 접속한 화면

서버 세팅​

yum 등의 root 명령어를 사용할 때는 sudo 를 붙혀주고 명령어를 입력하면 된다. yum update 를 먼저 실행해보자

sudo yum update

.NET에서 MySQL 사용자 변수 사용

· 약 1분

@value, @reg 같은 사용자 변수가 들어간 쿼리에서 오류가 발생한다.

해결​

Connection을 맺을 때 Allow User Variables=True 옵션을 추가해줘야한다.

string conf = "Server=$Server;Port=$port;Database=$DataBase;Uid=$User;Pwd=$Password;Allow User Variables=True";

C# String Split

· 약 1분

javascript 의 split 을 생각하고 split 을 사용했다간 예상치 못한 오류를 맞게된다.

원인​

일반 Split 함수는 Char 로만(한 글자로만) 자를 수 있다.

해결​

string str = "cat__dog__animal__person";
string[] animals = Regex.Split(str, "__");

Regex.Split 을 사용하면 된다.

C# MySQL Singleton DB Connection

· 약 1분

소스​

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;

namespace WebApplication.ClassFolder{

public class DBConfig{
private static string Server = "";
private static string Database = "";
private static string ID = "";
private static string PASS = "";

static string conf = "Server=" + Server + ";Database=" + Database + ";Uid=" + ID + ";Pwd=" + PASS;

static MySqlConnection db;

public static MySqlConnection Connection{
get{
if (db == null){
LazyInitializer.EnsureInitialized(ref db, CreateConnection);
}
return db;
}
}

static MySqlConnection CreateConnection(){
var db = new MySqlConnection(conf);

db.Open();
return db;
}

// 강제로 커넥션을 끊어야될 경우가 있을 때
static void CloseConnection(){
if(db != null) {
db.Close();
db.Dispose();
db = null;
}
}

}
}

예제​

// get Connection
var db = DBConfig.Connection;

.NET targetFramework 오류

· 약 1분

targetFramework가 인식할 수 없다고 페이지가 안 띄워지는 경우가 있다.

원인​

IIS의 .NET버전과 프로젝트의 .NET버전이 달라 발생한다. image from hexo

해결​

IIS > 응용프로그램 풀 > 내 프로젝트 클릭 > 기본설정 메뉴에서 .NET Framework 버전 속성을 변경해준다. image from hexo

D3 Word Cloud

· 약 2분

d3 와 d3-cloud 를 사용해 R 의 Word Cloud 를 javascript 로 구현해보자.

설치​

## npm
$ npm install d3
$ npm install d3.layout.cloud
## bower
$ bower install d3
$ bower install d3-cloud

예제​

소스​

<script src="/bower_components/d3/d3.min.js"></script>
<script src="/bower_components/d3-cloud/build/d3.layout.cloud.js"></script>

<script>
var fill = function (i) {
return d3.schemeCategory20b[i];
};
var layout = d3.layout
.cloud()
.size([500, 500])
.words(
[
"텍스트",
"마이닝",
"샘플",
"좋아요",
"R",
"Word",
"Cloud",
"text",
"mining",
].map(function (d) {
return { text: d, size: 10 + Math.random() * 90, test: "haha" };
}),
)
.padding(5)
.rotate(function () {
return ~~(Math.random() * 2) * 90;
})
.font("Impact")
.fontSize(function (d) {
return d.size;
})
.on("end", draw);

layout.start();

function draw(words) {
d3.select("body")
.append("svg")
.attr("width", layout.size()[0])
.attr("height", layout.size()[1])
.append("g")
.attr(
"transform",
"translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")",
)
.selectAll("text")
.data(words)
.enter()
.append("text")
.style("font-size", function (d) {
return d.size + "px";
})
.style("font-family", "Impact")
.style("fill", function (d, i) {
return fill(i);
})
.attr("text-anchor", "middle")
.attr("transform", function (d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function (d) {
return d.text;
});
}
</script>

d3-cloud의 예제소스는 nodejs 환경에서만 돌릴 수 있어 모든 웹에서 예제를 사용할 수 있게 수정했다.

결과​

image from hexo

Facebook Graph API를 활용한 Page 글쓰기

· 약 2분

페이스북 모듈 연동​

window.fbAsyncInit = function () {
FB.init({
appId: "앱 키",
xfbml: true,
version: "v2.8",
});
};
(function (d, s, id) {
let js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
})(document, "script", "facebook-jssdk");

Page 권한 얻기 (선택)​

앱공개를 한 뒤 페이스북 개발자 > 앱 검수 에서 publish_pages, manage_pages 권한을 부여해야한다.

FB.login(
function (login_result) {
if (login_result.status === "connected") {
// 여기에 3번 로직을 넣으면 된다.
} else if (login_result.status === "not_authorized") {
alert("페이스북 인증에 실패했습니다");
} else {
alert("페이스북 API 호출에 실패했습니다");
}
},
{ scope: "publish_pages,manage_pages" },
);
// 이 두 권한이 꼭 필요하다

해당 Page 관리자 권한 얻기​

페이지 아이디가 필요한데, 내 페이지로 이동하면 뒤에보이는 주소 번호가 있다. 또는 페이지 아이디를 여기서 주소로 검색해보자

FB.api(
"/나의 페이지 아이디/",
"GET",
{ fields: "access_token" },
function (token_result) {
// token_result.access_token 이 페이지 관리자로 글을 쓰기 위해 필요하다
// 여기에 4번 로직을 넣으면 된다.
},
);

Page Feed 작성​

Graph API 를 사용해 피드를 작성한다. 자세한 옵션 설정은 API 문서를 참조하자.

FB.api(
"/my page id/feed",
"POST",
{
access_token: token_result.access_token,
message: "내용",
link: "링크 걸 주소",
picture: "링크 이미지",
name: "링크 제목",
description: "링크 설명",
caption: "링크 하단 캡션",
},
function (page_result) {
if (page_result && !page_result.error) {
// 여기에 성공시 로직을 넣는다.
}
},
);

소스​

FB.login(
function (login_result) {
if (login_result.status === "connected") {
getFbAccessToken();
} else if (login_result.status === "not_authorized") {
alert("페이스북 인증에 실패했습니다");
} else {
alert("페이스북 API 호출에 실패했습니다");
}
},
{ scope: "publish_pages,manage_pages" },
);

function getFbAccessToken() {
FB.api(
"/나의 페이지 아이디/",
"GET",
{ fields: "access_token" },
function (token_result) {
postFbPage(token_result);
},
);
}

function postFbPage(token_result) {
FB.api(
"/나의 페이지 아이디/feed",
"POST",
{
access_token: token_result.access_token,
message: "내용",
link: "링크 걸 주소",
picture: "링크 이미지",
name: "링크 제목",
description: "링크 설명",
caption: "링크 하단 캡션",
},
function (page_result) {
if (page_result && !page_result.error) {
alert("성공");
}
},
);
}

여담​

OAuth 및 RESTful 의 개념이 잡혔다면 쉽게 접근할 수 있을듯 Graph API 로 모든 페이스북 API 이용이 가능한 것 같다.