Spring

Spring 06 - REST방식, 댓글

나주나주 2024. 3. 6. 10:31

과거에 제작된 웹페이지의 경우 페이지를 이동하더라도 브라우저의 주소는 변화하지 않는 방식을 선호했다. 하지만 최근의 웹페이지들은 페이지를 이동하면 브라우저의 주소도 이동하는 방식을 사용한다. 

 

REST 

Representational State Transfer

  • '하나의 URI는 하나의 고유한 Resource를 대표한다' 는 개념에 추가적인 데이터를 통한 전송방식 결합
  • 스프링은 (추가적인) 데이터 처리를 위한 어노테이션과 기능이 있다

       (ex) @RequestMapping, @ResponseBody, GET 방식, POST 방식

 

GET, POST, PUT, DELETE 4가지의 행위가 메서드로 제공

서버에서 전송하는 것이 순수한 데이터 (객체 X) <-> Model에 데이터를 담아서 기존의 방식과 다르게

메서드의 리턴 타입으로 사용자가 정의한 클래스 타입을 사용, JSON이나 XML로 자동 처리

Annotation 기능
@RestController REST 방식 Controller 명시
@ResponseBody 바디로 데이터 전달 (ex) json
@PathVariable URI 경로에 있는 값을 파라미터로 추출
@CrossOrigin Ajax의 크로스 도메인 문제 해결
@RequestBody JSON 데이터를 원하는 타입으로 바인딩 처리

Tip) REST 방식은 서버에서 순수한 데이터를 전송한다(기존의 Controller에서 Model에 데이터를 담아 View로 전달하는 방식과 다름)

 

@RestController

: 메서드의 리턴 타입으로 사용자가 정의한 클래스 타입을 사용하고, 이를 JSON이나 XML로 자동 처리

//RestController는 순수한 데이터를 반환하는 형태로, 일반 문자열, JSON, XML등을 사용

@RestController
@RequestMapping("/sample")
@Log4j2
public class SampleController {

	@GetMapping(value ="/getText", produces ="text/plain; charset=UTF-8")
    public String getText() {
	    log.info("MIME TYPE: " + MediaType.TEXT_PLAIN_VALUE);
        
        return "안녕하세요";
	}
}

 

JSON

JavaScript Object Notation

  • 구조를 표현한 문자열 
  • { } 사용,  으로 구성
	<!-- json -->
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>2.9.5</version>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.dataformat</groupId>
		<artifactId>jackson-dataformat-xml</artifactId>
		<version>2.9.5</version>
	</dependency>

 

P375

Ajax

 

1. 테이블 추가

외래키 설정을 통해서 tbl_board 테이블을 참조

 

board.sql

create table tbl_reply(
	rno number(10,0), --댓글 번호(10, 소수점 없게)
	bno number(10,0), --fk, 게시판 번호
	reply varchar2(1000) not null,
	replyer varchar2(50) not null,
	replyDate date default sysdate,
	updateDate date default sysdate);
	

create sequence seq_reply; --댓글 자동 번호 객체
alter table tbl_reply add constraint pk_reply primary key (rno); --rno pk지정

 

2. VO 클래스 추가

ReplyVO

package org.zerock.domain;

import java.util.Date;

import lombok.Data;

@Data
public class ReplyVO { //DB 자료 객체화
	private Long rno;
	private Long bno;
	private String reply;
	private String replyer;
	private Date replyDate;
	private Date updateDate;
}

 

3. Mapper 클래스와 xml 처리

ReplyMapper.java (i)

package org.zerock.mapper;

import org.zerock.domain.ReplyVO;

//xml과 연동해서 sql 처리
public interface ReplyMapper {

	public int insert(ReplyVO vo); // vo 객체를 받아 insert 처리, 1개의 처리 완료 int로 리턴
}

 

ReplyMapper.xml

<?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 namespace="org.zerock.mapper.ReplyMapper">

	<insert id="insert"> 
	<!-- 주의) bno가 존재해야 함 -->
	insert into tbl_reply(rno, bno, reply, replyer) values (seq_reply.nextval, #{bno}, #{reply}, #{replyer})
	</insert>
</mapper>

 

4.테스트 완료

@Test
	public void testRead() {
		Long targetRno = 5L; //6번 댓글 조회
		
		ReplyVO vo = mapper.read(targetRno); //ReplyMapper.xml의 id가 read인 메서드에 
		
		log.info(vo);
	}

 


@Param 을 사용한 목록 조회, 페이징처리

 목록 조회 / 페이징 처리 필요한 매개변수의 개수 합계
게시글 게시판 Criteria*   1
댓글 게시판 Criteria 글 번호 2

* 기준, JAVA에서 페이징 처리 시 pageNum (현재 페이지 번호)과 amout(페이지당 출력할 데이터의 수량)를 전달하는 매개변수로 사용된다

 

MyBatis는 2개 이상의 데이터 전달 시

  1. 별도의 객체로 구성
  2. Map 이용
  3. Param을 이용해서 이름 사용   !추천

 

ReplyMapper.java (i)

public List<ReplyVO> getListWithPaging(
	@Param("cri") Criteria cri, //@Param의 속성값은 #{ }로 사용
        @Param("bno") Long bno);

 

4. 테스트 완료

@Test
	public void testList() {
		Criteria cri = new Criteria();
		
		List<ReplyVO> replies = mapper.getListWithPaging(cri, bnoArr[0]); //첫번째 게시물의 댓글 조회
		replies.forEach(reply -> log.info(reply)); //댓글 내용 반복 출력
	}

 

5. 서비스 영역과 Controller 처리

 

ReplyService.java (i) : 서비스 영역에 맞는 메서드명으로 수정

 

public interface ReplyService {
	public int register(ReplyVO vo); // vo객체를 받아 insert, 1개의 처리 완료

	public ReplyVO get(Long rno); // 댓글 번호를 받아 댓글 조회, 댓글 객체 반환

	public int remove(Long rno); // 댓글 번호를 받아 delete 후 1개의 처리 완료

	public int modify(ReplyVO reply); // reply객체를 받아 update, 1개의 처리 완료

	public List<ReplyVO> getList(@Param("cri") Criteria cri, @Param("bno") Long bno); // cri와 bno를 받아 댓글 객체
}

 

ReplyServiceImpl.java: @Service, @Log4j2 적용

@Service
@Log4j2
@AllArgsConstructor
public class ReplyServiceImpl implements ReplyService {
	@Setter(onMethod_ = @Autowired) //필요한 메서드 자동 주입?
	private ReplyMapper mapper;
	
    @Override
	public int modify(ReplyVO vo) {
		log.info("modify........." + vo);
		return mapper.update(vo);
	}
}

 

ReplyController.java

작업 URL HTTP 전송 방식
등록 /replies/new POST
조회 /replies/:rno GET
삭제 /replies/:rno DELETE
수정 /replies/:rno PUT or PATCH
페이지 /replies/pages/:bno/:page GET

Tip) PK만으로 조회, 수정, 삭제가 가능하기 때문에 PK를 기준으로 작성 BUT 댓글의 목록은 PK를 사용할 수 없기 때문에 파라미터로 필요한 게시물의 번호bno와 페이지 번호page 정보들을 URL에서 표현하는 방식 사용

 

 


Tip) Long과 long의 차이점

  • 주요 차이점은 데이터 유형은 기본 유형이고 래퍼 클래스는 기본 유형이 아니라는 것이다.
  • 원시 데이터 유형(long)은 특정 값을 보유하는 반면 래퍼 클래스(Long)의 개체는 저장된 데이터 위치에 대한 포인터이다.

 

JSON, Ajax 사용을 위한 초기설정

1. JSON

:스프링 서블릿 자바 테스트 등 버전 변경, JSON 추가

<?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>org.zerock</groupId>
	<artifactId>controller</artifactId>
	<name>Rest</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>11</java-version>
		<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<!-- JSON -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.6</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.dataformat</groupId>
			<artifactId>jackson-dataformat-xml</artifactId>
			<version>2.9.6</version>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId> <!-- 구글에서 만든 거, JSON convert해줌 -->
			<artifactId>gson</artifactId>
			<version>2.8.2</version>
		</dependency>

		<!-- 스프링 테스트 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<!-- lombok 셋팅 : 세터/게터/ToString/생성자 자동 구현용-->
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.24</version>
			<scope>provided</scope>
		</dependency>

		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>

		<!-- Logging -->
		<!-- <dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency> -->

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>

		<!-- log4j2 활성화 : resources log4j2.xml 변경 https://logging.apache.org/log4j/2.x/maven-artifacts.html -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.18.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.18.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-slf4j-impl</artifactId>
			<version>2.18.0</version>
		</dependency>

		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-eclipse-plugin</artifactId>
				<version>2.9</version>
				<configuration>
					<additionalProjectnatures>
						<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
					</additionalProjectnatures>
					<additionalBuildcommands>
						<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
					</additionalBuildcommands>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>true</downloadJavadocs>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<configuration>
					<source>11</source>
					<target>11</target>
					<compilerArgument>-Xlint:all</compilerArgument>
					<showWarnings>true</showWarnings>
					<showDeprecation>true</showDeprecation>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>exec-maven-plugin</artifactId>
				<version>1.2.1</version>
				<configuration>
					<mainClass>org.test.int1.Main</mainClass>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

 

2. Ajax

두 개의 resources 폴더에 log4j2.xml 과 log4jdbc.log4j2.properties 추가

 

 

 

 


Tip) Uniform Resource Locator  Uniform Resource Identifier

 

중요

ResponseEntity

 

(별도의 화면 이동 없이 처리) Ajax를 이용해서 호출하는 REST 방식을 많이 사용

Tip) 비동기 방식: 화면은 가만 잇는데 팝업이나 모달 같은 걸로 움직쓰

 

JSP도 서버에서 돌리는 거 Server Pages...

'Spring' 카테고리의 다른 글

Spring - 초기 설정 ver.2  (0) 2024.03.07
Spring 07 - AOP, Transaction  (0) 2024.03.07
Spring 05 - Paging  (0) 2024.03.04
Spring 04  (0) 2024.02.29
기본적인 웹 게시물 관리  (0) 2024.02.28