'Back-End'에 해당되는 글 287건

  1. 2019.06.27 Spring API ( HttpServletRequest, HttpServletResponse )
  2. 2019.06.27 인터셉터 (Interceptor)
  3. 2019.06.27 기본 용어 정리
  4. 2019.06.27 무결성이란?
  5. 2019.06.27 Spring API (@RequestBody와 ResponseEntity의 차이점)
  6. 2019.06.26 AOP와 트랜잭션 처리 실습 (코드로 테스트)
  7. 2019.06.26 http 응답 코드와 method의 종류
  8. 2019.06.24 AOP와 트랜잭션 처리 실습 (데이터베이스로 테스트)

Spring API ( HttpServletRequest, HttpServletResponse )

Back-End/API 2019. 6. 27. 18:19

-HttpServletRequest-


HttpServletRequest를 사용하면, 그 안에 있는 값을 받아올 수 있다.


예를 들어, 아이디, 비밀번호 등의 데이터를 컨트롤러로 보냈을 때,


HttpServletRequest 객체 안에 모든 데이터들이 들어가게 된다.



원하는 데이터를 꺼낼 때는 HttpServletRequest 객체 안의 메소드를 이용하면 된다.


getParameter( )



getParameter( ) 메소드는 반환타입이 String 타입이다.



예를 들어,


String id = httpServletRequest.getParameter("id");


httpServletRequest안에 있는 id값을 String타입으로 가져온다.




출처

https://hongku.tistory.com/118



==================================================================================================



-HttpServletResponse-


클라이언트에 데이터를 전송하기 위해서 사용함, 


이를 위하여 Response 객체의 setContentType( ) 와 getWriter( ) 메소드를 이용한다.


그 다음에 html을 작성하거나 다른 컨텐츠를 기록하거나 하는 I/O 작업을 하면 된다.


이 외에도 헤더 정보를 설정하거나, 오류를 발생시키거나, 쿠키를 추가할 때도 Response 객체를 사용한다.




 > jar파일을 전송한다면..

 public class CodeReturn extends HttpServlet{

 public void doGet(HttpServletRequest request, HttpServletResponse reponse) throws IOException{

response.setContentType("application/jar");    //MIME타입. 외우지말자

ServletContext ctx = getServletContext();

InputStream is = ctx.getResourceAsStream("/book.jar");  // 이 코드를 풀어보면 입력스트림으로  book.jar을 주세요.

                                                                                                // 인자값은 반드시 /로 시작.

OutputStream os = response.getOutputStream();

byte[] bytes = new byte[1024];

while(true){

int count = is.read(bytes);

out.write(bytes,0,count);

if(bytes == -1){

break;

}

}

os.flush();

os.close();

}




출처

https://mkkbest.tistory.com/entry/HttpServletRequest-%EA%B0%9D%EC%B2%B4-HttpServletResponse-%EA%B0%9D%EC%B2%B4

:

인터셉터 (Interceptor)

Back-End/Spring 2019. 6. 27. 17:56

- Interceptor (인터셉터) -



  클라이언트의 요청 전,후에 특정 작업을 처리하고자 할 때 사용하는 기능 (간단하게 컨트롤러 같은 계층이라고 생각하면 됨)


  매개변수 - HttpServletRequest, HttpServletResponse

  

  용도 - 로그인 처리, pc웹 / 모바일웹 분기 처리 등

  

  


  Filter : 인코딩 처리할때 사용 (예를 들면 한글 인코딩 필터), 필터는 선처리만 된다.

  

  Interceptor : AOP의 @Around와 비슷한 성격이다, 하지만 AOP는 메소드 단위 (코드)로 설정하고, 인터셉터는 특정한 URL 단위로 설정한다.

  

  html 페이지는 웹서버에서 별도의 처리를 하지 않고, 그대로 클라이언트에게 전달된다.


  jsp 페이지는 JspServlet를 경유하여 html로 변환된 후 클라이언트에게 전달됩니다.

 

  Spring Framework에서는 DispatchereServlet을 경유하여 처리됩니다.


  인터셉터는  Filter (필터) - DispatcherServlet 이전에 실행되며 선처리만 가능합니다.

  

  

  AOP - @Around => ProceedingJoinPoint


@Before, @After => JoinPoint


  실행순서 : 1. Filter > 2. DispatcherServlet > 3. Interceptor > 4. AOP



-예제 1. 특정한 url에 대해서 인터셉터가 실행되는지 확인.-

  

SampleInterceptor.java

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
package com.example.spring02.interceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
// HandlerInterceptorAdapter 를 상속받음(추상클래스)
public class SampleInterceptor 
    extends HandlerInterceptorAdapter {
    //로깅을 위한 변수
    private static final Logger logger
        = LoggerFactory.getLogger(SampleInterceptor.class);
    
    
    //선처리와  후처리는 필수가 아니므로 원하는곳에서 작업을 하면 된다.
    
    
    
//선처리
    @Override
    //preHandle는 메인 요청 전에 경유하는 메소드
    public boolean preHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler) 
                    throws Exception {
        logger.info("pre handle...");
        return true//true이면 계속 진행, false이면 멈춤
    }
//후처리
    @Override
    //postHandle는 메인 요청이 끝난 다음에 경유하는 메소드 
    public void postHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        logger.info("post handle..."); 
    }
}
 
 
cs



servlet - context 인터셉터 관련 설정



  먼저 인터셉터를 bean으로 설정한 후


  <beans : bean id = "인터셉터의 아이디" class = "인터셉터의 경로" />




  

  어떤 url을 호출했을 때 인터셉터를 작동시킬 것인지 설정해야 합니다.


  <interceptors>

  <interceptor>

  <mapping path = "/shop/**"/>

  <beans:ref bean = "인터셉터의 아이디"/>

  </interceptor>

  </interceptors>




servlet-context.xml

(인터셉터 관련 빈을 등록하고 shop 하위 모든 url에 인터셉터를 적용)

=> 즉, shop 하위 url이 실행될때 인터셉터 빈에 등록된 클래스가 실행된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
<!-- 인터셉터 빈을 등록 -->
 
<beans:bean id = "sampleInterceptor" class = "com.example.spring02.interceptor.SampleInterceptor" />
    <interceptors>
        <interceptor>
 
        <!-- 인터셉터의 매핑 정보 -->
    
        <!-- shop 하위 url에 인터셉터를 적용 -->
 
            <mapping path="/shop/**" />
            <beans:ref bean="sampleInterceptor" /> //아이디를 참조하는 것이기 때문에 bean id와 ref bean은 같아야 한다.
    </interceptor>
</interceptors>
cs



코드를 추가하고 서버를 돌리고 로그를 확인해보면 pre handle와  post handle 사이에 인터셉터가 실행된 것을 확인할 수 있다.



==============================================================================================



예제 2. 


views / include / session_check.jsp


인터셉터를 사용하지 않고 세션의 존재 여부를 체크하는 코드를 작성할 경우 아래와 같이 처리한다.


  

  shop하위의 페이지로 넘어갈때 서블릿에 인터셉터를 빈으로 등록해놓으면 장바구니를 클릭할때 


  인터셉터에서 로그인 여부를 판단해서 작업을 처리한다.




원래는 컨트롤러에서 처리를 해도 된다

관리자 전용 페이지의 세션 체크

http://localhost:8080/spring02/shop/product/write.do


write.jsp파일에 다음 코드를 추가



  

  <%@ page language = "java" contentType = "text/html; charset=UTF-8" pageEncoding = "UTF-8"%>

  <!--views/include/session_check.jsp -->

  <%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>

  <c:if test = "${sessionScope.admin_userid == null}" >   // 세션을 체크했을때 null값과 같으면 (로그인을 안했다면)..

      <script>

           alert("로그인 하신 후 사용하세요.");                  // 다음 메시지를 출력함..

           location.href = "${path}/admin/login.do";          // 로그인 페이지로 이동시켜주는 코드

      </script>

  </c:if>




LoginInterceptor.java

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
package com.example.spring02.interceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
 
//HandlerInterceptorAdapter 추상클래스 상속
// preHandle(), postHandler() 오버라이딩
 
public class LoginInterceptor 
    extends HandlerInterceptorAdapter {
    
    
    //로그인을 하기전에 로그인이 되어있는 상태인지 검사하고 로그인이 되어있으면
    //메인 액션으로 이동하고, 로그인이 안되어있으면 로그인 페이지로 이동시킨다.
    //메인 액션이 실행되기 전 실행되는 메소드

    @Override
    public boolean preHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler) 
                    throws Exception {
        //세션 객체 생성
        HttpSession session=request.getSession();
        
        //세션이 없으면(로그인되지 않은 상태)
        if(session.getAttribute("userid"== null) {
            
            //login 페이지로 이동
            response.sendRedirect(request.getContextPath()
                    +"/member/login.do?message=nologin");
            return false//메인 액션으로 가지 않음
        }else {
            return true//메인 액션으로 이동
        }
    }
    
    //메인 액션이 실행된 후 실행되는 메소드
    @Override
    public void postHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }
}
cs


이 인터셉터를 적용하기 위해 태그를 선언해야 한다.


servlet - context.xml

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
<!-- 인터셉터 빈을 등록 -->
    <beans:bean id="sampleInterceptor" //id에는 클래스이름에다가 첫글자만 소문자로 된 것을 많이 사용한다.
class="com.example.spring02.interceptor.SampleInterceptor"> //클래스에는 정확한 경로를 적어야 한다.
    </beans:bean>
    <beans:bean id="loginInterceptor"
class="com.example.spring02.interceptor.LoginInterceptor">
    </beans:bean>
    <beans:bean id="adminInterceptor"
class="com.example.spring02.interceptor.AdminInterceptor" />
 
<!-- 인터셉터 호출을 위한 url mapping -->
 
    <interceptors>
        <interceptor>
        <!-- 인터셉터의 매핑 정보 -->    
        <!-- shop 하위 url에 인터셉터를 적용 -->
            <mapping path="/shop/**" />
            <beans:ref bean="sampleInterceptor" />
        </interceptor>

        <interceptor>
//그러니까 아래와 같은 url로 (list.do, insert.do) 접속했을때 loginInterceptor를 적용시키라는 의미.
            <mapping path="/shop/cart/list.do"/>
            <mapping path="/shop/cart/insert.do"/>
            <beans:ref bean="loginInterceptor"/>
        </interceptor>

    <!-- 관리자 세션 체크를 위한 인터셉터 설정 -->

        <interceptor>
            <mapping path="/shop/product/write.do"/>
            <mapping path="/shop/product/insert.do"/>
            <beans:ref bean="adminInterceptor" />
        </interceptor>

    </interceptors>
cs



인터셉터를 만들어놓으면 컨트롤러마다 세션을 만들지 않아서 되서 편리하다.



3. 관리자 로그인을 체크할 수 있는 인터셉터 만들기


AdminInterceptor.java

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
package com.example.spring02.interceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

// HandlerInterceptorAdapter 추상클래스 상속
// preHandle(), postHandle() 오버라이딩

public class AdminInterceptor 
    extends HandlerInterceptorAdapter {
    
    //로그인 실행전 처리하는 메소드
    //세션에 저장되어있는 id가 null이면 로그인 페이지로 이동하고,
    //세션에 저장되어 있는 id가 있으면 메인 액션으로 이동함

    @Override
    public boolean preHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler) 
                    throws Exception {
        //세션 객체 생성
        HttpSession session=request.getSession();
        //세션변수 admin_userid가 없으면
        if(session.getAttribute("admin_userid")==null) {
            //로그인 페이지로 이동
            response.sendRedirect(request.getContextPath()
                    +"/admin/login.do?message=nologin");
            //메인 액션으로 이동하지 않음
            return false;
        }else {
            //세션 변수가 있으면 메인 액션으로 이동
            return true;
        }
    }

    //후처리
    @Override
    public void postHandle(HttpServletRequest request
            , HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }
}
cs



servlet-context.xml 중 일부 (인터셉터 매핑 url 추가, chart랑 jchart도 관리자만 사용할 수 있게끔)

1
2
3
4
5
6
7
8
9
10
       <!-- 관리자 세션 체크를 위한 인터셉터 설정 -->
 
        <interceptor>
            <mapping path="/pdf/list.do"/>
            <mapping path="/shop/product/write.do"/>
            <mapping path="/shop/product/insert.do"/>
            <mapping path="/chart/**" />
            <mapping path="/jchart/**" />
            <beans:ref bean="adminInterceptor" />
        </interceptor>
cs



프로젝트를 실행하면 관리자 로그인을 한 상태에서만 차트와 j차트를 볼 수 있게끔 하고, 관리자 로그인이 안되어 있으면 관리자 로그인창이 출력된다.

:

기본 용어 정리

Back-End/Data Base 2019. 6. 27. 12:20

 

 용어


 설명

 Table

 데이터 값들의 집합을 뜻한다. 

 Row

 Table 내에서 한 줄에 해당하는 데이터 값들. (=Tuple 와 동일한 단어) 

 Column

 

 Table에서 데이터가 갖는 속성값. (=attribute와 동일한 단어)


 예시) 상단의 "설명" 이 column에 해당한다.


 Domain

 

 도메인은 하나의 Attirbute가 취할 수 있는 같은 타입의 원자 (Atomic)


 값들의 집합


 Attribute

 

 파일 구조상의 데이터 항목 또는 데이터 필드에 해당된다.


 속성 (Attribute)는 개체의 특성을 기술한다.


 Tuple

 Table (Relation) 을 구성하는 각각의 행을 뜻한다.

 Cardinality

 도메인에 있는 모든 값들의 갯수 



출처

https://jhkang-tech.tistory.com/6

'Back-End > Data Base' 카테고리의 다른 글

오라클 반복문 (for loop, while loop)  (0) 2019.07.03
오라클 변수 선언  (0) 2019.07.03
무결성이란?  (0) 2019.06.27
오라클 SQL Develope 다운로드 및 설치  (0) 2019.05.28
19.05.05 데이터베이스 성능  (0) 2019.05.05
:

무결성이란?

Back-End/Data Base 2019. 6. 27. 12:14

무결성이란?


무결성이란 데이터베이스에 저장된 데이터 값과 그것이 표현하는 현실 세계의 실제값이 일치하는 정확성을 의미한다.



무결성을 유지하는 방법


대표적으로 사용되는 방법은 중앙 통제에 의한 데이터 갱신으로서, 이 방법은 검증 프로그램을 이용하여 모든 갱신 처리 과정에서 


반드시 검증 단계를 거치도록 통제를 가한다.


검증 프로그램이 무결성을 검증하기 위해 무결성 규정을 사용한다.




 규정이름 : 무결성 규정을 참조할 때 사용하는 식별자


 트리거조건 : 트랜잭션의 접근 유형 및 데이터, 검사할 시기를 명시


 제약조건 : 무결성을 위한 검사조건


 위반조치 : 검사결과 무결성 위반이 발견되었을 때 처리할 조치





 

 -무결성의 종류-


 NULL 무결성 : 릴레이션의 특정속성 값이 NULL이 될 수 없도록 하는 규정


 고유 무결성 : 릴레이션의 특정 속성에 대해서 각 튜플이 갖는 값들이 서로 달라야 한다는 규정


 참조 무결성 : 외래키 값은 NULL 이거나 참조 릴레이션의 기본키 값과 동일해야 한다는 규정 즉 릴레이션은 참조할 수 없는 외래키 값을

  가질 수 없다는 규정


 도메인 무결성 : 특정 속성의 값이, 그 속성이 정의된 도메인에 속한 값이어야 한다는 규정


 키 무결성 : 하나의 테이블에는 적어도 하나의 키가 존재해야 한다는 규정






 

 -무결성 제약조건-


 데이터베이스에 들어있는 데이터의 정확성 (일관성)을 보장하기 위해 부정확한 자료가 데이터베이스 내에 저장되는 것을 

 방지하기 위한 제약 조건을 의미함



 개체 무결성


 릴레이션에서 기본키를 구성하는 속성은 Null값이나 중복값을 가질 수 없다.



 참조 무결성


 외래키 값은 Null이거나 참조 릴레이션의 기본키 값과 동일해야 한다.

 즉, 릴레이션은 참조할 수 없는 외래키 값을 가질 수 없다. 

 외래키와 참조하려는 테이블의 기본키는 도메인과 속성개수가 같아야 한다.



'Back-End > Data Base' 카테고리의 다른 글

오라클 변수 선언  (0) 2019.07.03
기본 용어 정리  (0) 2019.06.27
오라클 SQL Develope 다운로드 및 설치  (0) 2019.05.28
19.05.05 데이터베이스 성능  (0) 2019.05.05
19.05.04 백업과 복구  (0) 2019.05.04
:

Spring API (@RequestBody와 ResponseEntity의 차이점)

Back-End/API 2019. 6. 27. 11:43

Spring API (@RequestBody와 ResponseEntity의 차이점)


 

Spring에서는 HttpEntity란 클래스를 제공하는데 이 클래스의 역할은 Http 프로토콜을 이용하는 통신의 header과


body 관련 정보를 저장할 수 있게끔 합니다. 그리고 이를 상속받은 클래스로 RequestEntity와 ResponseEntity가

존재한다.

즉, 통신 메시지 관련 header과 body의 값들을 하나의 객체로 저장하는 것이 HttpEntity 클래스 객체이고,

Request 부분일 경우 HttpEntity를 상속받은 RequestEntity가, Response 부분일 경우 HttpEntity를 상속받은

ResponseEntity가 하게 됩니다.

@ResponseBody나 ResponseEntity를 return 하는거나 결과적으로는 같은 기능이지만.. 그 구현 방법이 틀리다.

예를 들어 header 값을 변경시켜야 할 경우엔 @ResponseBody의 경우 파라미터로 Response 객체를 받아서

이 객체에서 header를 변경시켜야 하고,.. ResponseEntity에서는 이 클래스 객체를 생성한뒤 객체에서

header 값을 변경시키면 된다.

자세한것은 Spring API 문서를 참고하면 된다.




ResponseEntity API


1
2
3
4
5
6
7
8
9
public class ResponseEntity<T> extends HttpEntity<T> {
 
    private final Object status;
 
 
    /**
     * Create a new {@code ResponseEntity} with the given status code, and no body nor headers.
     * @param status the status code
     */
cs




@RequestBody API


1
2
3
4
5
6
7
8
9
10
11
12
13
public @interface RequestBody {
 
    /**
     * Whether body content is required.
     * <p>Default is {@code true}, leading to an exception thrown in case
     * there is no body content. Switch this to {@code falseif you prefer
     * {@code null} to be passed when the body content is {@code null}.
     * @since 3.2
     */
    boolean required() default true;
 
}
cs


'Back-End > API' 카테고리의 다른 글

Spring API (@RequestMapping이 사용하는 속성)  (0) 2019.06.30
Spring API ( HttpServletRequest, HttpServletResponse )  (0) 2019.06.27
스프링 AOP JoinPoint 객체  (0) 2019.06.23
서블릿 API  (0) 2019.04.30
java.io 패키지  (0) 2019.04.21
:

AOP와 트랜잭션 처리 실습 (코드로 테스트)

Back-End/Spring 2019. 6. 26. 17:52

-AOP 실습예제-


사용자가 메시지를 남기면 포인트 10 증가


메시지를 읽으면 포인트 5 증가


글쓰기를 하면 포인트 10을 부여


글읽기를 하면 열람시간을 수정하고 포인트 5를 부여


뷰는 따로 만들지 않고 크롬의 확장 프로그램을 이용해서 보냄



  

  com.examplt.spring02.aop

  ㄴMessageAdvice.java


  com.example.spring02.controller.message

  ㄴMessageController.java


  com.example.spring02.model.message.dto

  ㄴUserDTO.java

  ㄴMessageDTO.java


  com.example.spring02.model.message.dao

  ㄴMessageDAO.java

  ㄴMessageDAOImpl.java

  ㄴPointDAO.java

  ㄴPointDAOImpl.java


  com.example.spring02.service.message

  ㄴMessageService.java

  ㄴMessageServiceImpl.java




AOP 용어 정리


아래 용어들은 Spring에서만 사용되는 용어들이 아닌 AOP 프레임워크 전체에서 사용되는 공용어입니다.




 타겟 (Target)


 부가기능을 부여할 대상을 의미한다.


 여기선 핵심기능을 담당하는 getBoards 혹은 getUsers를 하는 Service들을 의미한다.

 

 

 애스팩트 (Aspect)


 객체지향 모듈을 오브젝트라 부르는 것과 비슷하게 부가기능 모듈을 애스펙트라고 부르며, 핵심기능에 부가되어 의미를 갖는 특별한 모듈이라


 생각하면 된다.


 애스팩트는 부가될 기능을 정의한 어드바이스와 어드바이스를 어디에 적용할지를 결정하는 포인트컷을 함께 갖고 있습니다.


 AOP(Aspect Oriented Programiming) 라는 뜻 자체가 어플리케이션의 핵심적인 기능에서 부가적인 기능을 분리해서 애스팩트라는 모듈로 


 만들어서 설계하고 개발하는 방법을 의미한다.

 

 

 어드바이스 (Advice)


 실질적으로 부가기능을 담은 구현체를 의미합니다.


 어드바이스의 경우 타겟 오브젝트에 종속되지 않기 때문에 순수하게 부가기능에만 집중할 수 있습니다.


 어드바이스는 애스펙트가 '무엇' 을 '언제' 할지를 정의하고 있습니다.



 포인트컷 (PointCut)


 부가기능이 적용될 대상 (메소드) 를 선정하는 방법을 얘기합니다.


 즉, 어드바이스를 적용할 조인포인트를 선별하는 기능을 정의한 모듈을 얘기합니다.



 조인포인트 (JoinPoint)


 어드바이스가 적용될 수 있는 위치를 얘기합니다.


 다른 AOP 프레임워크와 달리 Spring에서는 메소드 조인포인트만 제공하고 있습니다.


 따라서 Spring 프레임워크 내에서 조인포인트라 하면 메소드를 가리킨다고 생각해도 된다.


 

 프록시 (Proxy)


 타겟을 감싸서 타겟의 요청을 대신 받아주는 랩핑(Wrapping) 오브젝트 입니다.


 호출자 (클라이언트)에서 타겟을 호출하게 되면 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 

 

 타겟 메소드 실행전에 선처리, 타겟 메소드 실행 후, 후처리를 실행시키도록 구성되어있습니다.



  

  (AOP에서 프록시는 호출을 가로챈 후, 어드바이스에 등록된 기능을 수행 후 타겟 메소드를 호출합니다.)
















MessageDTO.java (메시지 저장 DTO 클래스)

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
.package com.example.spring02.model.message.dto;
 
import java.util.Date;
 
public class MessageDTO {
    
    //메시지 저장 DTO 클래스
    
    private int mid; 
    private String targetid;
    private String sender;
    private String message;
    private Date opendate; //java.util.Date
    private Date senddate;
    
    //getter,setter,toString()
    
    public int getMid() {
        return mid;
    }
    public void setMid(int mid) {
        this.mid = mid;
    }
    public String getTargetid() {
        return targetid;
    }
    public void setTargetid(String targetid) {
        this.targetid = targetid;
    }
    public String getSender() {
        return sender;
    }
    public void setSender(String sender) {
        this.sender = sender;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Date getOpendate() {
        return opendate;
    }
    public void setOpendate(Date opendate) {
        this.opendate = opendate;
    }
    public Date getSenddate() {
        return senddate;
    }
    public void setSenddate(Date senddate) {
        this.senddate = senddate;
    }
    @Override
    public String toString() {
        return "MessageDTO [mid=" + mid + ", targetid=" + targetid + ", sender=" + sender + ", message=" + message
                + ", opendate=" + opendate + ", senddate=" + senddate + "]";
    }
    
}
cs




UserDTO (유저 정보 저장 DTO 클래스)

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
.package com.example.spring02.model.message.dto;
 
public class UserDTO {
    
    //사용자 정보 저장 DTO 클래스
    
    private String userid; //아이디
    private String upw;    //비밀번호
    private String uname; //이름
    private int upoint; //포인트
    
    //getter,setter,toString()
    public String getUserid() {
        return userid;
    }
    public void setUserid(String userid) {
        this.userid = userid;
    }
    public String getUpw() {
        return upw;
    }
    public void setUpw(String upw) {
        this.upw = upw;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public int getUpoint() {
        return upoint;
    }
    public void setUpoint(int upoint) {
        this.upoint = upoint;
    }
    @Override
    public String toString() {
        return "UserDTO [userid=" + userid + ", upw=" + upw + ", uname=" + uname + ", upoint=" + upoint + "]";
    }
    
}
 
cs




MessageDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.package com.example.spring02.model.message.dao;
 
import com.example.spring02.model.message.dto.MessageDTO;
 
public interface MessageDAO {
    
    //메시지 쓰기
    public void create(MessageDTO dto);
    
    //메시지 읽기
    public MessageDTO readMessage(int mid);
    
    //상태 변경
    public void updateState(int mid);
}
 
cs




MessageDAOImpl.java

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
.package com.example.spring02.model.message.dao;
 
import javax.inject.Inject;
 
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
 
import com.example.spring02.model.message.dto.MessageDTO;
import com.example.spring02.model.shop.dao.CartDAO;
 
@Repository //dao bean으로 등록
 
public class MessageDAOImpl implements MessageDAO {
 
    @Inject //의존관계 주입(Dependency Injection, DI)
    SqlSession sqlSession;
    
    @Override
    public void create(MessageDTO dto) { //메시지를 추가하는 메소드
        sqlSession.insert("message.create", dto);
    }
 
    @Override
    public MessageDTO readMessage(int mid) {
        return null;
    }
 
    @Override
    public void updateState(int mid) {
    }
 
}
 
cs



messageMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="message">
<!--메시지를 만들때 값을 집어넣는 쿼리문 -->
    <insert id="create">
        insert into tbl_message (mid,targetid,sender,message)
        values ( message_seq.nextval
                        , #{targetid}, #{sender}, #{message} )    
    </insert>
        
</mapper>
cs



메시지를 저장한 후에 포인트를 주기위한 Point 관련 인터페이스와 클래스를 만듦


PointDAO.java

1
2
3
4
5
6
.package com.example.spring02.model.message.dao;
 
public interface PointDAO {
    public void updatePoint(String userid, int point);
}
 
cs



PointDAOImpl.java

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
.package com.example.spring02.model.message.dao;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.inject.Inject;
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
 
@Repository //스프링에서 관리하게끔 하기 위해 bean 선언
public class PointDAOImpl implements PointDAO {
    
    @Inject //의존성을 주입
    SqlSession sqlSession;
    
    @Override
    public void updatePoint(String userid, int point) {
        Map<String,Object> map=new HashMap<>(); //두가지 타입의 값을 넣을때는 HashMap()사용
        map.put("userid", userid); //map안에 값들을 저장함
        map.put("point", point);
        //2개 이상의 값을 전달할 경우 - dto, map
        sqlSession.update("point.updatePoint", map); //네임스페이스와 id를 맞춰서 mapper 쿼리 실행
        
    }
 
}
 
 
cs



pointMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<!-- mappers/message/pointMapper.xml -->
 
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="point">
<!-- sqlSession.update("point.updatePoint", map); -->
    <update id="updatePoint">
        update tbl_user
        set upoint=upoint+#{point}
        where userid=#{userid}
    </update>
    <!-- 사용자의 아이디에 맞춰서 포인트를 올려주는 쿼리문 -->
    <!-- 변수 2개가 hashmap<>로 전달되었다. -->
    
</mapper>
cs




MessageSerivce.java

1
2
3
4
5
6
7
8
9
10
package com.example.spring02.service.message;
 
import com.example.spring02.model.message.dto.MessageDTO;
 
public interface MessageService {
    public void addMessage(MessageDTO dto); //메시지를 추가하는 메소드
    public MessageDTO readMessage(String userid, int mid); //메시지를 읽는 메소드
    
}
 
cs




-트랜잭션 처리 (거래 처리 단위)-


트랜잭션이 완료되지 않은 상태에서 에러가 발생할 경우 데이터에 오류가 발생함


트랜잭션의 특징중 일관성에 어긋나기 때문.


예를 들어 메시지는 전달되나 포인트는 안올라가는 문제가 발생할 수 있음.


이러한 문제를 예방하기 위해 @Transactional 어노테이션을 트랜잭션 메소드에 사용한다.


이 어노테이션을 사용하면 메소드 안에 있는 코드가 하나라도 에러가 발생할 시 rollback을 시켜버려서 트랜잭션의 일관성을 유지시켜준다.





-사전 설정-


1. 실습하기 전에 root-context.xml 파일의 네임스페이스의 tx (트랜잭션 처리를 할 수 있는 namespaces) 체크를 확인




2. root-context.xml에 트랜잭션 설정 코드가 있는지 확인


1
2
3
4
5
6
7
    <!-- 트랜잭션 관련 설정 -->
//dataSource에서 트랜잭션 관리자 역할을 할수있는 빈을 만든다.
//<tx:annotation-driven /> 이 태그는 아까 사용한 @Transactional을 인식할 수 있는 태그이다.

    <bean id="transactionManager" //변수명
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> //자료형
        <property name="dataSource" ref="dataSource" />
    </bean> //dataSource는 bean을 참조한다. (xml파일의 위쪽에 있음)

    <!-- 트랜잭션 관련 어노테이션을 자동 인식하는 옵션 -->

    <tx:annotation-driven /> //@Transaction 어노테이션을 인식할 수 있게 하는 태그
cs





MessageSerivceImpl.java

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
.package com.example.spring02.service.message;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.example.spring02.model.message.dao.MessageDAO;
import com.example.spring02.model.message.dao.PointDAO;
import com.example.spring02.model.message.dto.MessageDTO;
 
@Service //현재 클래스를 스프링에서 관리하는 bean으로 설정
public class MessageServiceImpl implements MessageService {
    
    //서비스는 dao보다 좀 더 큰 단위의 업무를 수행한다.
    //dao에서는 세부 단위 업무를 수행
    
//Inject는 각각 해야 함
//의존성을 주입해야할 DAO클래스가 2개이기때문에 반드시 각각한다.
    
    @Inject
    MessageDAO messageDao;
    
    @Inject
    PointDAO pointDao;
 
    
    //트랜잭션 처리 대상 method
    //이 어노테이션을 사용하는 메소드는 그 메소드안에 있는 명령이 모두다 실행이 되지
    //않으면 rollback을 시켜버린다.
    //트랜잭션의 일관성을 유지하기 위해.
    
    @Transactional //method 내부의 코드를 트랜잭션 (거래처리 단위)로 묶음
    @Override
    public void addMessage(MessageDTO dto) {
        
        //메시지를 테이블에 저장
        messageDao.create(dto);
        //메시지를 보낸 회원에게 10포인트 추가
        pointDao.updatePoint(dto.getSender(), 10); 
    }
 
    @Override
    public MessageDTO readMessage(String userid, int mid) {
        // TODO Auto-generated method stub
        return null;
    }
 
}
 
cs



이 예제를 진행할때는 jsp 페이지를 만들지 않는다.


원래는 만들어야 정상이지만,  이번에는 툴로 처리를 할 것이기 때문에 만들지 않는다.


@RestController을 사용해서 입력되는 데이터와 되돌려주는 데이터를 모두 json으로 처리한다.



MessageController.java

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
.package com.example.spring02.controller.message;
 
import javax.inject.Inject;
 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.example.spring02.model.message.dto.MessageDTO;
import com.example.spring02.service.message.MessageService;
 
@RestController //jsp파일을 사용하지 않고, 입력되는 데이터와 되돌려주는 데이터를 모두 json으로 처리한다.
@RequestMapping("messages/*"//공통적인 url mapping
public class MessageController {
    
    @Inject
    MessageService messageService;
    
    @RequestMapping(value="/", method=RequestMethod.POST)
    //post방식일때만 이 메소드가 실행되게 만들었다.
    
    public ResponseEntity<String> addMessage(
            @RequestBody MessageDTO dto){
        //json형식으로 자료가 입력될때 RequestBody 어노테이션을 사용한다.
        //RequestBody어노테이션을 DTO를 json형식으로 받는다는 뜻
        //즉 json(String)타입으로 들어오면 dto타입으로 변환해서 되돌려준다.
        
        ResponseEntity<String> entity=null;
        try {
            messageService.addMessage(dto);
            entity=new ResponseEntity<>("success",HttpStatus.OK);
            //ResponseEntiry<>는 메시지 (성공 or 실패)와 에러코드를 함께 출력하고 싶을때 사용하는 타입
        } catch (Exception e) { 
            //메시지 처리가 실패하면 실행되는 코드, 메시지와 에러코드를 출력
            e.printStackTrace();
            entity=new ResponseEntity<>(e.getMessage()
                    ,HttpStatus.BAD_REQUEST); //메시지 처리가 실패하면 메시지와 400에러를 출력시킨다.
        }
        return entity; //메시지와 에러코드를 같이 리턴한다. 그리고 되돌려주는 값도 json형식 으로 보낸다.
    }
}
cs



 서비스 쪽에 AOP 설정을 해서 전, 후에 처리가 어떻게 되는지 확인



 

 @Bean과 @Component의 차이


 @Bean의 경우 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용된다.


 ( 예를 들면 ObjectMapper의 경우 ObjectMapper Class에 @Component를 선언할 수는 없으니 ObjectMapper의 인스턴스를 생성하는 메소드를


 만들고 해당 메소드에 @Bean을 선언하여 Bean으로 등록한다.)


 반대로 개발자가 직접 컨트롤이 가능한 Class들의 경우엔 @Component를 사용한다.





MessageAdvice.java


@Before 어노테이션으로 MessageService.java 시작 전에는 로그 수집을 하고, 


@Around 어노테이션으로 MessageService.java 시작 전, 후에 실행시간을 체크한다.


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
package com.example.spring02.aop;
 
import java.util.Arrays;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
 
@Component // 기타 bean, 개발자가 직접 컨트롤이 가능한 class의 경우에 사용하는 어노테이션
 
@Aspect // aop bean - 공통 업무를 지원하는 코드
 
public class MessageAdvice {
 
    private static final Logger logger = LoggerFactory.getLogger(MessageAdvice.class);
    //MessageAdvice.class의 로그를 출력
    
    @Before( //핵심업무 수행전에 실행이 되는 어노테이션
            "execution(* "
            
//================================================================            
            
            + " com.example.spring02.service.message"
            + ".MessageService*.*(..))")
    
    // MessageSerivce로 시작하는 모든 클래스의 모든 메소드들, 모든파라미터들에 대해서
    // execution구문이 실행되기 전에 startLog메소드가 먼저 실행된다.
    
//================================================================
    
    //그러니까 메시지 서비스 시작하기 전에는 로그수집을 한다.
    public void startLog(JoinPoint jp) {                            //execution구문이 실행되기 바로 전에 호출됨
                                                                    //joinPoint는 advice를 적용 가능한 지점을 의미한다.
                                                                    //메소드 호출, 필드 값 변경 등이 Joinpoint에 해당한다.
        
        logger.info("핵심 업무 코드의 정보:" +jp.getSignature());             //시그니처의 값을 반환
        
        logger.info("method:" +jp.getSignature().getName());        //시그니처의 이름을 반환
        
        logger.info("매개변수:" +Arrays.toString(jp.getArgs()));        //클라이언트가 메소드를 호출할 때 넘겨준 인자 목록을 Object 배열로 리턴함
    }
    
    @Around( //호출 전 후에 실행 되게끔하는 어노테이션
            "execution(* "
            + " com.example.spring02.service.message"
            + ".MessageService*.*(..) )")
    public Object timeLog(ProceedingJoinPoint pjp) throws Throwable {//MessageService 시작 전후로는 시간체크를 한다.
        
        //호출 전(Before)
        long start=System.currentTimeMillis(); //long타입의 값이며, 1/1000초의 값을 리턴한다. 정확한 시간을 측정할때 사용
        
//=========================================================
        
        Object result=pjp.proceed();
        
        //이 구문을 기준으로 위쪽은 호출 전이고, 아래쪽은 호출 후 이다.
        
//=========================================================
        
        //호출 후(After)
        long end=System.currentTimeMillis();                          //long타입의 값이며, 1/1000초의 값을 리턴한다. 정확한 시간을 측정할때 사용
        logger.info(pjp.getSignature().getName()+":"+(end-start));    //시그니처의 이름과 실제 실행한 시간을 로그로 찍는다.
        logger.info("=================");                             //
        return result;                                                
    }
}
cs



(실습 방법)


이번 실습에서는 뷰 (view)를 별도로 만들지 않고 Advanced REST client 확장 프로그램으로만 테스트를 수행합니다.


method : POST


Request URL : http://localhost/spring02/messages/


Body > Body content type > application/json


     Editor view > Raw input





  

  Advanced REST client 확장 프로그램 설치


  (파라미터를 사용해서 컨트롤러로 값을 보낼 수 있음)


  구글 검색창에 Advanced REST client 검색


  




  




일단 입력 데이터를 json으로 보내기 위해 사용해보기


put : 전체 수정


delete : 삭제


patch : 일부분 수정


Method : POST


Request URL : http://localhost/spring02/message/Body


Body content type : application/json


Editor view : Raw input


다음 처럼 설정하고 json 코드를 작성




json 코드 작성하고 send버튼을 누른다.


1
2
3
4
5
{
"targetid" : "user01", //"변수" : "값" 형식이다, 즉, "targetid" 변수의 값은 "user01" 이다.
"sender" : "user02",
"message" : "Good morning"
} // 해석 : user02가 user01에게 "Good morning" 메시지를 보낸다는 뜻.
cs


하단에 200 OK버튼이 뜨면 정상적으로 처리된 것이다.


MessageController.java (메시지 컨트롤러)

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
package com.example.spring02.controller.message;
 
import javax.inject.Inject;
 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.example.spring02.model.message.dto.MessageDTO;
import com.example.spring02.service.message.MessageService;
 
@RestController    //json을 리턴하는 method가 있는 경우에는 RestController을 사용
 
@RequestMapping("messages/*"//공통적인 url mapping
 
 
//메시지를 추가할때 맵핑되는 컨트롤러
 
 
public class MessageController {
    
    
    @Inject
    MessageService messageService;    //서비스를 호출하기위해 의존성을 주입한다.
    
    
    @RequestMapping(value="/", method=RequestMethod.POST) //POST방식의 메소드와 맵핑
    
    public ResponseEntity<String> addMessage(
             
            //    크롬 ARC를 사용해서 데이터를 보냈는데 String타입이기때문에 dto에 저장하려면
            //    변환과정이 필요하다.
            //    그 변환과정을 RequestBody라는 어노테이션을 붙이면서 자동적으로 dto타입으로 변환이 되었다.
            

@RequestBody와 ResponseEntity의 차이점

Spring에서는 HttpEntity란 클래스를 제공하는데 이 클래스의 역할은 Http 프로토콜을 이용하는 통신의 header과

body 관련 정보를 저장할 수 있게끔 합니다. 그리고 이를 상속받은 클래스로 RequestEntity와 ResponseEntity가

존재한다.

즉, 통신 메시지 관련 header과 body의 값들을 하나의 객체로 저장하는 것이 HttpEntity 클래스 객체이고,

Request 부분일 경우 HttpEntity를 상속받은 RequestEntity가, Response 부분일 경우 HttpEntity를 상속받은

ResponseEntity가 하게 됩니다.

@ResponseBody나 ResponseEntity를 return 하는거나 결과적으로는 같은 기능이지만.. 그 구현 방법이 틀리다.

예를 들어 header 값을 변경시켜야 할 경우엔 @ResponseBody의 경우 파라미터로 Response 객체를 받아서

이 객체에서 header를 변경시켜야 하고,.. ResponseEntity에서는 이 클래스 객체를 생성한뒤 객체에서

header 값을 변경시키면 된다.

자세한것은 Spring API 문서를 참고하면 된다.
            @RequestBody MessageDTO dto){
        
        ResponseEntity<String> entity=null;
        
        try {
            
            messageService.addMessage(dto);    
            
            entity=new ResponseEntity<>("success",HttpStatus.OK);
            
            //되돌려줄 메시지는 success, 상태메시지는 상태코드는 200이다.
            
        } catch (Exception e) {
            e.printStackTrace();
            
            entity=new ResponseEntity<>(e.getMessage()
                    ,HttpStatus.BAD_REQUEST);
        }
        return entity;
    }
}
cs


데이터베이스에서 데이터를 삭제해보고 크롬브라우저에서 send를 사용해서 컨트롤러로 자료를 보내서 테스트를 해본다.


로그를 확인해보면 dto에 값들이 쌓여있는것을 확인할 수 있다.

:

http 응답 코드와 method의 종류

Back-End/Spring 2019. 6. 26. 17:11

HTTP 응답 코드의 종류



 응답 코드


 설  명

100

 Continue (클라이언트로부터 일부 요청을 받았으며 나머지 정보를 계속 요청함) 

 101 

 Switching protocols 

 200

 OK (요청이 성공적으로 수행되었음) 

 201

 Created (PUT 메소드에 의해 원격지 서버에 파일이 생성됨)

 202

 Accepted (웹 서버가 명령을 수신함) 

 203

 Non - authoritative information (서버가 클라이언트 요구 중 일부만 전송) 

 204

 No content, (사용자 요구를 처리하였으나 전송할 데이터가 없음) 

 301

 Moved permanently (요구한 데이터를 변경된 타 URL에 요청함) 

 302

 Not temporarily 

 304

 Not modified (컴퓨터 로컬의 캐시 정보를 이용함. 대개 gif 등은 웹 서버에 요청하지 않음) 

 400

 Bad request (사용자의 잘못된 요청을 처리할 수 없음) , 스프링으로 작업할 때 많이 나는 에러

 401

 Unauthorized (인증이 필요한 페이지를 요청한 경우) 

 402

 Payment required (예약됨) 

 403

 Forbidden (접근 금지, 디렉터리 리스팅 요청 및 관리자 페이지 접근 등을 차단)

 404

 Not found. (요청한 페이지가 없음)

 405

 Method not allowed (허용되지 않는 http method 사용함)

 407

 Proxy authentication required (프록시 인증 요구됨)

 408

 Request timeout (요청 시간 초과)

 410

 Gone (영구적으로 사용 금지)

 412

 Precondition failed (전체 조건 실패)

 500

 Internal server error (내부 서버 오류)

 501

 Not implemented (웹 서버가 처리할 수 없음) 

 503

 Service unnailable (서비스 제공 불가)

 504

 Gateway timeout (게이트웨이 시간 초과)

 505

 HTTP version not supported (해당 http 버전이 지원되지 않음)




HTTP 메소드의 종류


 

HTTP Method


 전송 형태 

설명 

 GET

 

 GET [request-uri]?query_string


 HTTP/1.1\r\n


 Host:[Hostname] 혹은 [IP] \r\n


GET 요청 방식은 URI (URL) 이 가진 정보를

 

검색하기 위해 서버측에 요청하는 형태이다. 

 POST

 

 POST [request-uri]?query_string


 HTTP/1.1\r\n


 HOST:[Hostname] 혹은 [IP] \r\n


 Content-Lenght:[Lenght in Bytes] \r\n


 \r\n


 [query-string] 혹은 [데이터]


 POST 요청 방식은 요청 URI (URL)에 폼 입력을


 처리하기 위해 구성한 서버 측 스크립트


 (ASP, PHP, JSP 등) 혹은 CGI 프로그램으로


 구성되고 Form Action과 함께 전송되는데,


 이 때 헤더 정보에 포함되지 않고 데이터 부분에


 요청 정보가 들어가게 된다.

 HEAD

 HEAD                               [request-uri]


 HTTP/1.1\r\n


 Host:[Hostname] 혹은 [IP] \r\n 


 HEAD 요청 방식은 GET과 유사한 방식이나


 웹 서버에서 헤더 정보 이외에는 어떤 데이터도


 보내지 않는다.


 웹 서버의 다운 여부 점검 (Health Check)이나


 웹 서버 정보 (버전 등) 등을 얻기 위해 


 사용될 수 있다. 


 OPTIONS

 

 OPTIONS [request-uri]


 HTTP/1.1\r\n


 Host:[Hostname] 혹은 [IP] \r\n



 해당 메소드를 통해 시스템에서 지원되는


 메소드의 종류를 확인할 수 있다. 

 PUT

 

 PUT [request-uri] HTTP/1.1\r\n


 Host:[Hostname] 혹은 [IP] \r\n


 Content-Lenght:[Length] 


 

 POST와 유사한 전송 구조를 가지기 때문에

 

 헤더 이외에 메시지 (데이터)가 함께 전송된다.


 원격지 서버에 지정한 콘텐츠를 저장하기 위해


 사용되며 홈페이지 변조에 많이 악용되고 있다.


 DELETE

 

 DELETE                               [request-uri]


 HTTP/1.1 \r\n


 Host:[Hostname] 혹은 [IP] \r\n  \r\n


 

 원격지 웹 서버에 파일을 삭제하기 위해

 

 사용되며 PUT과는 반대 개념의 메소드이다.


 TRACE

 

 TRACE                                [request-uri]


 HTTP/1.1 \r\n


 Host:[Hostname] 혹은 [IP] \r\n \r\n


 
 원격지 서버에 Loopback (루프백)
 
 메시지를 호출하기 위해 사용된다. 

 CONNECT

 

 CONNECT                           [request-uri]


 HTTP/1.1 \r\n


 Host:[Hostname] 혹은 [IP] \r\n   \r\n


 웹 서버에 프락시 기능을 요청할 때 사용된다.


:

AOP와 트랜잭션 처리 실습 (데이터베이스로 테스트)

Back-End/Spring 2019. 6. 24. 23:17

AOP 실습예제


사용자가 메시지를 남기면 포인트 10 증가

메시지를 읽으면 포인트 5 증가


  

  com.examplt.spring02.aop

  ㄴMessageAdvice.java


  com.example.spring02.controller.message

  ㄴMessageController.java


  com.example.spring02.model.message.dto

  ㄴUserDTO.java

  ㄴMessageDTO.java


  com.example.spring02.model.message.dao

  ㄴMessageDAO.java

  ㄴMessageDAOImpl.java

  ㄴPointDAO.java

  ㄴPointDAOImpl.java


  com.example.spring02.service.message

  ㄴMessageService.java

  ㄴMessageServiceImpl.java






-AOP 실습용 테이블을 생성-


(데이터베이스를 이용한 실습)


AOP와 트랜잭션 처리를 활용한 실습


글쓰기를 하면 포인트 10을 부여

글읽기를 하면 열람시간을 수정하고 포인트 5를 부여


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
drop table tbl_user cascade constraints //혹시 중복된 테이블이 있을수도 있기 때문에 테이블 삭제
 
 
create table tbl_user (            //tbl_user 테이블을 생성
userid varchar2(50not null,    //id
upw varchar2(50not null,        //비밀번호
uname varchar2(100not null,    //이름
upoint number default 0,        //포인트, 기본값은 0으로 한다
primary key(userid)                //기본키는 id로 한다.
);
 
 
 
create table tbl_message(        //tbl_message (메시지를 저장) 테이블을 생성
mid number not null,            //메시지의 id
targerid varchar2(50not null,    //메시지를 받을 사람의 id
sender varchar2(50not null,    //메시지를 보낸 사람의 id
message varchar2(4000not null,//메시지의 내용
opendate date,                    //메시지를 열어본 시간
senddate date default sysdate,    //메시지를 보낸 시간 (보낼 당시 현재 시간)
primary key(mid)                //기본키를 메시지의 id로 설정
);
 
 
 
--시퀀스 생성--
create sequence message_seq        //message_seq 시퀀스를 생성 (메시지가 하나 생길때마다 숫자가 1씩증가, 초기값은 1로 설정)
start with 1
increment by 1;
 
 
--제약 조건 설정--
alter table tbl_message add constraint fk_usertarger //tbl_message테이블에 제약조건을 설정
foreign key (targetid) references tbl_user(userid);     //무결성이 깨질수 있기 때문에 targetid값에 userid값만 들어갈 수 있도록 설정 (아무id나 들어가면 안되기 때문에)
 
alter table tbl_message add constraint fk_usersender //tbl_message테이블에 제약조건을 설정
foreign key (sender) references tbl_user(userid);     //위쪽과 마찬가지로 sender값에 userid값만 들어갈 수 있도록 설정함
 
 
--사용자 추가--
insert into tbl_user (userid, upw, uname) values ('user00','user00','kim');
insert into tbl_user (userid, upw, uname) values ('user01','user01','park');
insert into tbl_user (userid, upw, uname) values ('user02','user02','hong');
insert into tbl_user(userid, upw, uname) values ('user03','user03','choi');
insert into tbl_user(userid, upw, uname) values ('user04','user04','lee');
 
 
select * from tbl_user;
 
 
--user02가 user00에게 메시지를 전송
insert into tbl_message (mid, targetid, sender, message)
values (message_seq.nextval, 'user00','user02','안녕...');
 
 
--user02에게 포인트 10 추가
update tbl_user set upoint=upoint+10 where userid='user02';
select * from tbl_user;
 
 
--user00의 메시지박스 조회
select * from tbl_message where targetid='user00';
update tbl_message set opendate=sysdate where mid=2;  //메시지를 읽으면 읽은 시간을 현재시간으로 바꾼다.
select * from tbl_message;
 
update tbl_user set upoint=upoint+5 where userid='user00'//userid가 user00과 같으면 포인트를 5포인트 증가시킨다.
select * from tbl_user;
 
delete from tbl_message;
update tbl_user set upoint=0//tbl_message테이블이 삭제될때 tbl_user테이블의 포인트를 0으로 한다.
 
 
--메시지 일련번호를 관리할 시퀀스 객체
 
create sequence message_seq
start with 1 --1부터 시작
increment by 1--1씩 증가
 
 
 
--시퀀스.nextval => 다음번호
 
select message_seq.nextval from dual;
 
//이 구문을 실행시키게 되면 마치 은행에서 번호표를 뽑듯이 번호가 1씩 계속 증가가된다.
//또한 이미 내가 뽑은 번호의 앞번호로 돌아갈수는 없고, 내가 뽑은 번호가 기억이 된다.
 
 
 
 
====================포인트를 얻게하는 테스트========================================================================

--테스트를 위한 사용자 계정을 추가한다.
insert into tbl_user (userid, upw, uname) values ('user00','user00','kim'); //아이디, 비밀번호, 이름
insert into tbl_user (userid, upw, uname) values ('user01','user01','park');
insert into tbl_user (userid, upw, uname) values ('user02','user02','hong');
insert into tbl_user (userid, upw, uname) values ('user03','user03','choi');
insert into tbl_user (userid, upw, uname) values ('user04','user04','lee');
 
select * from tbl_user;
 
 
--메시지 보내기 테스트--
 
--user02가 user00에게 메시지 전송
insert into tbl_message (mid, targetid, sender, message) values
(message_seq.nextval,'user00','user02','안녕'); //해석 : user02가 user00에게 '안녕'이라는 메시지를 보낸다.
 
select * from tbl_message;
 
--user02에게 포인트 10 추가
update tbl_user set upoint=upoint+10 where userid='user02';
select * from tbl_user;
 
 
--user00이 메시지 목록
select * from tbl_message where targetid='user00';
 
--메시지를 읽으면 열람시간을 저장
update tbl_message set opendate=sysdate where mid=18//18번 메시지를 읽으면 읽은 열람시간을 현재시간으로 바꾸기
select * from tbl_message;
 
--메시지를 읽으면 읽은 사람한테 5포인트를 추가
update tbl_user set upoint=upoint+5 where userid='user00';
select * from tbl_user;
 
 

 
cs


테스트 종료 후 테이블 삭제 및 commit 실시


1
2
3
delete from tbl_message; //메시지 테이블은 지금 필요 없기 때문에 일단 삭제
 
commit; //지금까지 한 작업들을 반영하기 위해 commit를 
cs




: