Jenkins 설치 및 구동하기
sudo service jenkins start
# 또는 기본 포트 변경하고 구동
sudo vi /etc/default/jenkins
HTTP_PORT=8080
# 또는 기본 포트 변경하고 구동
sudo vi /etc/default/jenkins
HTTP_PORT=8080
호출할 페이지 또는 참고하는 파일의 위치를 path를 절대 경로로 주는 경우에
contextpath가 변경될 수도 있다는 가정하에..
직접적으로 명시하지 않고 request 객체에 저장된 contextpath를 참조하여 경로 명시하는 방법
<!-- c:set 이거 쓰려면 명시해줘야한다. jstl 라이브러리 다운받아서 WEB-INF/lib 에 넣어줘야함. --> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!-- contextpath 가져와서 변수 정의 하고.. --> <c:set var="contextPath" value="<%= request.getContextPath()%>"></c:set> 아래와 같이 사용 하면 됨. <!-- script 정의 시 --> <script src="${contextPath}/res/js/date/jquery-1.10.2.js"></script> <!-- script 내부에서 --> <script> alert("${contextPath}"); </script> <!-- html body 에서 --> <body> contextPath : ${contextPath} </body> </html>
1. JSON.simple Dependency
Maven을 사용한다면 pom.xml에 설정하나로 central repository에서 받아오게 설정
<dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1</version> </dependency>
아니면 직접 json_simple-1.1.jar를 다운 받아서 클래스 패스 설정
http://code.google.com/p/json-simple/
2. Write JSON to file
import java.io.FileWriter; import java.io.IOException; import org.json.simple.JSONArray; import org.json.simple.JSONObject; public class JsonSimpleExample { public static void main(String[] args) { JSONObject obj = new JSONObject(); obj.put("name", "mkyong.com"); obj.put("age", new Integer(100)); JSONArray list = new JSONArray(); list.add("msg 1"); list.add("msg 2"); list.add("msg 3"); obj.put("messages", list); try { FileWriter file = new FileWriter("c:\\test.json"); file.write(obj.toJSONString()); file.flush(); file.close(); } catch (IOException e) { e.printStackTrace(); } System.out.print(obj); } }
Output : test.json
{ "age":100, "name":"mkyong.com", "messages":["msg 1","msg 2","msg 3"] }
3. Read JSON from file
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Iterator; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JsonSimpleExample { public static void main(String[] args) { JSONParser parser = new JSONParser(); try { Object obj = parser.parse(new FileReader("c:\\test.json")); JSONObject jsonObject = (JSONObject) obj; String name = (String) jsonObject.get("name"); System.out.println(name); long age = (Long) jsonObject.get("age"); System.out.println(age); // loop array JSONArray msg = (JSONArray) jsonObject.get("messages"); Iterator<String> iterator = msg.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } } }
Output :
mkyong.com 100 msg 1 msg 2 msg 3
웹사이트를 운영하다보면 웹사이트의 디자인이나 프론트엔드 동작을 바꾸기 위해서 CSS 또는 javascript 파일을 수정하는 일이 종종 생기게 된다. 이때 수정된 파일을 서버로 배포하더라도, 기존 웹사이트를 이용하던 유저의 브라우저 캐쉬때문에 수정된(fresh) 파일을 다운로드 하지 않고 캐쉬를 이용하게되어 웹사이트가 깨져보이게되는 경우가 있다.
사용중인 웹서버에서 특정 파일에대한 캐쉬설정을 적절히 바꿔서 Http Response Header에 캐쉬관련 지시자나 E-Tag 등이 잘 포함되게 설정해주면, 브라우저에서 expired 된 캐쉬가 사용되는 것을 적절히 막을 수 있지만, 직접 웹서버를 운영하지 않고 웹 호스팅서비스를 이용하는 경우 쉽지 않은 일이며, 정확하게 설정되지 않을경우 브라우저마다 미묘하게 동작이 달라서 원하는 결과를 완벽하게 얻지 못할때도 있다.
오래된 캐쉬(stale cache) 사용 막으려면?
이런 상황에서 캐쉬문제를 해결하기 위해서 가장 확실하고 간단한 방법은 캐쉬 자체의 기본 동작 방식을 역이용하는 것이다.
기본적으로 캐쉬의 동작은 URL을 기준으로 기존에 동일한URL에 요청한 적이 있었는지를 판단하게 된다. 쉽게 바꿔말하면, 해당 수정된 파일의 URL을 바꿔주면 기존의 캐쉬에 의해 영향을 받지 않을 수 있게 되는 것이다.
URL을 바꾸는 방법
무식한 방법: 수정이 그리 자주되지 않는 파일이라면, 해당 수정된 CSS/JS 파일명을 아예 바꿔버리고, 해당 파일을 로딩하는 HTML 코드쪽에서도 수정된 파일명을 넣어주면 된다.
좀더 스마트한 방법: 위 방법이 번거로울 경우 CSS/JS 파일명은 유지하는 대신 HTML 코드쪽에서 불러올때 버전 쿼리스트링을 붙여주는 방법이 매우 유용하다. 다음 예시를 살펴보자.
<link href="http://example.com/custom.css" rel="stylesheet" type="text/css" />
<link href="http://example.com/custom.css?ver=1.1" rel="stylesheet" type="text/css" />
위 코드의 경우 custom.css 파일이 수정되더라도, 적절한 캐쉬 지시자가 적용되지 않은경우 기존 웹사이트 이용하던 유저들이 수정된파일이 아닌 캐쉬된 파일을 보게될 확률이 크다. 이를 해결한 아래 코드를 보자.
위 코드의 경우 ?ver=1.1 이라고 파일명 뒤에 쿼리스트링을 붙여주었다. custom.css를 수정한 후, 번거롭게 파일명을 바꾸는 대신 ver 값만 다르게 주면 다른 URL로 인식되기 때문에 캐쉬된 파일이 사용되는것을 방지할 수 있다.
조금 더 응용한다면, server side 프로그램에서 해당 HTML 코드를 출력할때 ver 대신 해당 파일의 modified date가 자동으로 쿼리스트링으로 붙도록 개발해둘 경우, 수정되는 즉시 자동으로 반영되는 편리함을 누릴 수 있을것이다.
/* 숫자만 입력받기 */ function fn_press(event, type) { if(type == "numbers") { if(event.keyCode < 48 || event.keyCode > 57) return false; //onKeyDown일 경우 좌, 우, tab, backspace, delete키 허용 정의 필요 } } /* 한글입력 방지 */ function fn_press_han(obj) { //좌우 방향키, 백스페이스, 딜리트, 탭키에 대한 예외 if(event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 46 ) return; //obj.value = obj.value.replace(/[\a-zㄱ-ㅎㅏ-ㅣ가-힣]/g, ''); obj.value = obj.value.replace(/[\ㄱ-ㅎㅏ-ㅣ가-힣]/g, ''); }
<!-- 이렇게하면 숫자만 입력 됨 //전화번호 이런거 입력할 input 만들때 --> <input type="text" maxlength="3" onkeypress="return fn_press(event, 'numbers');" onkeydown="fn_press_han(this);" style="ime-mode:disabled;"/> <!-- 이렇게하면 영문만(숫자포함) 입력 됨 //이메일 아이디 같은거 입력을 만들때 --> <input type="text" onkeydown="fn_press_han(this);" style="ime-mode:disabled;"/>
<script type="text/javascript"> //아이디 입력시 한글, 특수문자 체크 function h_check(Objectname) { var intErr var strValue = Objectname var retCode = 0 var re = /[~!@\#$%<>^&*\()\-=+_\']/gi; //특수문자 정규식 변수 선언 for (i = 0; i < strValue.length; i++) { var retCode = strValue.charCodeAt(i) var retChar = strValue.substr(i,1).toUpperCase() retCode = parseInt(retCode) //입력받은 값중에 한글이 있으면 에러 if ( (retChar < "0" || retChar > "9") && (retChar < "A" || retChar > "Z") && ((retCode > 255) || (retCode < 0)) ) { intErr = -1; break; //입력받은 값중에 특수문자가 있으면 에러 } else if(re.test(strValue)) { intErr = -1; break; } } return (intErr); } </script>