본문 바로가기
[study]이론정리/Spring Boot

Spring MVC - @RequestMapping_pattern

by yoon9i 2024. 7. 2.

3> 요청맵핑값의 패턴
- @RequestMapping("요청맵핑값")

ex>
  // 1. 맵핑값 하나
@RequestMapping("/list")
public String list() { 

logger.info("logger: MainController:{}", "/list요청");
return "hello"; 
}

// 2. 맵핑값 여러개
// String [] xx = {값,값};
@RequestMapping(value = {"/list2", "/listAll"})
public String list2() { 

logger.info("logger: MainController:{}", "/list요청");
return "hello"; 
}

// 3. 특정값으로 시작
@RequestMapping("/update*")
public String update() { 

logger.info("logger: MainController:{}", "/update* 요청");
return "hello"; 
}

// 4. 특정경로 하나
// http://localhost:8090/app/delete/
// http://localhost:8090/app/delete/임의의경로
// delete/ 뒤에 하나만 와야함 
// delete/xx/yy 하면 Whitelabel Error Page 발생
@RequestMapping("/delete/*")
public String delete() { 

logger.info("logger: MainController:{}", "/delete/* 요청");
return "hello"; 
}

// 5. 특정경로 여러개
// http://localhost:8090/app/add/[임의의경로, 임의의경로,...]
@RequestMapping("/add/**")
public String add() { 

logger.info("logger: MainController:{}", "/add/** 요청");
return "hello"; 
}

// 6. 경로중간에 패턴지정
// http://localhost:8090/app/add/[임의의경로, 임의의경로,...]
@RequestMapping("/find/**/board")
public String find() { 

logger.info("logger: MainController:{}", "/find/**/board 요청");
return "hello"; 
} <== 패턴에러

  # MainController 에서 6. 경로중간에 패턴지정 하기 위한 설정. 
  spring.mvc.pathmatch.matching-strategy=ant-path-matcher
  
  # 참고사이트
  https://docs.spring.io/spring-boot/docs/2.7.18/reference/html/web.html#web.servlet.spring-mvc.content-negotiation

 

Web

Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and servlet-based web applications. It occurs as part of closing the application context and is performed in the earliest

docs.spring.io

 

package com.exam;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}
package com.exam.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
	// 1. 맵핑값 하나
	@RequestMapping("/list")
	public String list() { 
		
		logger.info("logger: MainController:{}", "/list요청");
		return "hello"; 
	}
	
	// 2. 맵핑값 여러개
	// String [] xx = {값,값};
	@RequestMapping(value = {"/list2", "/listAll"})
	public String list2() { 
		
		logger.info("logger: MainController:{}", "/list요청");
		return "hello"; 
	}

	// 3. 특정값으로 시작
	@RequestMapping("/update*")
	public String update() { 
		
		logger.info("logger: MainController:{}", "/update* 요청");
		return "hello"; 
	}
	
	// 4. 특정경로 하나
	// http://localhost:8090/app/delete/
	// http://localhost:8090/app/delete/임의의경로
	// delete/ 뒤에 하나만 와야함 
	// delete/xx/yy 하면 Whitelabel Error Page 발생
	@RequestMapping("/delete/*")
	public String delete() { 
		
		logger.info("logger: MainController:{}", "/delete/* 요청");
		return "hello"; 
	}
	
	// 5. 특정경로 여러개
	// http://localhost:8090/app/add/[임의의경로, 임의의경로,...]
	@RequestMapping("/add/**")
	public String add() { 
		
		logger.info("logger: MainController:{}", "/add/** 요청");
		return "hello"; 
	}
	
	// 6. 경로중간에 패턴지정
	// http://localhost:8090/app/add/[임의의경로, 임의의경로,...]
	@RequestMapping("/find/**/board")
	public String find() { 
		
		logger.info("logger: MainController:{}", "/find/**/board 요청");
		return "hello"; 
	}
}
<%@ page 
         contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"        
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p>안녕하세요</p>
<p>Hello</p>
</body>
</html>
<%@ page 
         contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"        
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>로그인화면</h2>
<form action="login"  method="post">
아이디:<input type="text" name="userid"><br>
비번:<input type="text" name="passwd"><br>
<input type="submit" value="로그인">
</form>
</body>
</html>
# application.properties
logging.level.org.springframework=info

# tomcat port 번호 변경
server.port=8090

# context 명 변경
server.servlet.context-path=/app

# jsp의 경로와 확장자 지정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp


spring.mvc.pathmatch.matching-strategy=ant-path-matcher
<?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 
	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.18</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.exam</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-devtools</artifactId>
		</dependency>
	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-jasper</artifactId>
		<scope>provided</scope>
	</dependency> 
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
	</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 

3-1> 요청맵핑값의 패턴2

  @RequestMapping("요청맵핑값") 의 클래스 레벨 사용가능

  # 현재
  ==> 필요기능: 회원정보보기/ 회원생성하기/ 회원수정하기/ 회원삭제하기/ ...

    @RequestMapping("/member")
    @RequestMapping("/member/list") // 회원정보보기
    @RequestMapping("/member/add") // 회원생성하기
    @RequestMapping("/member/update") // 회원수정하기
    @RequestMapping("/member/delete") // 회원삭제하기
    
    단, member 가 중복되는 단점이 있다.
    아래의 방법으로 중복사용을 방지할수있다.

  # 적용 (클래스레벨, 메서드레벨 에서 사용가능하다.)
  @RequestMapping("/member") // 클래스레벨
  public class MainController2 {
    @RequestMapping("/list") // 메서드레벨
    public String list() {}

    @RequestMapping("/add")
    @RequestMapping("/update")
    @RequestMapping("/delete")

    @RequestMapping
    public String default() {} // 무조건 맵핑값을 지정해야하는것은 아니다.

  }

package com.exam.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/member")
public class MainController2 {
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
	// http://localhost:8090/app/member/list
	@RequestMapping("/list")
	public String list() {
		logger.info("logger:MainController2:{}", "/list 요청");	
		return "hello"; 
	}
	@RequestMapping("/add")
	public String add() {
		logger.info("logger:MainController2:{}", "/add 요청");	
		return "hello"; 
	}

}

 

3-2> 요청맵핑값의 패턴3
- GET|POST 방식 명시 가능.
ex>
  로그인(회원가입) 작업은 반드시 2번 요청해야된다.
  이유는 첫번째 요청은 화면요청이고 두번째 실제 로직요청이다.

  # 현재
  @RequestMapping("/loginForm") <== 화면요청, GET 방식이용이 일반적
  public String loginForm(){}

  @RequestMapping("/login") <== 로직요청, POST 방식이용이 일반적
  public String login(){}

  # 적용
  ==> 요청 맵핑값은 /login 으로 동일한지만 method 방식이 달라서 요청에 대한 식별이 가능하다.
  @RequestMapping("/login", method=RequestMethod.GET) <== 화면요청, GET 방식이용이 일반적
  public String loginForm(){}

  @RequestMapping("/login", method=RequestMethod.POST) <== 로직요청, POST 방식이용이 일반적
  public String login(){}


  * Spring Framework 4.3 이후에 어노테이션이 추가됨.

  @RequestMapping(value="/login", method = RequestMethod.GET) 해당되는
  ==> @GetMapping("/login")

  @RequestMapping(value="/login", method = RequestMethod.POST) 해당되는
  ==> @PostMapping("/login")

  * PRG(Post-Redirect-Get) 패턴을 적용해서 최종적인 작업은 post 가 아닌 get 로 처리해야된다.
  https://gofo-coding.tistory.com/entry/PRG-%ED%8C%A8%ED%84%B4-Post-%E2%86%92-Redirect-%E2%86%92-Get

  (참고사이트)

package com.exam.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
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;

@Controller
public class MainController3 {
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
	// 화면 요청
//	@RequestMapping(value="/login", method = RequestMethod.GET)
	@GetMapping("/login")
	public String list() {
		return "loginForm"; 
	}
	
	// 로직 요청
//	@RequestMapping(value="/login", method = RequestMethod.POST)
	@PostMapping("/login")
	public String add() {
//		return "hello";
		return "redirect:xxx"; // post 를 redirect 해서 get 방식으로 바꾼다.
	}
	// post 방식으로 끝내면 안되기에 PRG 패턴으로 끝내야한다.
	// `redirect:` 는 redirect 방식
	// `forward:` 는 forward mapping 값 주는것.
	
	// PRG 패턴적용
	@GetMapping("/xxx")
	public String hello() {
		return "hello"; 
	}

}