오늘부터 2장 학습 (ppt 33페이지)

2장 Controller / RequestMapping

 

p34
Controller는 요청을 처리하기 위해 RequestMapping부터 접근한다.
RequestMapping에 포함된 문자열이 요청 주소와 같다면 해당 클래스나 메소드에 접근

Service로 처리 위임 → 아직 안배움
☞ 현재 우리는 뷰 이름만 리턴했다.

RequestMapping은 Get, Post 방식으로 사용 가능
GetMapping은 Get 방식으로만 사용 가능
PostMapping은 Post 방식으로만 사용


※ 리퀘스트 매핑을 사용하면 편하다.. 하지만 중요한 정보를 다루는 경우가 있다. 가급적이면 GET, POST 매핑을 따로 사용하자.


클래스에는 꼭 RequestMapping 사용
메소드에는 RequestMapping, GetMapping, PostMapping 사용 가능


※  GetMapping과 PostMapping에 대해서 HTTP를 꼭 공부하고 사용하자.


위의 그림자료에서 Logger를 사용했지만 우리는 lombok을 다운받고 log.info( )를 사용한다.

(어제 이 환경설정 때문에 3~4시간을 소비했다... 자바를 처음 배울 때 eclipse와 전자정부 프레임워크 egov eclipse의 폴더와 파일명이 같았는데, 자바 eclipse폴더 내에 전자정부 eclipse폴더를 넣어놨기 때문... 전자정부 eclipse폴더 명을 egov_eclipse로 바꾸고, 자바 ecilpse 폴더가 있는 Program Files에 놓으니 lombok이 잘 인식한다.)

 


p35

★ 중요!!!

 

포커스는 시작행에 맞춰져 있다.


GET 또는 POST → 요청 방식 


브라우저 검사(F12) 네트워크를 보면
Request Method: GET을 볼 수 있다. 이것이 요청 방식이다.
연결할 때 ip와 포트번호가 필요하다.

 


p36


요청 방식이 GET일 때
?앞 : 까지가 RequestMapping (href요청경로)
?뒤 : 이후 사용자가 요청한 주소 = 쿼리 스트링(Query String)
bkind : 파라미터 이름
free : 파라미터 값
파라미터 이름&파라미터 값(파라미터 이름이 두 개일 때를 예로 보여줌)

폼 태그의 메소드에 GET 또는 POST를 결정할 수 있다 (기본적으로 GET)
?앞부분까지가 action

사용자의 입력값을 받는 input 태그 → 앞서 말했던 파라미터 이름과 파라미터 값을 받을 수 있다.

 

※  type="submit"이 가능한 태그들 → input / button

input 태그에 type을 이미지를 사용할 수 있다. (submit 이미지를 다운받아 넣어보았다.)

*form 태그안에 인풋이나 button이 들어가야 제출 역할을 한다.
type="submit"으로 넣어줘야함

<form class="m-2" method="get" action="getMethod">
   <input type="hidden" name="chNum" value="ch02"/>
   <div class="form-group mb-2">
       <label for="bkind">bkind</label>
       <input type="text" class="form-control" id="bkind" name="bkind" value="free">
   </div>

   <div class="form-group mb-2">
       <label for="bno">bno</label>
       <input type="text" class="form-control" id="bno" name="bno" value="1">
   </div>
   <!-- 제출 버튼: 양식의 데이터를 서버로 보내겠다. -->
   <!-- <input type="submit" value="GET방식" class="btn btn-info btn-sm"/>
   <button type="submit" class="btn btn-info btn-sm">GET방식</button> -->
   <input type="image" 
   src="${pageContext.request.contextPath}/resources/image/submit_button.png"
   width="100" height="30"/>
</form>

getMethod.jsp 폼 삽입
액션부분을 getMethod로 수정
${ } 사용해도 되지만 그럴 이유가 없다..? 정확히 이해해보자.
input hidden 왜 넣었는지?
submit에 대한 이해 필요


location.herf → 배웠었다. 복습하자.
$.ajax → 오늘 배울 것

**ch02 컨트롤러로 실습

package com.mycompany.springframework.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
@RequestMapping("/ch02")
public class Ch02Controller {

	@GetMapping("/getMethod")
	public String getMethod(String chNum, String bkind, String bno, Model model) {
		// 요청 처리 코드
		log.info("getMethod() 실행 ");
		log.info("chNum: " + chNum);

		model.addAttribute("chNum", chNum);
		return "ch02/getMethod";
	}

	@RequestMapping(value = "/getMethodAjax", method = RequestMethod.GET)
	public String getMethodAjax(String chNum, String bkind, String bno, Model model) {
		// 요청 처리 코드
		log.info("getMethodAjax() 실행 ");
		log.info("chNum: " + chNum);
		log.info("bkind: " + bkind);
		log.info("bno: " + bno);

		model.addAttribute("chNum", chNum);
		return "ch02/getMethodAjax";
	}

	@RequestMapping("/postMethod")
	public String postMethod(String chNum, String mid, String mpassword, Model model) {
		// 요청 처리 코드
		log.info("postMethod() 실행 ");
		log.info("chNum: " + chNum);
		log.info("mid: " + mid);
		log.info("mpassword: " + mpassword);

		model.addAttribute("chNum", chNum);
		return "ch02/postMethod";
	}

	/*
	 * @RequestMapping("/postMethodAjax") public String postMethodAjax(String mid,
	 * String mpassword, Model model) { // 요청 처리 코드
	 * log.info("postMethodAjax() 실행 "); log.info("mid: " + mid);
	 * log.info("mpassword: " + mpassword); return "ch02/postMethodAjax"; }
	 */

	/*
	 * @RequestMapping("/postMethodAjax") public void postMethodAjax(String mid,
	 * String mpassword, HttpServletResponse response) throws IOException { // 요청 처리
	 * 코드 log.info("postMethodAjax() 실행 "); log.info("mid: " + mid);
	 * log.info("mpassword: " + mpassword);
	 * 
	 * Map<String, String> map = new HashMap<>(); map.put("spring", "12345"); // 데이터
	 * 베이스가 있었으면 데에터 베이스로 확인 map.put("summer", "67890");
	 * 
	 * String result = ""; if(map.containsKey(mid)) {
	 * if(map.get("mid").equals(mpassword)) { // 로그인 성공 result =
	 * "{\"result\":\"success\"}"; } else { // 비밀번호가 틀린 경우 result =
	 * "{\"result\":\"fail\", \"reason\":\"wrongMpassword\"}"; } } else { // 아이디가
	 * 존재하지 않는 경우 result = "{\"result\":\"fail\", \"reason\":\"wrongMid\"}"; }
	 * 
	 * // 직접 응답을 생성해서 브라우저로 보냄 PrintWriter pw = response.getWriter();
	 * response.setContentType("application/json; charset=UTF-8");
	 * pw.println(result); pw.flush(); pw.close(); }
	 */

	@PostMapping("/postMethodAjax")
	public void postMethodAjax(String mid, String mpassword, HttpServletResponse response) throws IOException {
		//요청 처리 코드
		log.info("postMethodAjax() 실행");
		log.info("mid: " + mid);
		log.info("mpassword: " + mpassword);

		Map<String, String> map = new HashMap<>();
		map.put("spring", "12345");
		map.put("summer", "67890");

		/*
		 * String result = ""; if(map.containsKey(mid)) {
		 * if(map.get(mid).equals(mpassword)) { //로그인 성공 result =
		 * "{\"result\":\"success\"}"; } else { //비빌번호가 틀린 경우 result =
		 * "{\"result\":\"fail\", \"reason\":\"wrongMpassword\"}"; } } else { //아이디가
		 * 존재하지 않는 경우 result = "{\"result\":\"fail\", \"reason\":\"wrongMid\"}";; }
		 */

		// JSON 라이브러리를 pom.xml에 추가하여 다운로드하여 사용
		// 위의 코드보다 훨씬 간편하게 사용할 수 있다.
		JSONObject result = new JSONObject();
		if (map.containsKey(mid)) {
			if (map.get(mid).equals(mpassword)) {
				// 로그인 성공
				result = result.put("result", "success");
			} else {
				// 비빌번호가 틀린 경우
				result.put("result", "fail");
				result.put("reason", "wrongMpassword");
			}
		} else {
			//아이디가 존재하지 않는 경우
			result.put("result", "fail");
			result.put("reason", "wrongMid");
		}

		// 직접 응답을 생성해서 브라우저로 보냄
		PrintWriter pw = response.getWriter();
		response.setContentType("application/json; charset=UTF-8");
		pw.println(result.toString());
		pw.flush();
		pw.close();
	}

}


컨트롤러 위에 어노테이션을 붙일 시 객체를 생성한다.

dispatcher 폴더 아래의 component_scan.xml파일에서 설정되어 있다.

base-package="com.mycompany.springframework"
src/main/java 밑으로 쭉 스캔하겠다는 의미


ch02컨트롤러 생성 및 작성
return (WEB-INF/views/ → 접두사, .jsp → 접미사)

menu.jsp파일에서 경로설정부분 ?chNum=ch02 추가
컨트롤러 getMethod의 파라미터 추가
브라우저 화면 확인 : 요청 주소값 변경,
아코디언 코랩스드, show부분 수정 (수업에 있어서 아코디언을 설정함)

(새로고침 할 때나 링크를 들어갈 때 아코디언을 편하게 사용하기 위해서)

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

<div class="accordion" id="accordionExample">
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button ${chNum=='ch01'?'':'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
        Ch - 01. 개발 환경 구축
      </button>
    </h2>
    <div id="collapseOne" class="accordion-collapse collapse ${chNum=='ch01'?'show':''}" data-bs-parent="#accordionExample">
      <div class="accordion-body">
      	<ul>
      		<li><a href="${pageContext.request.contextPath}/ch01/content?chNum==ch01">공통 레이아웃 구성</a></li>
      	</ul>  
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button ${chNum=='ch02'?'':'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
        Ch - 02. 요청 매핑
      </button>
    </h2>
    <div id="collapseTwo" class="accordion-collapse collapse ${chNum=='ch02'?'show':''}" data-bs-parent="#accordionExample">
      <div class="accordion-body">
        <ul>
      		<li><a href="${pageContext.request.contextPath}/ch02/getMethod?chNum=ch02">GET 방식</a></li>
      		<li><a href="${pageContext.request.contextPath}/ch02/postMethod?chNum=ch02">POST 방식</a></li>
      	</ul> 
      </div>
    </div>
  </div>
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button ${chNum=='ch03'?'':'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
        Ch - 03
      </button>
    </h2>
    <div id="collapseThree" class="accordion-collapse collapse ${chNum=='ch01'?'show':''}" data-bs-parent="#accordionExample">
      <div class="accordion-body">
        <ul>
      		<li>Item-01</li>
      		<li>Item-02</li>
      	</ul> 
      </div>
    </div>
  </div>
</div>

 

<!-- JSON 라이브러리 사용 -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20240303</version>
</dependency>



submit으로 데이터를 제출할 경우 서버에서 어떻게 전달받을 수 있을까?
getMethod.jsp파일을 수정하며 학습

# Ajax란? 
Asynchronous JavaScript and XML
비동기 자바스크립트 그리고 XML


1) 비동기란?
비동기는 동시에 일어나지 않는다는 의미

서버에게 데이터를 요청한 후 요청에 따른 응답을 계속 기다리지 않아도되며 다른 외부 활동을 수행하여도되고 서버에게 다른 요청사항을 보내도 상관없다.(서버요청과 동시에 바로 다음 코드를 실행한다.)
응답에 대한 지난 코드도 응답에 필요한 시간이 지난후 실행한다.

2) 효과
페이지 이동 → URL 변경 → 화면 갱신
→ 기존 화면은 폐기되고, 새로운 화면으로 렌더링


이 경우, 하나의 화면에서 일부분만 변경이 된다면?
그 일부분만 변경하는 것이 효율적 해당 <div></div> 내용만 갱신해주면 될 것이다.

AJAX를 사용하여 비동기 처리를 해야한다.


동기, 비동기 중 어떤 것을 사용해야 할까?

cf) 동기와 비동기에 대해 알아보자

( https://velog.io/@slobber/%EB%8F%99%EA%B8%B0%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%9D%98-%EC%B0%A8%EC%9D%B4 )


# A와 B의 화면이 완전히 다를 경우 
<a href="요청경로">
location.href="요청경로"
→ 이것을 사용

# A와 B의 화면이 일부분만 다를 경우
비동기 부분화면 갱신 (AJAX) 사용
A의 jsp파일이 전체적으로 있다면
B jsp파일은 해당 일부분의 화면만 정의

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

<div>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo1.jpg" width="100"/>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo2.jpg" width="100"/>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo3.jpg" width="100"/>
</div>

 

@RequestMapping(value = "/getMethodAjax", method = RequestMethod.GET)
public String getMethodAjax(String chNum, String bkind, String bno, Model model) {
    // 요청 처리 코드
    log.info("getMethodAjax() 실행 ");
    log.info("chNum: " + chNum);
    log.info("bkind: " + bkind);
    log.info("bno: " + bno);

    model.addAttribute("chNum", chNum);
    return "ch02/getMethodAjax";
}
function handleBtn1() {
       console.log("handleBtn2() 실행");
       $.ajax({
          url: "getMethodAjax",
          //method: "get", // method 대신에  type: "get" 을 사용해도 된다.
          type: "get",
          //data: "bkind=notice&bno=300",
          data: {bkind:"notice", bno:300}, // 이렇게 사용하는 경우가 더 많다.
          success: function(data) {
              console.log(data);
             $("#ajaxResponseInclude").html(data);
          }
       });
}
<button onclick="handleBtn1()" type="button" class="btn btn-success btn-sm">JavaScript로 요청</button>


이렇게 AJAX 부분 처리를 해주면 화면 전체 갱신이 일어나지 않는다.
(부분 UI 변경)


■ jQuery AJAX

https://www.w3schools.com/jquery/jquery_ref_ajax.asp
오전에 사용해보았던 $.ajax( ) 정보
$.get() Syntax
→ $.get(URL,data,function(data,status,xhr),dataType)
$.ajax ( )를 $.get( )으로 사용해보았다.

<button onclick="handleBtn3()" type="button" class="btn btn-success btn-sm">AJAX로 요청</button>


success → url ... data까지 정상적으로 왔을 때 응답을 해준다.

37p

POST 방식일 경우에 무엇이 달라지나?

시작행에 ?bkind=free&bno=2가 오는것이 아니라
?bkind=free&bno=2 이 내용이 본문으로 들어간다.


POST방식을 많이 사용하는 이유 ?

get방식을 사용했을 때 데이터들 주소창에 보이게된다.
이때 아이디, 비밀번호 등이 url에 보이게 될 수 있다.
post방식을 사용했을 때 실제 데이터는 본문에 실려서 보내기 때문에 보안에 강하다.

ppt에 나와있는대로 2가지 방법으로 사용할 수 있다
1. HTML
2. jQuery AJAX (교수님이 선호하는 방식)

-- 실습
getMethodAjax 파일

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

<div>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo1.jpg" width="100"/>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo2.jpg" width="100"/>
	<img src="${pageContext.request.contextPath}/resources/image/photos/photo3.jpg" width="100"/>
</div>


a태그는 항상 GET 방식이다.
cf) get : 얻다. form : 처리하다. a태그 : 해당 링크를 얻다.
따라서 a 태그는 get 처리 방식이다.

 

<form class="m-2" method="post" action="postMethod">
   <input type="hidden" name="chNum" value="ch02"/>
   <div class="form-group mb-2">
       <label for="mid">멤버 아이디</label>
       <input type="text" class="form-control" id="mid" name="mid" value="spring">
   </div>

   <div class="form-group mb-2">
       <label for="mpassword">멤버 패스워드</label>
       <input type="password" class="form-control" id="mpassword" name="mpassword" value="12345">
   </div>
   <!-- 제출 버튼: 양식의 데이터를 서버로 보내겠다. -->
   <button type="submit" class="btn btn-info btn-sm">로그인</button>

</form>


라벨 for는 다음에 나오는 인풋의 id를 의미하고 name도 아이디의 값과 왠만하면 같이 준다.

getMethodAjax 파일 복사

postMethodAjax로 바꾸어 활용


POST 방식
postMethod.jsp 로 실습
1. form태그 수정으로 HTML 방식 실습

2. function 으로 AJAX 방식 실습
- url, type, data 까지 데이터가 적절하면 success 실행

컨트롤러를 여러번 변경하여 사용

## 매우 중요 개념 ## 
ppt 4페이지 삼각형 구조 세부 내용
*Browser        *WebApplication
           ------→   HttpServletRequest
           ←-----    HttpServletresponse

브라우저가 웹 어플리케이션에 요청시 모든 정보는 HttpServletRequest가 담고있다. HttpServletRequest와 HttpServletresponse 객체가 동시에 생성되며 stream 형식으로 데이터를 전달 또는 받는다.

jsp는 html을 생성하는데 최적화되어있다.

 

---------------------------------
참고하여 공부하자
https://velog.io/@dydaks7878/HttpServletRequest-HttpServletResponse%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4

https://velog.io/@nrudev/HttpServletRequest%EC%99%80-HttpServletResponse

https://baekee.tistory.com/entry/%EC%9B%B9-%EC%9E%91%EB%8F%99-%EC%9B%90%EB%A6%ACWASWeb-Application-Server

https://m.boostcourse.org/web316/lecture/254276
---------------------------------

ppt 38, 39페이지

 



# 어노테이션 (자바 12장 내용)
지금까지 우리는 @XXX(" ... ") 이렇게 사용하였다.

@XXX("기본값", 속성명="값")
--> 값을 두 개를 주기위해선 속성명이 들어가야 하는데 속성명이 하나가 나오면 전체적으로 속성명을 주어줘야한다.

@XXX(value="기본값", 속성명="값") 이런식으로...

하지만 이렇게 안해도 되고 @GetMapping @PostMapping 을 사용하자...


※ 정리

AJAX 비동기 처리 방식, 요청과 반응 등 개념 등을 찾아보고, 소스코드 보며 미니 프로젝트에 직접 사용해보면 익숙해질 것 같다.

'JAVA' 카테고리의 다른 글

34일차 2024-4-15  (0) 2024.04.15
33일차 2024 - 4 - 12  (0) 2024.04.12
31일차 2024 - 4 - 9  (0) 2024.04.09
30일차 2024 - 4 - 8  (0) 2024.04.08
29일차 2024 - 4 - 5 (Git과 GitHub)  (0) 2024.04.05

+ Recent posts