'전체 글'에 해당되는 글 384건

  1. 2020.06.01 formData, XMLHttpRequset, HTTP Content-Disposition
  2. 2020.05.28 일반for문 vs. for in문
  3. 2020.05.06 article vs. section vs. div
  4. 2020.05.06 렉시컬 스코핑, 실행 컨텍스트와 클로저
  5. 2020.04.20 이클립스 톰캣 연동
  6. 2020.04.17 경로 표기법
  7. 2020.04.07 트러블 슈팅이란?
  8. 2020.04.02 Tomcat context 설정
  9. 2020.03.31 box-sizing : 박스의 크기를 어떤 것을 기준으로 계산할지를 정하는 속성
  10. 2020.03.31 스프링(Spring) AOP : AspectJ Pointcut 표현식 (Feat. 프로젝트에서 꼭 활용할 내용들)

formData, XMLHttpRequset, HTTP Content-Disposition

|

formData

1. form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공

2.  XMLHttpRequest.send() 메서드를 사용하여 쉽게 전송할 수 있다. 인코딩 타입이 "multipart/form-data"로 설정된 경우, form에서 사용하는 것과 동일한 포맷을 사용해야 함.

// 생성자
var data = new FormData();  // 새로운 FormData 객체를 생성

// 메소드
data.append(name, value, filename) // FormData 객체안에 이미 키가 존재하면 그 키에 새로운 값을 추가하고, 키가 없으면 추가합니다.
	(filename은 optional)
data.delete() // FormData 객체로부터 키/밸류 쌍을 삭제합니다.
data.entries() // 이 객체에 담긴 모든 키/밸류 쌍을 순회할 수 있는 iterator를 반환합니다.
data.get() // FormData 객체 내의 값들 중 주어진 키와 연관된 첫번째 값을 반환합니다.
data.getAll() // FormData 객체 내의 값들 중 주어진 키와 연관된 모든 값이 담긴 배열을 반환합니다.
data.has() // FormData 객체에 특정 키가 포함되어 있는지 여부를 나타내는 boolean 을 반환합니다.
data.keys() // 이 객체에 담긴 모든 키/벨류 쌍들의 모든 키들을 순회 할 수 있는 iterator를 반환합니다.
data.set() // FormData 객체 내에 있는 기존 키에 새 값을 설정하거나, 존재하지 않을 경우 키/밸류 쌍을 추가합니다.
data.values() // 이 객체에 포함된 모든 밸류를 통과하는 iterator를 반환합니다.

 

 

XMLHttpRequset

1. 객체는 서버와 상호작용하기 위하여 사용. 전체 페이지의 새로고침없이도 URL 로부터 데이터를 받아올 수 있다. 이는 웹 페이지가 사용자가 하고 있는 것을 방해하지 않으면서 페이지의 일부를 업데이트할 수 있도록 해줌. XMLHttpRequest 는 AJAX 프로그래밍에 주로 사용된다.

2.  모든 종류의 데이터를 받아오는데 사용할 수 있고, 또한 HTTP 이외의 프로토콜도 지원합니다(file 과 ftp 포함).

// 생성자
var xhr = new XMLHttpRequest(); // XMLHttpRequest 를 초기화. 다른 모든 메소드 호출이전에 호출되어야함

// 속성
xhr.onreadystatechange // readyState 어트리뷰트가 변경될때마다 호출되는 EventHandler 입니다.
xhr.readyState // 요청의 상태를 unsigned short 로 반환합니다. readonly
xhr.response // Read only 응답 엔티티 바디를 갖는하는 XMLHttpRequest.responseType 의 값에 따라 ArrayBuffer, Blob, Document, JavaScript 객체, 또는 DOMString 을 반환합니다.
xhr.responseText // Read only 요청에 대한 응답을 텍스트로 갖는 DOMString 을 반환합니다. 요청이 성공하지 못했거나 아직 전송되지 않았을 경우 null 을 반환합니다.
xhr.responseType // 응답 타입을 정의하는 열거형 값입니다.
xhr.responseURL // Read only 응답의 연속된 URL 을 반환합니다. URL 이 null 인 경우 빈 문자열을 반환합니다.
xhr.responseXML // Read only 요청에 대한 응답을 갖는 Document 를 반환합니다. 요청이 성공하지 못했거나, 아직 전송되지 않았거나, XML 또는 HTML 로 파싱할 수 없는 경우 null 을 반환합니다.
xhr.status // Read only 요청의 응답 상태를 갖는 unsigned short 를 반환합니다.
xhr.statusText // Read only HTTP 서버에 의해 반환된 응답 문자열을 갖는 DOMString 을 반환합니다. XMLHTTPRequest.status 와는 다르게, 응답 메시지의 전체 텍스트를 갖습니다(예, "200 OK").
xhr.timeout // 요청이 자동으로 종료될때까지 걸린 시간을 밀리초 단위로 나타내는 unsigned long 입니다.

XMLHttpRequestEventTarget.ontimeout // 요청 시간 초과때마다 호출되는 EventHandler 입니다.

xhr.upload // Read only 업로드 과정을 나타내는 XMLHttpRequestUpload 입니다.
xhr.withCredentials // 사이트 간 Access-Control 요청이 쿠키나 인증 헤더와 같은 자격 증명을 사용해야하는지 여부를 나타내는 Boolean 입니다.

// 메소드
xhr.abort() // 이미 전송된 요청을 중지합니다. ★응답시간이 오래되거나 부적절한 응답을받을경우 중단하기 위함!!!! 
xhr.getAllResponseHeaders() // 모든 응답 헤더를 CRLF 로 구분한 문자열로 반환합니다. 응답을 받지 않은 경우 null 입니다.
xhr.getResponseHeader() // 지정한 헤더의 텍스트를 갖는 문자열을 반환합니다. 응답을 아직 받지 못했거나 응답에 헤더가 존재하지 않을 경우 null 입니다.
xhr.open() // 요청을 초기화합니다. 이 메소드는 네이티브 코드로부터의 요청을 초기화하기 위해 JavaScript 코드에 의해 사용됩니다. 대신 openRequest() 를 사용하세요.
xhr.overrideMimeType() // 서버에의해 반환된 MIME 타입을 오버라이드합니다.
xhr.send() // 요청을 보냅니다. 요청이 비동기인 경우(기본값), 이 메소드는 요청이 보내진 즉시 반환합니다.
xhr.setRequestHeader() // HTTP 요청 헤더의 값을 설정합니다. open() 후, send() 전에 setRequestHeader() 를 호출해야합니다.

// 이벤트
abort // 예를 들어 프로그램이 XMLHttpRequest.abort()를 호출해서 요청이 중단되면 발생한다.onabort 속성을 통해서도 가능하다.
error // 요청에 에러가 생기면 발생한다.onerror 속성을 통해서도 가능하다.
load // XMLHttpRequest 처리 과정이 성공적으로 완료되면 발생한다.onload 속성을 통해서도 가능하다.
loadend // 요청이 성공이든 (load 다음) 실패든 (abort 또는 error 다음) 완료되면 발생한다. onloadend 속성을 통해서도 가능하다.
loadstart // 요청이 데이터를 받기 시작하면 발생한다. onloadstart 속성을 통해서도 가능하다.
progress // 요청이 데이터를 받는 동안 주기적으로 발생한다. onprogress 속성을 통해서도 가능하다.

 

HTTP Content-Disposition

1. Disposition이란 기질, 성향, 배치, 배열 이란 뜻

2. HTTP Response Header에 들어가는 Content-Disposition은 HTTP Response Body에 오는 컨텐츠의 기질/성향을 알려주는 속성

3. default 값은 inline으로 web에 전달되는 data라고 생각하면 된다.

4. 특수한 경우는 Content-Disposition에 attachment를 주는 경우로, 이때 filename과 함께 주게 되면 Body에 오는 값을 다운로드 받으라는 뜻이 된다.

5. "Content-disposition: inline"은

브라우저 인식 파일확장자를 가진 파일들에 대해서는 웹브라우저 상에서 바로 파일을 자동으로 보여줄 수 있어서 의미상인 멀티파트 메시지를 표현하는데 있다. 그외의 파일들에 대해서는 "파일 다운로드" 대화상자가 뜨도록 하는 헤더속성이다.

6. "Content-disposition: attachment"은
브라우저 인식 파일확장자를 포함하여 모든 확장자의 파일들에 대해,  다운로드시 무조건 "파일 다운로드" 대화상자가 뜨도록 하는 헤더속성이라 할 수 있다.

'JavaScript' 카테고리의 다른 글

favicon.ico 404 Not found 에러  (0) 2020.08.25
Map vs. Array  (0) 2020.07.31
일반for문 vs. for in문  (0) 2020.05.28
렉시컬 스코핑, 실행 컨텍스트와 클로저  (0) 2020.05.06
클래스 기반 언어 vs 자바스크립트  (0) 2020.03.27
And

일반for문 vs. for in문

|

일반for문

자바스크립트에서 for 문은 반복적인 동작을 수행하는 데 사용되며, 초기화식, 검사식, 증가식으로 세 부분으로 구성된다. 문법은 다음과 같다.

for (초기화식, 검사식, 증가식){
    구문
}
  • 초기화식은 반복문이 시작하기 전에 한 번만 평가된다.
  • 검사식은 각 반복에 앞서 평가되며 반복문의 본문이 실행될지 여부를 좌우한다. 검사식이 참이면 반복문의 본문에 해당하는 구문이 실행된다.
  • 증가식은 각 반복이 끝날 때마다 평가된다.

 

for in 문

자바스크립트에서 for...in 문은 객체의 프로퍼티를 순회하는 데 사용된다. 문법은 다음과 같다.

for (변수 in 객체){
    구문
}
  • for...in 문의 본문은 객체의 각 프로퍼티에 대해 한 번씩 실행된다.
  • 각 반복에 앞서 객체 프로퍼티 중 하나의 이름이 변수에 문자열 타입으로 할당된다.
  • 일반 object의 문자열 키를 순회하기 위해 만들어진 문법!
  • 프로토타입 체인을 모두 탐색하므로 hasOwnProperty 로 필터링 해야 에러 및 속도개선이 됨!
  • (JavaScript는 Java와 다르게 프로토타입 을 통해 상속을 사용하는데, for in 문은 객체의 각 프로퍼티에 접근하려고 하면 JavaScript는 해당 이름의 프로퍼티를 찾을 때까지 프로토타입 체인을 거슬러 올라가면서 탐색하게 됨. 없는 프로퍼티에 접근하려고 하면 항상 프로토타입 체인 전체를 탐색하게 됨. ) 
// 객체 정의
var person = { hand: 2, legs: 2, head: 1 };

// 코드 어딘가에서 모든 객체에 아래와 같은 메서드 하나가 추가되었다고 해보자.
if (typeof Object.prototype.clone === 'undefined') {
	Object.prototype.clone = function () {
 		// 메소드 로직 생략
	};
}

for (var prop in person) {
	console.log(prop, ":", person[prop]);
}

// 콘솔에 출력결과는 다음과 같다.

/* 
   hand : 2
   legs : 2
   head : 1
   clone : () {
   // 메소드 로직 생략
   }
*/

person 을 정의하기 전이나 후,
어디선가 Object 프로토타입에 clone() 이라는 이름의 메서드가 편의상 추가되었다고 했을때
프로토타입 체인의 변경 사항은 실시간으로 반영되기 때문에
자동적으로 모든 객체가 이 새로운 메서드를 사용할 수 있습니다.

person 을 열거할 때 clone() 메서드가 나오지 않게 하려면 프로토타입 프로퍼티를 걸러내기 위해
hasOwnProperty() 를 호출해야 합니다.
이렇게 걸러내지 않으면 clone() 이 나오게 되는데, 대부분의 경우 이러한 동작 방식은 바람직하지 않습니다.
seiresMap = {
	"A001": {name: "소정", data: Array(12)},
	"B001": {name: "시간외", data: Array(12)}
    }

seriesMap이 위와 같이 구성된 경우 for in문으로 작동이 되고,
일반 for문에선 // for ( i = 0, len = seriesMap.length; i < len; i++ ) {
작동하지 않는다.

            for ( i in seriesMap ) {
                res.push( {
                    name: seriesMap[ i ].name,
                    data: seriesMap[ i ].data,
                    categories: categories,
                    type: "bar",
                    stack: info.yAxisTitle
                } );
            }

 

And

article vs. section vs. div

|

article : 내용이 독립적이고 스스로 설 수 있는 내용인 경우

section : 내용이 서로 관계가 있다면

div : 의미적으로 관계가 없다면

 

여러개의 section을 article로 묶을 수 있고 마찬가지로 여러개의 article을 section으로 묶을 수 있다.

'HTML & CSS' 카테고리의 다른 글

좌표  (2) 2021.04.20
부트스트랩 모달  (0) 2021.03.31
box-sizing : 박스의 크기를 어떤 것을 기준으로 계산할지를 정하는 속성  (0) 2020.03.31
CSS기본문법, 속성, 선택자  (0) 2020.02.23
Margin vs. Padding  (0) 2020.01.21
And

렉시컬 스코핑, 실행 컨텍스트와 클로저

|

렉시컬 스코핑(lexical scoping)

  1. 스코프는 함수를 호출할 때가 아니라 선언할 때 생김
var name = 'zero';
function log() {
  console.log(name);
}

function wrapper() {
  var name = 'nero';
  log();
}
wrapper(); // zero

함수를 처음 선언하는 순간, 함수 내부의 변수는 자기 스코프로부터 가장 가까운 곳(상위 범위에서)에 있는 변수를 계속 참조하게 됩니다. 위의 예시에서는 log 함수 안의 name 변수는 선언 시 가장 가까운 전역변수 name을 참조하게 됩니다. 그래서 wrapper 안에서 log를 호출해도 지역변수 name='nero'를 참조하는 게 아니라 그대로 전역변수 name의 값인 zero가 나오는 겁니다.

 

실행 컨텍스트(문맥; 코드의 실행환경)를 이해하기 위한 자바스크립트 동작과정

  1. 변수, 함수 선언, arguments 을 가진 활성 객체(Variable Object) 생성
  2. Scope Chain 생성 및 초기화
    • 변수 초기화 : 변수 값에 undefined 할당
  3. this 바인딩
  4. 코드 해석 및 실행
    • 변수 값 할당 : 변수에 실제 값 할당
var name = 'zero'; // (1)변수 선언 (6)변수 대입
function wow(word) { // (2)변수 선언 (3)변수 대입
  console.log(word + ' ' + name); // (11) 
}
function say () { // (4)변수 선언 (5)변수 대입
  var name = 'nero'; // (8)
  console.log(name); // (9) 
  wow('hello'); // (10) // hello zero
}
say(); // (7) // nero
'전역 컨텍스트': { // 1. 모든 것을 관리하는 환경, 페이지가 종료될 때까지 유지됨.
  // 2. 함수를 호출할때마다 함수 컨텍스트가 생김
  변수객체: { // 3. 컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments, variable), scope chain, this가 생성
    arguments: null, // 함수의 인자
    variable: ['name', 'wow', 'say'], // 해당 스코프의 변수들
  },
  scopeChain: ['전역 변수객체'], // 자신과 상위 스코프들의 변수객체
  this: window,
}

// 4. 컨텍스트 생성 후 함수가 실행되는데, 사용되는 변수들은 변수 객체 안에서 값을 찾고, 없다면 스코프 체인을 따라 올라가며 찾습니다.
// 5. 함수 실행이 마무리되면 해당 컨텍스트는 사라집니다.(클로저 제외) 페이지가 종료되면 전역 컨텍스트가 사라집니다.

variable: [{ name: 'zero' }, { wow: Function }, { say: Function }]
//  wow랑 say는 호이스팅 때문에 선언과 동시에 대입
//  그 후 variable의 name에 'zero'가 대입
// (7)번에서 say();를 하는 순간 새로운 컨텍스트인 say 함수 컨텍스트가 생김
'say 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: ['name'], // 초기화 후 [{ name: 'nero' }]가 됨
  },
  scopeChain: ['say 변수객체', '전역 변수객체'],
  this: window,
}
/* say를 호출한 후 위에서부터 차례대로((8)~(10) 실행하는데요.
variable의 name에 nero를 대입해주고 나서 console.log(name);이 있습니다.
name 변수는 say 컨텍스트 안에서 찾으면 됩니다. variable에 name이 nero라고 되어 있네요.
name이 콘솔에 찍힙니다. 그 다음엔 wow('hello')가 있는데요.
say 컨텍스트 안에서 wow 변수를 찾을 수 없습니다.
찾을 수 없다면 scope chain을 따라 올라가 상위 변수객체에서 찾습니다.
그래서 전역 변수객체에서 찾습니다. 전역 변수객체의 variable에 wow라는 함수가 있네요.
이걸 호출합니다.

(10)번에서 wow함수가 호출되었으니 wow 컨텍스트도 생기겠죠?
arguments는 word = 'hello'고, scope chain은 wow 스코프와 전역 스코프입니다.
여기서 중요한 게 lexical scoping에 따라 wow 함수의 스코프 체인은 선언 시에 이미 정해져 있습니다.
따라서 say 스코프는 wow 컨텍스트의 scope chain이 아닙니다.
variable은 없고, this는 window입니다.
*/

'wow 컨텍스트': {
  변수객체: {
    arguments: [{ word : 'hello' }],
    variable: null,
  },
  scopeChain: ['wow 변수객체', '전역 변수객체'],
  this: window,
}

/*
이제 컨텍스트가 생긴 후 함수가 실행 됩니다. say 함수는 아직 종료된 게 아닙니다.
wow 함수 안에서 console.log(word + ' ' + name);이 있는데요.
word랑 name 변수는 wow 컨텍스트에서 찾으시면 됩니다.
word는 arguments에서 찾을 수 있고, name은 wow 변수객체에는 값이 없으니,
scope chain을 따라 전역 스코프에서 찾으시면 됩니다.
전역 변수객체로 올라가니 variable에 name이 zero라고 되어 있네요.
그래서 hello zero가 되는 겁니다. hello nero가 아니라요.
wow 컨텍스트에 따르면 wow 함수는 애초에 say 컨텍스트와 일절 관련이 없었던 겁니다.

이제 wow 함수 종료 후 wow 컨텍스트가 사라지고, say 함수의 실행이 마무리됩니다.
따라서 say 컨텍스트도 사라지고, 마지막에 전역 컨텍스트도 사라집니다.
*/

변수 초기화 과정

  1. 변수 선언 - 변수를 활성 객체에 할당
  2. 변수 초기화 - 변수 값에 undefined 할당
  3. 변수 실제 값 할당 - 변수에 실제 값을 할당

클로저

실행이 끝난 함수의 스코프를 참조할 수 있는 함수

function parent() {
  var a = 'Parent is done';
  function child() {
    console.log(a);
  }
  return child;
}
var closure = parent();
closure();

위 내부함수의 정의대로라면 parent 의 내부함수인 child() 는 외부에서 접근이 불가능하다. 하지만 return 값에 child 를 넘김으로써 외부에서도 child 를 호출할 수 있게 된다. 따라서, child() 에서 parent 의 값을 참고하고 있다면, child() 를 밖에서 호출함으로써 parent() 의 변수에 접근이 가능하게 된다. 이것이 클로져

And

이클립스 톰캣 연동

|

이클립스(Oxygen Ver.)는 설치되었다는 가정하에 톰캣 연동을 하는 방법이다.

 

1) 먼저 톰캣 홈페이지에 접속하여 원하는 톰캣 버전을 다운받는다.

☞ https://tomcat.apache.org

 

(해당 포스팅은 톰캣 8버전을 기준으로 작성하였습니다)

 

2) 자신의 PC에 맞는 파일을 다운!

 

3) 압축을 풀고 tomcat-8.0(이름이 길어 짧게 변경)을 "C:" 경로로 옮긴다.

 

3-1) 설치한 톰캣 폴더(tomcat-8.0)/conf/server.xml 파일 확인

☞ (포트번호 확인)기존에는 8080이 사용될 것이다. 포트 충돌 방지를 위해 포트번호를 변경해준다.

 

 

4) 이클립스의 서버탭의 아래 표시된 부분 클릭

 

5) 자신이 설치한 톰캣 버전 선택

 

6) 아래와 같은 창이 뜬다면 Browse... 클릭

 

7) 설치한 톰캣 폴더 선택 후 확인 ☞ Next

 

8) 자신의 프로젝트 파일 선택 후 Add ☞ Finish

 

9) 톰캣 실행!

 

10) 프로젝트의 WebContent 폴더 아래 index.jsp 파일을 만든다.

 

11) 웹을 켜서 localhost:8088(3-1에서 설정한 포트번호)/프로젝트 이름/index.jsp을 입력

아래와 같이 화면이 보인다면 성공!

 

*** 마지막으로 이클립스 build path 에서 external api 추가 ( 톰캣설치폴더 - lib 폴더안의 servlet~~.api 와 jsp~~.api) 

 

TOMCAT_HOME/conf/server.xml 파일에서 수정

 

<GlobalNamingResources> 

....[주석]

....[기존설정내용]

.....

</GlobalNamingResources> 

해당 구문을 찾고 아래 내용을 사이에 넣는다.


<Resource

      name="jdbc/oracle"

      auth = "Container"

      type = "javax.sql.DataSource"

      driverClassName = "oracle.jdbc.OracleDriver"

      url = "jdbc:oracle:thin:@localhost:1521:XE"

      username = "scott"

      password = "tiger"

      maxActive = "50"

      maxWait = "-1"

    />

 

 

*** 서버주소 매핑하는 법

D:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\Catalina\localhost

하위 폴더에 아래 내용을 예시로 wizard.xml 파일을 저장하면 됨.

<Context path="/wizard" reloadable="true" privileged="true" docBase="D:\work\inorgdesignwizard\wizard"></Context>


출처: https://shxrecord.tistory.com/104 [첫 발]

'DevTools' 카테고리의 다른 글

Eslint  (0) 2021.09.28
Markdown 쓰는 방법  (0) 2021.03.15
Tomcat context 설정  (0) 2020.04.02
UML - 관련 정리  (0) 2020.03.30
Tomcat 프로세스 강제종료  (0) 2020.03.19
And

경로 표기법

|
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
     <h1>상대 경로</h1>
     <div><a href ="./ex04.htm">같은 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="ex04.htm">같은 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="./Member/list.htm">자식 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="Member/list.htm">자식 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="./Member/private/private.htm">자식 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="Member/private/private.htm">자식 폴더의 다른 페이지 이동하기</a></div>
     <div><a href ="../필기.txt">프로젝트 루트 폴더의 자원으로 이동</a></div>
     
     <h1>절대 경로</h1>
     <div><a href ="/WebClientTest/ex01.htm">절대경로</a></div>
     <div><a href ="/WebClientTest/Member/list.htm">절대경로</a></div>
     <div><a href ="/WebClientTest/Member/private/private.htm">절대경로</a></div>
     <div><a href ="/WebClientTest/Member/list.htm">부모폴더의 다른 페이지 이동하기</a></div>
     
     
     <h1>로컬 경로</h1>
     <div><a href ="ex01.htm">1번예제 (상대)</a></div>
     <div><a href ="/WebClientTest/ex01.htm">1번예제 (절대)</a></div>
     <div><a href ="C:\Users\user\Desktop\Class\WebClient\WebClientTest\WebContent\ex01.htm">1번예제 (로컬)</a></div>
     
     <h1>외부 경로</h1>
     <div><a href = "http://naver.com">네이버 이동하기</a></div>
     <div><a href = "http://www.naver.com">네이버 이동하기</a></div>
     
</body>
</html>

'etc' 카테고리의 다른 글

끄적3  (0) 2020.10.28
끄적2  (0) 2020.10.15
고쳐야할것, 실수 끄적여놓은 것들  (0) 2020.06.23
트러블 슈팅이란?  (0) 2020.04.07
코딩을 잘하는 사람들의 특징  (0) 2020.01.21
And

트러블 슈팅이란?

|

정확한 원인을 짚고 넘어가야 함... 안그러면 나중에 더 큰 문제가 발생하거나 풀스캔을 해야만 하는 큰 사태가 벌어지게 된다.

 

troubleshooting 방법론

 

마이크로소프트는 오류가 발생하거나 성능상의 문제가 발생하게 되면 다음과 같은 detect 라는 방법을 통해서 문제에 접근하고 해결하는 것을 권장하고 있습니다.

> 6 단계로 구성

d discover the problem
e explore the conditions
t track down possible approaches
e execute the most likely approach
c check for success
t tie up loose ends
  • 첫 번째 discover the problem 단계는 성능 문제나 장애 사항을 발견하는 첫 단계 입니다. 이단계에서는 발생된 문제와 관련된 정보를 정확히 유지하여야 합니다.
  • 두 번째 explore the conditions 단계는 발생된 문제의 주변 상황을 면밀히 검토하여 문제를 올바르게 정의하는 단계입니다.
  • 세 번째 track down possible approaches 단계는 앞의 단계에서 정의된 문제가 발생된 원인을 찾기 위해 범위를 좁혀 나가고 예상되는 원인 별로 가능한 방안을 검토하여 문제 해결의 전략을 수립하는 단계입니다.
  • 네 번째 execute the most likely approach 단계는 검토된 방안 중에서 가장 기본적인 방법부터 또는 가장 해결 가능성이 높은 방법부터 수행하여 문제 해결에 접근하는 단계입니다.
  • 다섯 번째 check for success 단계는 문제의 해결여부를 점검하는 단계입니다.
  • 마지막 여섯 번째 tie up loose ends 단계는 문제 해결을 위해 적용한 방법에 대한 추가적인 문제 발생 여부를 확인하고 잠재적인 문제점이 있는지 여부 등을 점검하며, 끝으로 발생단계부터 종결까지 문서화해서 차후 유사한 문제의 해결을 돕는 마무리 단계입니다.

이와 같은 detect 방법을 사용해 각 단계별로 지정된 절차를 통해 발생된 문제에 접근하고 해결 방법을 도출하는 경우 얻을 수 있는 장점은 다음과 같습니다.

 

먼저, 발생되는 문제와 해결방법을 정형화하고 단계별로 차근차근 접근함으로써 문제 해결에 자연스럽게 접근할 수 있습니다. 또한, 기존에 문제를 해결한 것을 바탕으로 새로운 문제가 발생했을 때 원인을 규명하는데 필요한 논리적 판단력과 대응력을 키우게 됩니다. 이러한 상황을 유발하게 된 원인이 무엇인지를 찾기 위해 윈도우 이벤트 로그나 sql server 오류 로그 등을 살펴보고 그 당시에 발생된 상황 등을 추적해 하나씩, 하나씩 정리 하면서 문제의 원인이 될 수 있는 부분과 될 수 없는 부분을 구별하게 되며, 그에 따른 해결방법을 정리해 놓음으로써 향후에 동일한 문제가 재발하거나 유사한 문제가 발생되는 경우 효율적으로 대처 할 수 있게 됩니다. 그리고 이러한 접근이 습관화가 되면, 발생한 문제에 대해서 어느 부분부터 접근하는 것이 문제를 보다 신속하고 정확하게 해결하는 것인지를 직관화하는 능력도 배양할 수 있습니다.

 

뿐만 아니라, 문제해결을 위해 본인이 습득해야 할 지식이 무엇인지를 명확하게 규명해 줍니다

 

간단한 예로 데이터베이스가 갑자기 주의 대상 (suspect) 모드로 변경되어 엔터프라이즈 관리자에서 시커멓게 변해 버렸습니다. 이때“이게 뭔 일이래?”하는 생각이 들거나, 또는“관리자에게 문의하세요”라는 메시지를 받았는데 자신이 관리자인 경우입니다. 그런데 정작 자신은 본인에게나 다른 사람에게 도대체 뭘 어떻게 물어봐야 하는지도 모르는 상황이라면 어떻겠습니까

 

이럴 때라도 detect 방법에 따라 차근차근 접근해 나가면서 각 단계별로 어떠한 작업을 해야 하고 그런 작업을 하기 위해서는 자신이 무엇을 모르고, 무엇을 알고 있는지를 인식할 수 있게 됩니다.


출처: https://mingnol2.tistory.com/173 [거북이 개발자]

'etc' 카테고리의 다른 글

끄적3  (0) 2020.10.28
끄적2  (0) 2020.10.15
고쳐야할것, 실수 끄적여놓은 것들  (0) 2020.06.23
경로 표기법  (0) 2020.04.17
코딩을 잘하는 사람들의 특징  (0) 2020.01.21
And

Tomcat context 설정

|

 

1. C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf/server.xml

 

2.

<Context path="/하고자 하는 경로명" reloadable="true" privileged="true" docBase="D:\aaa\bbb(해당 프로젝트 폴더 주소)"></Context>

3. 서버 재시작 후 '/하고자 하는경로명' 으로 접속

 

 

'DevTools' 카테고리의 다른 글

Markdown 쓰는 방법  (0) 2021.03.15
이클립스 톰캣 연동  (0) 2020.04.20
UML - 관련 정리  (0) 2020.03.30
Tomcat 프로세스 강제종료  (0) 2020.03.19
전자정부프레임워크  (0) 2020.02.06
And

box-sizing : 박스의 크기를 어떤 것을 기준으로 계산할지를 정하는 속성

|
box-sizing: content-box | border-box | initial | inherit
  • content-box : 콘텐트 영역을 기준으로 크기를 정합니다.
  • border-box : 테두리를 기준으로 크기를 정합니다.
  • initial : 기본값으로 설정합니다.
  • inherit : 부모 요소의 속성값을 상속받습니다.

'HTML & CSS' 카테고리의 다른 글

부트스트랩 모달  (0) 2021.03.31
article vs. section vs. div  (0) 2020.05.06
CSS기본문법, 속성, 선택자  (0) 2020.02.23
Margin vs. Padding  (0) 2020.01.21
구글 크롬 개발자 도구  (0) 2019.07.31
And

스프링(Spring) AOP : AspectJ Pointcut 표현식 (Feat. 프로젝트에서 꼭 활용할 내용들)

|
1. AOP(Aspect Oriented Programming)
- 주기능과 보조기능을 분리한 후 선택적으로 메소드에 적용
- XML(aound advice) 스키마 기반
- aspect(클래스) 애노테이션 기반

// XML 설정파일
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
       
       
<!-- 공통 기능을 제공할 클래스를 빈으로 등록 -->
 <bean id="profiler" class="spring.apo.ex01.advice.ProfilerAdvice" />

 <!-- Aspect 설정: Advice를 어떤 Pointcut에 적용할 지 설정 -->
 <aop:config>
  <aop:aspect id="traceAspect" ref="profiler">
   // Aspect J의 표현식
   <aop:pointcut id="publicMethod" expression="execution(public * spring.apo.ex01..*(..))" />
   // pointcut 이라는 호출할 메소드의 범위를 결정하고 / * - 모든 파라미터를 가진 / (..) - 하위 패키지까지 포함.
   <aop:around pointcut-ref="publicMethod" method="trace" />
   // around - 호출시점 / trace - 공통기능
  </aop:aspect>
 </aop:config>

 <bean id="readArticleService" class="spring.apo.ex01.component.ReadArticleServiceImpl">
  <property name="articleDao" ref="articleDao" />
 </bean>

 <bean id="articleDao" class="spring.apo.ex01.component.ArticleDaoImpl" />       
       
</beans>

// Advice 클래스
// Aound Advice
// 다른 advice는 대상객체 호출을 spring FW이 실행
public class ProfilerAdvice {
// ProceedingJoinPoint joinPoint 파라미터이면 -> Around Advice이고,
 public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
  String signatureString = joinPoint.getSignature().toShortString();
  System.out.println(signatureString + " 시작");
  long start = System.currentTimeMillis();
  try {
  // Around Advice이면, proceed() 메소드 제공한다.
   Object result = joinPoint.proceed(); // aspect가 적용될 대상 객체 호출
   return result;
  } finally {
   long finish = System.currentTimeMillis();
   System.out.println(signatureString + " 종료");
   System.out.println(signatureString + " 실행 시간 : " + (finish - start) + "ms");
  }
 }
}

2. AspectJ의 Pointcut 표현식

execution(public void set*(..)) : 리턴타입이 void이고 메소드이름이 set으로 시작하고 파라미터가 0개이상인 매소드 호출. 파라미터 부분에 ..을 사용하여 0개 이상인 것을 표현
execution(*.net.spring.*.*()) : spring 패키지의 파라미터가 없는 모든 메소드, 모든 리턴타입
execution(*.net.spring..*.*(..)) : spring 패키지의 파라미터가 0개 이상이고 패키지 부분에 ..을 표현하여 하위패키지를 표현
execution(Integer net.spring.boid.WriteArticleService.write(..)) : 리턴타입이 Integer인 WriteArticleService IF의 write() 메소드 호출
execution(* get*(*)) : 이름이 get으로 시작하고 1개의 파라미터를 갖는 메소드 호출
execution(* get*(*,*)) : 이름이 get으로 시작하고 2개의 파라미터를 갖는 메소드 호출
execution(* read*(Integer, ..)) : 이름이 read로 시작하고, 첫번째 파라미터 타입이 Integer이며, 1개의 파라미터를 갖는 메소드 호출

스프링(Spring) AOP : AspectJ Pointcut 표현식

execution 명시자
- Advice를 적용할 메서드 지정

- 기본 형식 :
-> "*" 는 모든 값을 의미
-> ".." 는 0개 이상 의미

 execution([수식어] [리턴타입] [클래스이름] [이름]([파라미터])

 수식어
 - 생략가능
 - public, protected 등등

리턴타입
 - 메서드의 리턴타입 지정

클래스이름, 이름
 - 클래스의 이름 및 메서드의 이름 지정

 파라미터
 - 메서드 파라미터 지정

ex)

execution(* some.package.*.*())
- some.package 패키지 내
- 파라미터가 없는 모든 메서드 호출

execution(* some.package..*.*(..))
- some.package 패키지와 하위 패키지에 있는
- 파라미터가 0개 이상인 모든 메서드 호출

execution(String some.package.SomeService.someMethod(..))
- 리턴 타입이 String,
- some.package.SomeService 인터페이스 내
- 파라미터가 0개 이상인 someMethod 메서드 호출

execution(* some*(*))
- 메서드 이름이 some으로 시작되고,
- 파라미터가 1개인 메서드 호출

execution(* some*(*, *))
- 메서드 이름이 some으로 시작되고,
- 파라미터가 2개인 메서드 호출

execution(* some*(String, ..))
- 메서드 이름이 some으로 시작되고,
- 첫번째 파라미터 타입이 String,
- 파라미터가 1개 이상인 메서드 호출

within 명시자 
- 특정 타입(Interface, Class)에 속하는 메서드를 Pointcut으로 지정

ex)
within(some.package.SomeService)
- SomeService 인터페이스 내 모든 메서드 호출

within(some.package.*)
- some.package 패키지 내 모든 메서드 호출

within(some.package..*)
- some.package 패키지 및 하위 패키지 내 모든 메서드 호출

bean 명시자
- Spring 2.5부터 제공
- 스프링 빈 이름을 이용하여 Pointcut 지정
- 빈 이름의 패턴을 설정

ex)
bean(someServiceBean)
- 이름이 someServiceBean인 빈의 메서드 호출

bean(*SomeService)
- 이름이 SomeService로 끝나는 빈의 메서드 호출

- 표현식에는 '&&' 및 '||' 연산자를 이용
-> 각각의 표현식을 연결
-> and 연산과 or 연산
-> and면 양쪽 표현식을 모두 만족하는
-> or이면 양쪽 표현식중 어느 하나를 만족하는

ex)
@Before("execution(public !void get*(..)) || execution(public !void set*(..))")
public void someBeforeAdviceMethod(JoinPoint joinPoint){
	// 대상 객체 메서드 실행전 수행할 공통기능
}

@After("execution(public !void get*(..)) && execution(public * get*(..))")
public void someAfterAdviceMethod(JoinPoint joinPoint){
	// 대상 객체 메서드 실행후 수행할 공통기능
}

- XML 스키마에서 Aspect를 설정할 경우
-> '&&', '||' 사용가능 ('&amp;&amp;' 식으로)
-> 'and', 'or'로 사용가능
<aop:pointcut id="somePointcut" 
       expression="execution(public !void get*(..)) &amp;&amp; execution(public * get*(..))" />

<aop:pointcut id="somePointcut" 
       expression="execution(public !void get*(..)) and execution(public * get*(..))" />

출처: https://groovysunday.tistory.com/204?category=312452 [성냥의 불친절한 IT 이야기]

'Framework' 카테고리의 다른 글

[Spring] Tomcat + Spring Framework 구동 흐름 정리  (1) 2023.06.13
[Spring] 스프링의 4가지 concept 정리  (0) 2023.06.02
개발표준  (0) 2023.04.27
[Spring] PostConstruct  (0) 2023.04.04
Front-End Framework 정리  (0) 2021.06.13
And