[스프링부트] - Web MVC

2025. 4. 22. 20:37·Spring
728x90
반응형
SMALL

Spring Web MVC 구조

MVC 아키텍처 흐름이다. 

여기서 Servelet이 Front Controller를 담당한다. 

요청에 따라 해당 Controller로 매핑이 된다. 

응답으로 보여줄 View를 처리한다.

  • Controller는 손님을 맞이한다고 생각하면 된다. (배웅까지는 덤)
  • Model은 db에서 데이터를 뽑아오거나 집어넣는다.
  • View는 사용자 눈에 보이는 것 

이라고 생각하면 쉽다.

 

  • @Controller // @RestController 
    • 사용 위치: 클래스 
    • Controller : html을 사용시 컨트롤러를 사용
    • RestController: Json사용시 RestController 사용
      • html파일을 사용하지 않아서 있는 그대로 리턴값을 페이지에 출력해준다.
      • API서버를 만들 때 유용

@Controller

package com.example.basic.controller;

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

@Controller
public class HtmlController {
    @GetMapping("html/string")
    public String htmlString() {
        return "html/string";
    }
}

그럼 html패키지 안에 string.html을 찾아 웹 브라우저에 string.html값을 출력해준다.

 

@RestController

package com.example.basic.controller;

import java.util.HashMap;
import java.util.Map;

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

@RestController
public class Json2Controller {
    @GetMapping("json2/map")
    public Map<String, Object> jsonMap(Map<String, Object> map) {
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("key1", "value");
        map2.put("key2", 2324);
        map2.put("key3", true);
        return map2;
    }

}

json2/map을 Get요청시

이렇게 JSON형식으로 나오게 되는 것을 볼 수 있다.

 

@Post // @Get

특정 HTTP 메소드 Post와 Get만을 처리하기 위해 딱 꼬집어서 사용하는 전용 어노테이션이다.

 

@GetMapping

HTTP 뒤에 ?가 붙어서 나오는 요청이에 대한 반환 이라고 보면 쉽다.

 @GetMapping("req/get2")
    public String get2(String name, int id){
        return String.format("나이 %s 아이디 %s",name, id );
    }

@RestController 밑에 있는 get2를 GetMapping하는 메서드이다.

http://localhost:8080/req/get2?name=jang&id=1234

name을 jang으로 하고 id를 1234로 하면 어떻게 html에 나올까?

예상했겠지만

이렇게 웹 브라우저에 출력이 되는 것을 볼 수 있다.

그래서 데이터가 URL에 노출되기 때문에 민감한 데이터를 보내는데는 적합하지 않다.

주로 서버로부터 데이터를 조회(읽어올 때) 사용된다.

 

 

 

@PostMapping

Get과 다르게 URL에 데이터를 붙여서 보내지 않는다.

HTTP 요청 메시지 본문(Body)에 담겨서 전송이 된다.

프론트에서 폼 데이터를 입력하고 제출 시 HTTP 요청 본문에 담겨 서버로 보내짐

JSON형태의 데이터를 본문에 담아 보내는것이 일반적

주로 데이터 생성 or 업데이트 할 때 사용됨

 

 

@RequestParam

클라이언트에서 보내오는 요청을 받아낼 때 사용한다. (? 뒤에 오는 값들)

보통 메서드 매개변수에 사용한다.

개별 파라미터 값을 메소드의 단일 인자에 바인딩시 사용한다.

@GetMapping("req/get")
    // 리퀘스트 파람 뒤에 받고싶은 명칭
    // requestParam사용시 값 넣어서 처리 가능
    public String get(@RequestParam) Integer page,
            @RequestParam() String search) {
                return String.format("%s페이지 %s", page, search);
    }

 

만약에

http://localhost:8080/req/get?search=dog

요청값을 이렇게 보냈다고 하자

그럼 어떻게 나올까?

브라우저에 이렇게 Required parameter page가 없다고 뜬다.

 

그럼 RequestParam안에 있는 매개변수를 입력해주면 어떻게 될까?

    @GetMapping("req/get")
    // 리퀘스트 파람 뒤에 받고싶은 명칭
    // requestParam사용시 값 넣어서 처리 가능
    public String get( /*HttpSession session*/@RequestParam(required = false, defaultValue = "") Integer page,
            @RequestParam(required = false, defaultValue = "") String search) {
                // session.setAttribute("abcd","1234");
                return String.format("%s페이지 %s", page, search);
    }

required = false : 해당 요청에 포함되어도 되고, 생략되어도 된다.

defaultValue = " ": 데이터가 생략되었으면 디폴트 벨류를 설정해준다.

http://localhost:8080/req/get

이렇게 요청하면 어떻게 될까?

 

이렇게 null과 아무런 값이 나오지 않는다.

※null이 나오는 이유: Integer는 참조 자료형이기 때문에 초기값이 null이다. 그래서 아무 값을 입력하지 않으면 null이 출력되는 것을 볼 수 있다.

 

@ModelAttribute

※@RequestParam과의 차이점@RequestParam: 1:1 로 매핑시키냐@ModelAttribute: 복합객체로 매핑시키냐

이 차이인듯??

 

여러 파라미터값 즉 복합객체 DTO에 바인딩 할 때 사용한다.

많은 양의 데이터 ex)회원정보, 글 정보 등을 처리할 때 사용한다.

Post방식은 일반 URL에 직접 입력하면 안되고

Postman같이 테스트 프로그램을 사용하면 유용하다.

package com.example;

public class UserDTO {
    private String username;
    private int userAge;
    private String email;

    // Spring이 객체를 생성하고 데이터를 주입할 때 필요합니다.
    // (기본 생성자는 필수)
    public UserDTO() {
    }

    // 필드 값을 받는 생성자 (선택 사항이지만 있으면 편리)
    public UserDTO(String username, int userAge, String email) {
        this.username = username;
        this.userAge = userAge;
        this.email = email;
    }

    // Getter 및 Setter 메소드 (Spring이 속성에 접근하고 값을 설정하기 위해 사용)
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getUserAge() {
        return userAge;
    }

    public void setUserAge(int userAge) {
        this.userAge = userAge;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Post를 위해 임의로 DTO를 만들었다.

@RestController
public class UserController {
    @PostMapping("/submit-user-form")
    public String handleUserForm(@ModelAttribute UserDTO userdto) {
        // @ModelAttribute 어노테이션 덕분에 Spring이 요청 파라미터들을
        // UserForm 객체의 필드(username, userAge, email)에 자동으로 바인딩하여
        // userForm 인자로 전달해 줍니다.

        System.out.println("--- 받은 사용자 정보 ---");
        System.out.println("이름: " + userdto.getUsername());
        System.out.println("나이: " + userdto.getUserAge());
        System.out.println("이메일: " + userdto.getEmail());
        System.out.println("---------------------");

        // 받은 데이터를 포함한 응답 문자열 반환
        return "사용자 정보가 성공적으로 접수되었습니다: " + userdto.toString();
    }

/submit-user-form으로 body에 form형식 데이터를 제출시

 

200OK가 뜨면서 사용자 정보가 성공적으로 접수되었다고 뜬다.

 

그럼 콘솔에서는 어떻게 뜰까?

이렇게 내가 Postman에서 입력한 값들이 뜨게 된다.

@PostMapping 설명의 확장이라고 보면 된다.

 

@PathVariable

"/{경로변수}"로 오는 요청을 받을 때 사용하면 유용하다.

경로 변수는 {}(중괄호)로 둘러싸인 값을 나타낼 때 사용된다.

URL경로에서 매개변수값을 추출하여 매개변수에 할당한다.

기본적으로 무조건 값을 가져야하며 값이 없을 시 NULL반환

※주로 상세 조회, 수정, 삭제에서 많이 사용된다.

아래의 코드는 게시판의 상세조회하는 코드이다.

	@GetMapping("/board/view/{id}")
	public String boardView(
		@PathVariable("id") Long id, Model model
	) {
		Optional<Board> opt = boardRepository.findById(id);
		if(opt.isEmpty()){
			return "redirect:/board";
		}
		else{
			Board board = opt.get();
			model.addAttribute("board", board);
		}
		return "board/view";
	}

해당 경로로 /board/view/2를 받으면 id값이  PathVariable로 들어간다.

그럼 boardRepository Jpa를 이용해서 id로 board에 DB테이블을 매핑한다.

opt가 비어있으면 다시 board로 redirection하고 

opt에 값이 있으면 board객체에 opt.get()을 이용하여 불러와 넣어준다.

그 후 model.addAttribute로 front에 값을 "board"형식으로 넘겨준다.

 


※Post 요청 방법

1. HTML의 <form> 태그에 method 속성 사용

    ex) <form method="post">

 

2. JavaScript의 fetch() 함수 사용

    ex) fetch('https://api.google.com/user', { method: 'post' })

 

3. 외부 프로그램 사용

    ex) Postman, Talend API Tester


@RequestMapping

RequestMapping은 

 Get, Post,Put, Delete 모두 지원한다.

요즘에는 잘 안쓴다.

but, 한번씩 클래스에 requestMapping사용시 

모든 메소드에 접두어를 공통으로 사용하기위해서

ex) /user클래스의 모든 메소드에 적용 ex)add메소드,list메소드

/user/add                /user/list 

와같이 유용하게 사용된다.

@RequesMapping(value= "/jpa")와 같이 붙여주면 /jpa/add나 이렇게 할 수 있다.


 

@ResponseBody

메소드에서 생존하는 어노테이션이다.

@Controller는 메소드가 문자열 등을 반환하면 View는 기본적으로 이름을 해석하여 html파일을 랜더링하여 응답본문에 담아 보낸다.

BUT 

@ResponseBody어노테이션을 사용하면 메소드의 반환값을 HTTP 응답의 Body로 직접 전송하는 어노테이션이다.

package com.example.basic.model;

import lombok.Getter;
import lombok.Setter;

//스프링이 실행될 때
//Java 컴파일러가 컴파일 할 때때
@Setter
@Getter
public class Member {
    String name;
    public Member(){
    }

    public Member(String name){
        this.name = name;
    }
}

Member 클래스를 생성하고 Getter와 Setter로 생성자 생성한다.

    @GetMapping("json1/list")
    @ResponseBody
    public List<Member> jsonList() {
        List<Member> list = new ArrayList<>();
        // List에 멤버 저장시
        Member member = new Member();
        member.setName("KIM");
        list.add(member);

        // 생성자 클래스에 만들면 한줄로 바꿀 수 있다
        list.add(new Member("Lee"));
        return list;
    }

ResponseBody에 담아서 list리턴시 어떻게 뜰까?

이렇게 List형식안에 JSON으로 나오는 것을 확인할 수 있다.

 

여기서 tip

그럼 RestController하나쓰는것과 Controller + ResponseBody를 같이사용하면 같아지는 것이다.

@RequestBody

중간에 스프링이 개입을 해서 텍스트를 JSON형태로 convert해주는 MessageConverter이다.

리액트와 통신할 때 주로 사용 JSON 형태의 데이터라고 생각하면 쉽다.


HTML 템플릿 응답

String

@Controller
public class HtmlController {
    @GetMapping("html/string")
    public String htmlString() {
        return "html/string";
    }
}

string.html을 찾아서 랜더링 한다.

 

Map

@GetMapping("json1/map")
@ResponseBody
public Map<String, Object> jsonMap(Map<String, Object> map) {
    Map<String, Object> map2 = new HashMap<String, Object>();
    map2.put("key1", "value");
    map2.put("key2", 2324);
    map2.put("key3", true);
    return map2;
}

List, Object DTO들은 다 메소드의 리턴타입만 바꿔주기만 하면된다.

@HttpServletRequest

가장 전통적으로 사용되는 요청처리방식이다.

@RestController
public class RequestController {
    @GetMapping("req/http")
    public String http(HttpServletRequest request) {
        String name = request.getParameter("name");
        String pageNum = request.getParameter("pageNum");
        return name + ", " + pageNum;
}
}

HttpServletRequest 클래스 request객체를 파라미터로 받는다.

그 후 request객체의 메서드 getParameter로 값을 받아서 웹 브라우저에 띄워준다.

 

 

 


응답처리 요약

1.HTML

  • @Controller + String

 

2.JSON

  • @Controller + @ResponseBody + (Map/List/DTO)
  • @RestController + (Map/List/DTO)

 

728x90
반응형
LIST

'Spring' 카테고리의 다른 글

[스프링 부트] -Spring JDBC  (1) 2025.04.25
[스프링 부트] - AJAX 요청 파라미터 전달  (1) 2025.04.24
[스프링부트] - 컨트롤러와 어노테이션들  (0) 2025.04.22
[스프링부트] - DI, IoC 와 Bean  (0) 2025.04.22
[스프링부트] - Maven 개발환경 준비하기 feat. VSCode  (1) 2025.04.22
'Spring' 카테고리의 다른 글
  • [스프링 부트] -Spring JDBC
  • [스프링 부트] - AJAX 요청 파라미터 전달
  • [스프링부트] - 컨트롤러와 어노테이션들
  • [스프링부트] - DI, IoC 와 Bean
코린이 파닥거리기
코린이 파닥거리기
    반응형
    250x250
  • 코린이 파닥거리기
    코린이 파닥거리기의 블로그
    코린이 파닥거리기
  • 전체
    오늘
    어제
    • 분류 전체보기 (117) N
      • 백준[파이썬] (48) N
      • Spring (31)
      • CS (1)
      • 자바 (4)
      • 백준[자바] (20)
      • 프로그래머스 (5)
      • 토이프로젝트 (1)
      • SWEA (2)
      • MSA (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Java
    SWEA
    MSA
    파이썬
    JPA
    코딩테스트
    스프링
    SpringBoot
    누적합
    테스트코드
    스프링 부트와 AWS로 혼자 구현하는 웹 서비스
    스프링부트
    JWT
    자바
    백준
    db
    컨테이너
    spring
    프로그래머스
    재귀
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코린이 파닥거리기
[스프링부트] - Web MVC
상단으로

티스토리툴바