DUAL 테이블에서 00~23 시 까지 입력된 컬럼에 현재 시간 찍기 코드이다.


여러가지 방식을 사용할 수 있다.



1. CUBE 2의 n승 값을 주는 방법



1
2
3
4
5
6
7
8
9
10
11
12
SELECT A.STANDARD, DECODE(TO_CHAR(SYSDATE,'HH24'),STANDARD,'O','') AS MYTIME
  FROM (
        SELECT 
          CASE
          WHEN LEVEL-1 < 10
            THEN '0' || TO_CHAR(LEVEL-1)
            WHEN LEVEL-1 < 24
            THEN TO_CHAR(LEVEL-1)
          END AS STANDARD
         FROM DUAL
        CONNECT BY LEVEL <=24
  ) A
cs



2. CASE WHEN THEN ELSE END 조건문을 주는 방법



1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT A.STANDARD, B.MTIME
  FROM
  (
   SELECT LPAD(LEVEL-1,2,'0') AS STANDARD
     FROM DUAL
     CONNECT BY LEVEL<=24
  )A,
  (
   SELECT TO_CHAR(SYSDATE,'HH24') AS MTIME
     FROM DUAL
  )B
  WHERE A.STANDARD = B.MTIME(+)
  ORDER BY A.STANDARD
cs


3. LPAD 왼쪽에 위치 지정해 추가하는 방법



1
2
3
4
5
6
7
8
9
10
11
12
SELECT LPAD(ROWNUM-1,2,0) AS STANDARD, 
       CASE 
         WHEN TO_CHAR(SYSDATE,'HH24'= LPAD(ROWNUM-1,2,0
         THEN 'O' 
       END AS MYTIME
  FROM 
  ( 
       SELECT 1
         FROM DUAL
         GROUP BY CUBE(1,1,1,1,1)
   )
  WHERE ROWNUM <= 24  
cs


웹서버는 아파치 회사의 아파치 제품, 마이크로소프트의 IIS, NGINX의 nginx, 구글의 GWS가 있다.



우리가 웹브라우저를 접속하면 내부적으로 Request를 웹 서버(아파치 or IIS or nginx or GWS)에 보내고 웹 서버는 이 요청을 다시 WAS(tomcat,제우스,웹로직,웹스피어)로 보내게 된다. WAS에서는 웹 서버의 요청을 처리하고 다시 웹서버로 response하고 웹서버는 우리가 사용하는 웹 브라우저로 응답한다.


다음 그림을 보면 정확히 이해 할수 있다.



그림 출처 : http://slideplayer.com/slide/8297012/

'전체 > 네트워크' 카테고리의 다른 글

OSI 7 계층이란?, OSI 7 계층을 나눈 이유  (25) 2018.08.15
HTTP 프로토콜이란?  (2) 2018.08.12

1. Servlet의 이해

1.1 Servlet 이란

  • Servlet은 웹에서 JAVA 프로그래밍을 구현하기 위해 탄생 함.
  • JAVA 로 구현된 CGI(Common Gateway Interface) 라고들 흔히 말함
  • HTTP protocol 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속하여 개발하며, Servlet은 Container에 의해서 실행되고, 관리된다.
  • HTML 변경시 Servlet을 재컴파일 해야 하는 단점이 있다.

1.2 Servlet Container란

  • HTTP 요청을 받아서 Servlet을 실행시키고, 그 결과를 사용자 브라우저에게 전달해주는 기능을 제공하는 컴포넌트 이다.
  • Servlet을 실행하고 생명주기를 관리하는 역할을 한다.
  • Servlet과 웹 서버(Apache, nginx..)가 서버 통신 할 수 있는 방법을 제공한다.
  • 멀티 스레딩을 지원하여 클라이언트의 다중 요청을 알아서 처리해준다.
  • 대표적인 Conatainer에는 Tomcat, jetty, jboss 등이 있다.

1.3 Servlet 동작과정


  • ① 사용자가 URL을 클릭하면 HTTP Request를 Servlet Container에 보낸다.
  • ② Servlet Container는 HttpServletRequest, HttpServletResponse 두 객체를 생성한다.
  • ③ 사용자가 요청한 URL을 분석하여 어느 서블릿에 대한 요청인지 찾는다. (DD를 참조하여 분석)
  • ④ 컨테이너는 서블릿 service() 메소드를 호출하며, POST, GET여부에 따라 doGet() 또는 doPost()가 호출된다.
  • ⑤ doGet() or doPost() 메소드는 동적인 페이지를 생성한 후 HttpServletResponse객체에 응답을 보낸다.
  • ⑥ 응답이 완료되면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킨다.
DD (배포서술자, Deployment Descriptor) = web.xml
  • Servlet, Error Page, Listener, Fillter, 보안 설정등 Web Application의 설정 파일이다.
  • URL과 실제 서블릿의 매핑 정보도 담고 있다.
  • 하나의 웹 어플리케이션에 하나만 존재한다.
  • 보통 Web Document Root 디렉토리에 WEB-INF 폴더 아래 web.xml 파일로 존재한다.

1.4 JSP의 동작구조






index.jsp 파일을 작성해서 저장하면 서블릿으로 변환하여 index_jsp.java 로 변환되고 다시 index_java.class로 컴파일 된다.


.java와 .class 파일로 바꾸는 것은 WAS(tomcat)과 JDK에서 내부적으로 처리해준다.


그래서 tomcat server 의 Server path: 를 보면 .metadata 뒤로 .java와 .class 파일이 저장될 위치를 알려주고 있다.


해당경로로 들어가 파일을 읽어보면  jsp소스가 java형식과 class형식의 코드로 재작성된 코드를 볼수 있다.




서블릿 작성 순서


  • Servlet 예제 코드 작성 

  • URL과 Servlet 매핑하기  

  • Tomcat 연동 하기 

  • 서블릿 실행


참조 : http://wiki.gurubee.net


Maven 왜 써야하나



1. 기존방식


레파지토리 관리 문제


프로젝트 폴더의 properties > Java Build Path > Libraries > Add External JARs 를 통해 자신이 필요한 jar 파일을 구해 추가해야 했다.


초기 개발 환경설정에 어려움이 생길 뿐만 아니라 이후 유지보수나 추가개발 시 jar 파일을 다운받고 서로의 버전을 맞춰야 하는 문제가 발생했다.



2. Maven 쓰고 난 다음 방식


https://mvnrepository.com/


접속하여 자신이 필요한 jar 파일 이름 키워드를 검색하면


.jar로 제공되는 많은 maven 정보가 뜨게 되고


메이븐을 사용하여


pom.xml 안에 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.1.11</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>
cs


간단하게 문장 몇줄만 적어주게 되면 Maven Dependencies 안에 .jar 파일을 모두 받아온다.




  • 교착 상태(膠着狀態, 영어: deadlock)란 두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 가리킨다. 예를 들어 하나의 사다리가 있고, 두 명의 사람이 각각 사다리의 위쪽과 아래쪽에 있다고 가정한다. 이때 아래에 있는 사람은 위로 올라 가려고 하고, 위에 있는 사람은 아래로 내려오려고 한다면, 두 사람은 서로 상대방이 사다리에서 비켜줄 때까지 하염없이 기다리고 있을 것이고 결과적으로 아무도 사다리를 내려오거나 올라가지 못하게 되듯이, 전산학에서 교착 상태란 다중 프로그래밍 환경에서 흔히 발생할 수 있는 문제이다. 


  • 프로세스(process)는 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램을 말한다. 종종 스케줄링의 대상이 되는 작업(task)이라는 용어와 거의 같은 의미로 쓰인다. 


프로세스 상태



커널 내에는 준비 큐, 대기 큐, 실행 큐 등의 자료 구조가 있으며 커널은 이것들을 이용하여 프로세스의 상태를 관리한다.

  • 생성(create) : 프로세스가 생성되는 중이다.
  • 실행(running) : 프로세스가 CPU를 차지하여 명령어들이 실행되고 있다.
  • 준비(ready) : 프로세스가 CPU를 사용하고 있지는 않지만 언제든지 사용할 수 있는 상태로, CPU가 할당되기를 기다리고 있다. 일반적으로 준비 상태의 프로세스 중 우선순위가 높은 프로세스가 CPU를 할당받는다.
  • 대기(waiting) : 보류(block)라고 부르기도 한다. 프로세스가 입출력 완료, 시그널 수신 등 어떤 사건을 기다리고 있는 상태를 말한다.
  • 종료(terminated) : 프로세스의 실행이 종료되었다.


  • 스레드와 멀티스레드


스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티스레드(multithread)라고 한다.


  • 해시맵


HashMap이란 Map인터페이스의 한종류로써 Key와 Value 값으로 데이터를 저장하는 형태를 가지고 있다.


Map은 키(Key), 값(Value) 을 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스들을 구현하는 데 사용된다.


쉽게 말해 key, value 값으로 저장하는 List 와 비슷하다.


  • REST


Representational safe transfer (REST)는 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처이다.

REST 원리를 따르는 시스템은 종종 RESTful이란 용어로 지칭된다.

영어의 접미사인 ful이란 단어는 가득한 풍부한이라는 뜻이다. REST가 가득하다는 뜻이다.


REST는 요소로는 크게 리소스,메서드,메세지 3가지 요소로 구성된다.


예를 들어서 “name이 sanghyun인 users를 생성한다” 라는 호출이 있을 때


"users" 는 생성되는 리소스, 

"생성한다" 라는 행위에 POST 메서드,

"name이 sanghyun인 users" 는 메시지가 된다


이를 REST 형태로 표현해보면


HTTP POST , http://localhost/users/


1
2
3
4
5
{  
   "users":{  
      "name":"sanghyun"
   }
}
cs


REST에서는 행위에 대한 메서드를 HTTP 메서드 그대로 사용한다.

HTTP 에는 여러가지 메서드가 있지만 REST에서는 CRUD(Create Read Update Delete)에 해당 하는 4가지의 메서드만 사용한다.

REST의 리소스

REST는 리소스 지향 아키텍쳐 스타일이라는 정의 답게 모든 것을 리소스 즉 명사로 표현을 하며, 각 세부 리소스에는 id를 붙인다.

즉 사용자라는 리소스 타입을 http://localhost/users라고 정의했다면, sanghyun이라는 id를 갖는 리소스는 http://localhost/users/sanghyun 의 형태이다.
REST의 리소스가 명사의 형태를 띄우다 보니, 명령(Operation)성의 API를 정의하는 것에서 혼돈이 올 수 있다.

예를 들어서 “Push 메서지를 보낸다”는 보통 기존의 RPC(Remote Procedure Call)이나 함수성 접근해서는 /localhost/sendpush 형태로 잘못 정의가 될 수 있지만, 이러한 동사형을 명사형으로 바꿔서 적용해보면 리소스 형태로 표현하기가 조금더 수월해 진다.

“Push 메시지 요청을 생성한다.”라는 형태로 정의를 변경하면, API 포맷은 POST/localhost/push 형태와 같이 명사형으로 정의가 될 수 있다. 물론 모든 형태의 명령이 이런 형태로 정의가 가능한 것은 아니지만, 되도록이면 리소스 기반의 명사 형태로 정의를 하는게 REST형태의 디자인이 된다. 

REST API의 간단한 예제

그러면, 간단한 REST API의 예제를 살펴보도록 하자 간단한 사용자 생성 API를 살펴보면

1. 생성

다음은 http://localhost/users 라는 리소스를 이름은 sanghyun, 취미는 game 이라는 내용(메시지)로 HTTP Post를 이용해서 생성하는 정의이다. 

HTTP Post, http://localhost/users/


1
2
3
4
{  
   "name":"sanghyun",
   "hobby":"game"
}
cs

2. 조회

생성된 리소스 중에서 http://localhost/users 라는 사용자 리소스중에, id가 sanghyun인 사용자 정보를 조회해오는 방식이다. HTTP Get을 사용한다.

HTTP Get, http://localhost/users/sanghyun



3. 업데이트

http://localhost/users 라는 사용자 리소스중에, id가 sanghyun인 사용자 정보에 대해서, 취미를 “piano”로 수정하는 방식이다. 수정은 HTTP 메서드 중에 PUT을 사용한다.

HTTP PUT, http://localhost/users/sanghyun


1
2
3
4
{  
   "name":"sanghyun",
   "hobby":"piano"
}
cs


4. 삭제

http://localhost/users 라는 사용자 리소스중에, id가 sanghyun 사용자 정보를 삭제 한다.

HTTP DELETE, http://localhost/users/sanghyun



API 정의를 보면 알겠지만 상당히 간단하다. 단순하게 리소스를 URI로 정해준 후에, 거기에 HTTP 메서드를 이용해서 CRUD를 구현하고 메시지를 JSON으로 표현하여 HTTP Body에 실어 보내면 된다. POST URI에 리소스 id가 없다는 것을 빼면 크게 신경쓸 부분이 없다. 


HTTP


Web-Browser(브라우저)같은 응용프로그램을 통해 


Web-Client(사용자)와 Web-Server(서비스제공자)사이 


데이터를 전송하는 프로토콜이다.



1. HTTP는 TCP/IP를 이용하는 응용 프로토콜이다.


   컴퓨터와 컴퓨터 간 데이터 전송


2. HTTP는 연결 상태를 유지하지 않는 프로토콜이다.


   연결이 지속적이지 않기에 Web-Client와 연결 종료 후


   추가적인  Web-Client의 요청시 어떤 Web-Client이 요청인지 모른다는 점 발생해


   Cookie, Session, URL Rewriting, Hidden Form Field로 해결



   HTTP와 반대로 연결 상태 유지는 프로토콜은 FTP, Telnet이 있다.(TCP/IP)

   


3. HTTP는 연결 상태를 유지하지 않는 프로토콜이기 때문에 


   요청/응답(request/response)방식으로 동작한다.


   


참고 :


https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4

http://bcho.tistory.com/953

'전체 > 개발지식' 카테고리의 다른 글

Spring 개발 구성 및 파일 디렉토리 구조  (0) 2018.10.04
open <tag> in XML mapper - mybatipse plugin 사용하기  (3) 2018.02.21
Servlet 정의  (0) 2017.05.15
Maven을 쓰는이유  (1) 2017.05.12
Mybatis를 쓰는 이유  (1) 2017.05.12


Spring MVC 구조


Spring MVC는 Servlet Container 안에 있는 Servlet 요소 중 하나이다.



Spring MVC(Model-View-Controller)의 핵심 Component는 아래와 같다.

Component개요
DispatcherServletSpring MVC Framework의 Front Controller, 웹요청과 응답의 Life Cycle을 주관한다.
HandlerMapping웹요청시 해당 URL을 어떤 Controller가 처리할지 결정한다.
Controller비지니스 로직을 수행하고 결과 데이터를 ModelAndView에 반영한다.
ModelAndViewController가 수행 결과를 반영하는 Model 데이터 객체와 이동할 페이지 정보(또는 View객체)로 이루어져 있다.
ViewResolver어떤 View를 선택할지 결정한다.
View결과 데이터인 Model 객체를 display한다.

이들 컴포넌트간의 관계와 흐름을 그림으로 나타내면 아래와 같다. 


  1. Client의 요청이 들어오면 DispatchServlet이 가장 먼저 요청을 받는다.
  2. HandlerMapping이 요청에 해당하는 Controller를 return한다.
  3. Controller는 비지니스 로직을 수행(호출)하고 결과 데이터를 ModelAndView에 반영하여 return한다.
  4. ViewResolver는 view name을 받아 해당하는 View 객체를 return한다.
  5. View는 Model 객체를 받아 rendering한다.

Bean


Bean(빈)이란 개발자가 생성하지 않고 Spring이 관리하는 인스턴스이다. 


Spring이 제공하는 Container를 통해서 관리되는 인스턴스를 우린 Bean이라고 부른다.


POJO

POJO는 Plain Old Java Object의 약자인데 그 어느 곳에도 종속되지 않은 (즉, 상속받지도, 구현하지도 않은 독립적인) Java Class를 말한다.



IOC 


이전의 방식

main()에서 시작할 때 사용할 객체를 결정, 객체 내의 메소드 호출 작업 일반적

오브젝트가 프로그램 흐름 결정한다.


IOC 방식

IOC는 자신이 사용할 오브젝트를 스스로 생성하거나 선택하지 않는다.

자신이 어떻게 만들어지고 어디서 사용되는지 모른다.

모든 제어 권한을 자신이 아닌 다른 대상에게 위임한다.



DL(Dependency Lookup)


저장소에 저장되어 있는 빈에 접근하기 위해 컨테이너에서 제공하는 API 이용해 사용하고자 하는 빈을 LOOKUP 하는 것


DI(Dependency Injection)


각 계층, 클래스 사이 필요로 하는 의존관계 컨테이너가 자동으로 연결해준다.

각 클래스 사이 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해준다.

DL 사용시 컨테이너 종속성 증가하여 이를 줄이기 위해 DI 사용한다.


각 class/객체 사이의 의존관계를 빈 설정 정보를 바탕으로 container가 자동적으로 연결해 주는 것을 말한다. 


따라서 lookup과 관련된 코드들이 오브젝트 내에서 완전히 사라지고 컨테이너에 의존적이지 않은 코드를 작성할 수 있다. 


단지 빈 설정 파일에서 의존관계가 필요하다는 정보를 추가하면 된다.


Spring container 에서 지원한다. 스프링의 경우 초기 빈 Lookup을 제외하면 의존성이 항상 Injection 형태의 IoC를 사용하게 된다.





1. Mybatis란 무엇인가?


사실 JDBC라는 개념부터 알아야한다.

JDBC란 Java에서 DB와 연동하고 쓰기위해 사용하는 API이다.


JDBC는 DB 연동에 필수적으로 사용하는 것인데


이 JDBC만 사용해서 DB 쿼리문을 작성하면 java소스와 쿼리소스가 겹치게 되고 관리가 어려워진다.


Mybatis는 SQL 쿼리문을 xml 형식의 파일로 분리시켜 저장관리할 수 있고 java소스에서 xml 태그의 id만 호출하며 개발의 편리함을 제공한다.


Mybatis는 xml형식의 쿼리파일을 저장 및 호출하는 역할을 내부적으로 처리하는 것이다.



2. 왜 쓰고 있나?


Mybatis 없었을 때 소스 방식


1
2
3
4
5
6
7
8
9
10
11
12
13
public Entity selectFAQList(UserConnection conn, Entity param) throws SQLException {
    UserStatement stmt = null;
    ResultSet rslt = null;
    StringBuffer sql = new StringBuffer();
    sql.append("\n SELECT *");
    sql.append("\n FROM");
    sql.append("\n TABLE1");
    stmt = conn.prepareStatement(sql.toString());
    rslt = stmt.executeQuery();
    Entity _DATA = new Entity();
    _DATA.put("_DATA", EntityUtil.ResultSetToClobList(rslt));
    return _DATA;
}
cs


소스를 보면 .java 파일안에 StringBuffer라는 클래스를 호출해 sql이라는 객체를 만들어 문자를 계속 이어주면서 sql query를 작성하고 있다.


다 작성한 다음 작성 된 쿼리를 다른 메소드의 파라미터로 넘기고 리턴하고 있다.


이러한 방식은 쿼리가 수정될 때 마다 계속 .java에 들어가 .append() 메소드를 추가하고 저장해 유지보수가 힘들고 sql query구문의 분리가 어려지고 복잡해진다.


또한 쿼리 양이 많아질수록 .java에는 자바코드 뿐만아니라 쿼리코드로 인해 양이 방대해지는 문제가 발생한다.


아 이래선 도저히 안된다. 유지보수도 해야되고 추가개발도 해야되므로 sql구문과 java코드의 분리 필요성을 느끼게 된다.


Mybatis 적용 후 소스 방식


1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
  <ENTITY id="table.getTable1List" type="SQL" return="List">
    <![CDATA[
        SELECT *
            FROM
            TABLE1
    ]]>
    <PARAMS>    
    </PARAMS>
  </ENTITY>
cs


xml로 빼내서 쿼리문을 작성하면 내부적 처리는 Mybatis에서 모두 처리해주므로


Entity Id 값을 java에서 호출만하면 된다. 





Jquery의 ajax() 사용시 url type 호출방법으로 GET, POST 방법 등을 쓰게 되는데 


다음 소스와 같이 직접적으로 url에 넣어 통신을 할 경우 access-control-allow-origin 크로스 도메인 이슈가 발생하게 됩니다.



1
2
3
4
5
6
7
8
9
$(document).ready(function(){
    var seoul = ['http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1159063000']
        $.ajax({
            url : seoul[i],
            type : "GET",
            success : function(xml){
            }
        });
});
cs


해결방법으로는 클라이언트에서 처리하는 방법과 서버에서 처리하는 방법이 있는데


클라이언트에서 처리하는 방법을 사용할 시 서비스를 사용하는 사용자에게 플러그인을 모두 깔아서 보게하거나 설정해야 할 일이 생겨


서버쪽에서 처리해주어야 합니다.



제가 해결한 방법으로는 controller를 만들어 해결하는 것입니다.


저는 get방식으로 컨트롤러를 태워 기상청 RSS 데이터 XML을 파싱해 가져오려고 합니다.


servlet을 통해 다음과 같이 어노테이션을 주어 컨트롤러로 이동시킵니다.



1
2
3
4
5
6
7
8
9
10
$(document).ready(function(){
 
        $.ajax({
            url : 'get.do',
            type : "GET",
            success : function(xml){
            }
        });
 
});
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@WebServlet("/get.do")
public class Test1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public Test1() {
        super();
    }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String addr = "http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1159063000";
        URL url = new URL(addr);
        
        
        InputStream in = url.openStream(); 
        CachedOutputStream bos = new CachedOutputStream();
        IOUtils.copy(in, bos);
        in.close();
        bos.close();
        
        String data = bos.getOut().toString();        
        out.println(data);
     }
}
cs


다음과 같이 작성하여


controller를 통해 데이터를 받게되면 클라이언트에서 크로스 도메인 이슈가 나타나지 않습니다.


+ Recent posts