Responding HTTP Request with JSON, HTML

민준·2023년 2월 22일
0
post-thumbnail

1. HTTP 요청을 JSON으로 응답하기

package com.cos.controllerdemo.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HttpResponseJsonController {

	@GetMapping("/resp/json")
	public String respJson() {
//		return "문자열"; 					 // 리턴 타입이 'String'이기 때문에 문자열로 리턴됩니다.
        return "{\"username\":\"cos\"}";  // JSON으로 응답을 받기 위해 형식을 맞춰 요청합니다.
	} 
	
    @GetMapping("/resp/json/object")
	public User respJsonObject() {
		User user = new User(); // 전에 만들었던 domain.User 클래스 임포트
		user.setUsername("홍길동");
		return user; 
	}
    // 이걸 보니 어제 본 'HttpBodyController'(요청)랑 뭐가 다른 건지 비교해봐야 될 것 같습니다.
}

위 코드의 첫 번째 메서드에 따라 도메인에 접속하면 아래와 같이 'JSON'형식의 코드로 응답합니다.
따로 언급한 적은 없지만 크롬 플러그인으로 'JSON Viewer'를 설치했는데,
이 때문에 아래처럼 JSON의 형식으로 화면에 출력된 것입니다.

두 번째 메서드에 따라 도메인에 접속하면 '홍길동'이라는 데이터를 받아 아래와 같이 JSON 형식으로 출력됩니다.

아래의 코드는 바로 위의 메서드와 똑같은 기능을 하는 코드입니다.
MessageConverter 라는 클래스가 아래 같은 코드(JavaObject)를 위처럼(Json) 변경해서 통신을 통해 응답 해줍니다.
다만 이 클래스는 @RestController 일 때만 작동합니다.

@GetMapping("/resp/json/javaobject")
public String respJsonJavaObject() {
	User user = new User(); 
	user.setUsername("홍길동");
		
	String data = "{\"username\":\"" + user.getUsername() + "\"}"; 
		return data; // JSON의 형식을 맞춰 요청할 때 JSON의 형식으로 응답합니다.
}

2. HTTP 요청을 파일로 응답하기

ㄱ) txt 파일 응답하기 (기본 경로 : resources/static)
ㄴ) 스프링부트가 '지원하는' mustache 파일 응답하기
ㄷ) 스프링부트가 '버린' jsp 파일 응답하기

html 문서에 java 코드를 작성하면 일반적으로 웹 브라우저는 이것을 읽지 못합니다.
클라이언트가 웹서버로 요청하고 응답 받으면 문자 그대로 화면에 출력되는 것입니다.

반면 'jsp', 'mustache' 파일은 '템플릿 엔진'을 가지고 있습니다.
템플릿 엔진(Templat Engine) 이란 'html' 파일에 'java' 코드를 쓸 수 있는 것입니다.

평소에는 Apache HTTP Server '아파치' 라는 웹 서버를 사용하다가
클라이언트가 'jsp' 파일을 Web Application Server(WAS) 'Tomcat' 에게 보내면
'톰캣'이 'jsp' 파일의 자바 코드를 해석해 'html' 파일로 만들어 줍니다.

ㄱ) txt 파일 응답하기

아래와 같이 'HttpRespController' 클래스를 생성합니다.

package com.cos.controllerdemo.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller // 파일을 리턴하기 위함, '@RestController'는 Data를 응답하는 컨트롤러입니다.
public class HttpRespController {

	@GetMapping("/txt")
	public String txt() {
		return "a.txt";
	}
}

그리고 src/main/resources/static 폴더에 'a.txt' 파일을 하나 생성합니다.
내용은 아무거나 적습니다. 저는 강의와 같이 "This is a.txt"라고 적었습니다. 저장 후 확인합니다.

파일의 내용을 잘 읽어왔습니다. 궁금해서 html 태그도 적어봤는데 적용되지 않습니다.
기본 경로가 'static'폴더인 이유는 프레임워크를 사용하고 있기 때문에 이미 잡힌 틀을 따라야하기 때문입니다.
일반 정적인 파일들은 이 폴더 내부가 기본 경로입니다.

ㄴ) mustache 파일 응답하기

이 파일 또한 템플릿 엔진을 가지고 있습니다. 먼저 이 링크로 접속합니다. 👉 Maven Repasitory
Spring Boot Starter Mustache 를 찾습니다.
가장 최신 버전을 누르고 [Maven] 내용을 복사합니다.

그리고 'pom.xml' 파일의 'dependencies' 태그 안쪽에 내용을 붙여넣기 합니다.
저번에 데브툴, 자바 웹 라이브러리를 붙여넣기 한 것과 같이 라이브러리를 추가하는 작업입니다.
붙여넣기 한 내용 중 'version' 부분은 삭제합니다.

그리고 라이브러리를 추가했기 때문에 저장에서 그치는 게 아니라 껐다가 다시 켜주는 게 안전합니다.
콘솔창 우측 [빨간 네모 버튼]과 바로 왼쪽의 ['X'두겹 버튼]을 눌러 앱을 종료합니다.(아래 캡쳐 참고)
그리고 다시 Run As - Spring Boot App 으로 서버를 다시 동작시킵니다.
혹시 이 글을 보는 분 중 궁금한 분이 계실까 싶어 정상적으로 실행됐을 때 나오는 내용을 아래에 첨부합니다.

이제 'static' 폴더 우클릭 New - Other html 파일을 하나 생성합니다.(mustache가 없기 때문)
그리고 html 파일을 누르고 [F2] 키를 눌러 파일 확장자를 '.mustache'로 변경합니다.
이 파일에 내용은 아래와 같이 입력합니다.
'h1' 태그의 내용을 제외하고는 이미 템플릿이 적용되어 나머지 내용은 적혀있습니다.
사실 이렇게 들여쓰기 되어있지 않았지만 뭔가 답답해서 해두었습니다.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		<h1>This is mustache</h1>
	</body>
</html>

다시 'HttpRespController' 클래스로 돌아가 아래와 같이 메서드를 추가합니다.

@GetMapping("/mus")
public String mus() {
	return "b.mustache";
}

mustache 파일의 내용을 문자열로 응답받습니다. 'https://localhost:8080/mus'로 접속합니다.
이번에는 파일 내용을 보여주지 않고 'mus'라는 파일을 다운로드 받습니다.
위에서는 웹 브라우저가 txt 파일 내용은 보여주었지만 이 파일은 해석하지 못해 파일로 다운로드 받는 것입니다.

이 파일이 이해받기 위해서는 'static'이 아니라 같은 경로의 'templates' 폴더에 넣어야합니다.
파일을 이동시키고 아래와 같이 위의 메서드 리턴 부분에서 확장자를 지웁니다.

@GetMapping("/mus")
public String mus() {
	return "b";
}

성공적으로 파일을 해석하고 응답합니다.
위에서 등록한 템플릿 엔진 라이브러리가 등록 완료되었기 때문에 'templates' 폴더에 파일을 두고
리턴 값으로 확장자 없이 파일명만 적으면 자동으로 파일을 찾습니다.

ㄷ) jsp 파일 응답하기

다시 'Maven Repository' 사이트로 가서 Tomcat Jasper 를 찾습니다.
글을 쓰는 현재(2023-02-22) 11버전까지 나왔지만 강의에서는 9.0.41 버전을 등록합니다.
지난번 이 버전을 등록했다가 에러 난 적이 있어서 저는 그냥 최신버전으로 등록하겠습니다.
'pom.xml'에 등록합니다. 이때 아까 등록한 'mustache' 부분은 템플릿 엔진이 중복될 수 없기 때문에 주석처리합니다.
등록이 완료되면 서버를 재시작합니다. 저는 서버를 새로 시작할 때마다 조마조마 합니다.

이 라이브러리는 스프링부트가 지원을 하지 않기 때문에 'mustache'와 달리 기본 경로를 설정해야합니다.
src - main 에 'webapp/WEB-INF/views'라고 폴더를 생성합니다.
그러면 폴더 안에 폴더가 생기게 됩니다. 'views' 폴더에 Other - JSP File 'c.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>
	</head>
	<body>
		<h1>This is c.jsp</h1>
	</body>
</html>

그리고 다시 'HttpRespController' 클래스에 메서드를 추가합니다.

@GetMapping("/jsp")
public String jsp() {
	return "c";
}

저장하고 도메인 따라 접속합니다. 이제 mustache 링크는 작동하지 않고

404 에러창이 나타납니다.

스프링부트가 'jsp'를 지원하지 않기 때문에 추가적인 설정이 필요합니다.

src/main/resources 의 'application.properties' 파일의 확장자를 'yml'로 변경하고 아래와 같이 작성합니다.
spring.mvc.view.prefix 마침표마다 자동완성이 나타나는데 그대로 따라갑니다. 저장하면 서버가 리로드됩니다.

spring:
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

이 부분은 yml 의 이해 부분에서 본 기억이 납니다.
아무튼 다시 메서드로 만든 도메인에 접속합니다. 파일을 잘 읽어 왔습니다.
위에서 기본 경로를 설정한 것을 'ViewResolver 설정'이라고 합니다.

현재 jsp 엔진을 사용하고 있고 기본 경로는 방금 만든 webapp 폴더가 기본 경로가 됩니다.
그래서 리턴으로 'c'를 찾으면 'webapp' 이하 'c'라는 이름을 가진 파일을 찾습니다.
그중에서 'prefix: /WEB-INF/views/' 경로와 리턴값 'c'에 'subfix: .jsp'를 찾습니다.

결국 'src/main/webapp/WEB-INF/views/c.jsp'를 찾는 것입니다.
이 과정을 위에서 언급한 ViewResolver 가 도와줍니다.


JSON - MessageConverter
JSP - ViewResolver

profile
백엔드 포지션 공부 중입니다.

0개의 댓글