본문 바로가기
Spring/Spring

[Spring] Rest API / @RestController(2)

by J4J 2021. 2. 27.
300x250
반응형

개요

 

들어가기에 앞서
프로젝트 설정
파일 구성

 

 

 

안녕하세요. J4J입니다.

 

이번 포스팅은 스프링에서 Rest API 구현을 위한 프로젝트 설정에 대해 적어보는 시간을 가져보려고 합니다.

 

 

들어가기에 앞서

 

이전 포스팅에서 Rest API와 @RestController가 무엇인지에 대해 간단하게 알아봤었습니다.

 

앞서 알게 된 개념들을 바탕으로 이번 시간에는 JSP와 스프링을 사용하여 Rest API의 구조를 만들어보겠습니다.

 

JSP로는 사용자가 보게 될 화면을 만들것이고 스프링에서는 화면에서 가져다 쓸 API를 만들어 보겠습니다.

 

 

프로젝트 설정

 

※ 스프링과 관련된 코드는 모두 STS-3.9.12.RELEASE 버전을 기준으로 작성되었습니다.

 

[ 0. 프로젝트 초기 설정 (프로젝트 명: rest, 패키지 명: com.spring.rest) ]

 ※ 참고: 2021/02/11 - [IT/Spring] - [Spring] 스프링을 이용한 MVC패턴 구현(2) - 프로젝트 초기 설정 방법

 

[ 1. pom.xml에 dependency 추가 ]

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spring</groupId>
	<artifactId>rest</artifactId>
	<name>rest</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
        <java-version>1.8</java-version>
        <org.springframework-version>5.2.11.RELEASE</org.springframework-version>
        <org.aspectj-version>1.9.6</org.aspectj-version>
        <org.slf4j-version>1.7.30</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
        	...
		
		<!-- Data Binding -->
		<dependency> <!-- JSON 데이터 처리를 위한 dependency -->
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.9.8</version>
		</dependency>
				
		...
        
	</dependencies>
    <build>
    
        ...
        
    </build>
</project>

 

 

[ 2. web.xml에 인코딩 필터 추가 ]

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	...
	
	<!-- Encoding Filter -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

 

 

반응형

 

 

[ 3. JSP파일 인코딩 설정 ]

 

STS 상단의 Window → Preferences -> encoding 검색 → JSP Files에서 Encoding을 UTF-8로 설정 후 Apply

 

JSP Encoding Setting

 

 

[ 4. servlet-context.xml 수정 ]

 

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	...
	
	<context:component-scan base-package="com.spring.rest.controller" /> <!-- Controller 관련 클래스에 설정파일 적용 -->
</beans:beans>

 

 

[ 5. 내 정보를 저장할 객체 클래스 생성 (com.spring.rest.dto.Info) ]

 

package com.spring.rest.dto;

public class Info {
	private String name;
	private String phone;
	private int age;
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getPhone() {
		return phone;
	}
	
	public void setPhone(String phone) {
		this.phone = phone;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Info [name=" + name + ", phone=" + phone + ", age=" + age + "]";
	}
}

 

 

혹시 getter, setter와 toString을 만들 때 직접 작성하시는 분은 안계시겠죠?

 

자동 완성으로 만들 수가 있는데 자동 완성하는 방법은 변수 입력(name, phone, age 등) → 화면 우클릭 → Source → Getters and Setter / toString() 입니다.

 

Auto Complete

 

 

뿐만 아니라 생성자도 동일한 방법으로 자동완성 할 수 있습니다.

 

 

728x90

 

 

[ 6. 컨트롤러 클래스 생성 (com.spring.rest.controller.MyController) ]

 

package com.spring.rest.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.spring.rest.dto.Info;

@Controller
public class MyController {
	
	@GetMapping("/")
	public String init() { // 초기 로드 시 info.jsp페이지 로드
		return "info";
	}
	
	@GetMapping("/myName")
	@ResponseBody
	public ResponseEntity<Object> myName() { // 이름 데이터를 전달
		return new ResponseEntity<Object>("J4J", HttpStatus.OK); // 데이터와 상태코드 리턴
	}
	
	@GetMapping("/myInfo")
	@ResponseBody
	public ResponseEntity<Object> myInfo() { // 정보 데이터를 전달
		Info myInfo = new Info();
		myInfo.setName("J4J");
		myInfo.setPhone("010-2021-0226");
		myInfo.setAge(20);
		
		return new ResponseEntity<Object>(myInfo, HttpStatus.OK); // 데이터와 상태코드 리턴
	}
	
	@GetMapping("/compareInfo")
	@ResponseBody
	public ResponseEntity<Object> compareInfo(Info info) { // 전달받은 데이터와 값이 동일한지 판단 후 true, false 전달
		if(info.getName().equals("J4J") && info.getPhone().equals("010-2021-0226") && info.getAge() == 20) {
			return new ResponseEntity<Object>("true", HttpStatus.OK); // 데이터와 상태코드 리턴
		} else {
			return new ResponseEntity<Object>("false", HttpStatus.OK); // 데이터와 상태코드 리턴
		}
	}
}

 

 

[ 7. 사용자가 볼 JSP페이지 생성 (src/main/webapp/WEB-INF/views/info.jsp) ]

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
	#myTable {
		text-align: center;
	}
	
	.button {
		margin-right: 5px;
	}
</style>
</head>
<body>
	<h2>내 정보</h2>
	<table id="myTable">
		<tr>
			<td>이름</td>
			<td>전화번호</td>
			<td>나이</td>
		</tr>
		
		<tr>
			<td><input type="text" id="name" /></td>
			<td><input type="text" id="phone" /></td>
			<td><input type="number" id="age" /></td>
		</tr>
	</table>
	
	<input type="button" id="getName" class="button" value="이름 가져오기"/>
	<input type="button" id="getInfo" class="button" value="정보 가져오기"/>
	<input type="button" id="compare" class="button" value="정보 비교하기"/>
	
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <!-- Jquery 사용을 위해 필요한 CDN -->
<script>
	$("#getName").click(function() { // body에서 id가 getName인 것을 클릭할 경우
		$.ajax({
			type: "GET", // HTTP Method 종류
			url: "/rest/myName", // 컨트롤러와 매핑된 URL
			success: function(data) {
				$("#name").val(data); // body에서 id가 name인 것에 data값을 저장 
			},
			error: function(error) {
				console.log(error);
			}
		})
	});
	
	$("#getInfo").click(function() { // body에서 id가 getInfo인 것을 클릭할 경우 
		$.ajax({
			type: "GET", // HTTP Method 종류
			url: "/rest/myInfo", // 컨트롤러와 매핑된 URL
			success: function(data) {
				$("#name").val(data.name); // body에서 id가 name인 것에 data.name값을 저장
				$("#phone").val(data.phone); // body에서 id가 name인 것에 data.phone값을 저장
				$("#age").val(data.age); // body에서 id가 name인 것에 data.age값을 저장
			},
			error: function(error) {
				console.log(error);
			}
		})
	});
	
	$("#compare").click(function() { // body에서 id가 compare인 것을 클릭할 경우
		let params = { // JSON 데이터
			name: $("#name").val(), // body에서 id가 name인 것에 담긴 value값을 가져오기
			phone: $("#phone").val(), // body에서 id가 phone인 것에 담긴 value값을 가져오기
			age: $("#age").val() // body에서 id가 age인 것에 담긴 value값을 가져오기
		}
	
		if(params.name == "" || params.phone == "" || params.age == "") {
			alert("정보를 모두 입력해주세요.");
			return;
		}
		
		$.ajax({
			type: "GET", // HTTP Method 종류
			url: "/rest/compareInfo", // 컨트롤러와 매핑된 URL
			data: params, // 파라미터로 넘길 데이터
			success: function(data) {
				if(data == "true") {
					alert("동일한 정보입니다.");
				} else {
					alert("다른 정보입니다.");
				}
			},
			error: function(error) {
				console.log(error);
			}
		})
	});
</script>
</html>

 

 

Jquery를 사용하기 위해서는 CDN이라는 것을 넣어줘야 합니다.

 

저 같은 경우는 jquery.com/download/에 접속하여 거의 하단에 있는 Google CDN에 접속한 뒤 "3.x snippet:"에 해당하는 값을 가져와 사용했습니다.

 

 

 

 

[ 8. 프로젝트 실행 화면 ]

 

Init Page

 

 

여기서 이름 가져오기 버튼을 누르게 되면 다음과 같이 이름을 스프링에서 가져옵니다.

 

getName

 

 

정보 가져오기 버튼을 누르게 되면 이름, 전화번호, 나이를 모두 스프링에서 가져옵니다.

 

getInfo

 

 

정보 비교하기 버튼을 누르게 되면 페이지에 보이는 데이터를 가지고 스프링에서 비교를 하여 데이터가 동일한지 여부를 알림창으로 보여줍니다.

 

compareInfo

 

 

만약 이름을 조금 변경하여 다시 정보를 비교하면 다음과 같이 나옵니다.

 

compareInfo

 

 

Ajax를 이용하여 데이터를 가져올 경우에는 페이지가 깜빡이는 현상이 발생하지 않습니다.

 

왜냐하면 비동기처리 방식의 특징은 웹 페이지를 reload하지 않고 데이터만 가져와서 뿌려주기 때문입니다.

 

다른 말로는 html파일을 다시 파싱하지 않는다고도 할 수 있겠습니다.

 

그리고 제가 지금까지 한 방식은 단순히 예시를 보여주기 위해 컨트롤러만 구현한 것이고 실제적으로 많이 사용되는 것은 데이터베이스에 저장되어 있는 데이터를 가져다 사용하는 비즈니스 로직 처리 구간이 포함되어 있어야 합니다.

 

관련된 내용은 이전에 포스팅한 내용과 동일하기 때문에 참고하시면 될 것 같습니다.

 

 - 2021/02/13 - [IT/Spring] - [Spring] 스프링을 이용한 MVC패턴 구현(3) - MySQL, MyBatis, @Repository 구성

 

 - 2021/02/16 - [IT/Spring] - [Spring] 스프링을 이용한 MVC패턴 구현(4) - @Service 구성

 

 - 2021/02/18 - [IT/Spring] - [Spring] 스프링을 이용한 MVC패턴 구현(5) - @Controller 구성

 

 

파일 구성

 

File Structure

 

 

 

이상으로 스프링에서 Rest API 구현을 위한 프로젝트 설정에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

728x90
반응형

댓글