Spring MVC Core

DeadWhale·2022년 11월 12일
0

Spring-MVC-Core

목록 보기
5/6
post-thumbnail

Spring MVC 기본 지원 기능

  • War : Tomcat이 외부에 있고 JSP를 사용할 때.

  • Jar : 내장 톰캣을 사용하고 webapp 경로도 사용 안함.

  • jar는 /resources/static/index.html이 Welcome페이지로 처리해준다

  • 운영 시스템에서는 System.out을 사용하지 않는다. == Logging라이브러리를 사용

    • Spring boot 는 로깅라이브러리를 기본 내장
    • logback , log4j , log4j2등 여러개가 있다.

Logger

importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;

@RestController
public classLogTestContoller {
private final Loggerlog = LoggerFactory.getLogger(LogTestContoller.class);

    @RequestMapping("/log-test")
		publicString logTest(){
        String name = "Spring";
        log.info("info-log = {}",name);
		return name;
    }
}
  • @RestController는 문자열이 아닌 값으로 반환한다는 의미
    • @RequestMapping은 뷰의 이름을 반환하는 것
  • slf4j를 Import해야 한다!!
  • private final Loggerlog 로그 객체 생성 후 slf4j의 구현체를 주입해줘야한다.
    LoggerFactory.getLogger(LogTestContoller.class)
    괄호 안에서는 사용하는 위치의 클래스를 넣어준다
  • { } 안에 String 넣어줘야 한다.
      • String를 이용해 출력하게 되면 문자열 객체를 + 연산하여 만들어 메모리를 소모하게 한다.
        출력하지 않는 레벨이여도 생성된다
  • Log는 Sysout과 다르게 파일로 남길 수 있다.
    • 파일로 남기면서 용량에 따른 파일 분할을 제공한다
    • 압축 , 백업 , 파일 개수 유지등 여러 기능이 제공된다.

Log는 성능 최적화면에서 sysout에 비해 압도적이다 !!

#hello . springmvc패키지와 하위 로그 레벨 설정

logging.level.hello.springmvc=debug;
logging.level.hello.springmvc=trace;

  • applicatoin.properties에서 설정한 레벨 수준으로만 Logger가 출력된다.
    • 개발 서버에서는 debug, warn등을 다 보며 개발할 수 있지만
      운영서버에서 모든 logger - level을 다 출력 시 Log문서가 너무 커진다
    • 계속 sys out 으로 출력하면 아주 난리난다.

Log Level

  • TRACE > DEBUG > INFO > WARN > ERROR
  • 개발 서버는 DEBUG
  • 운영서버는 INFO
  • Default가 : INFO
    • loggin.level.root = INFO == Default Setting

@Slf4j 으로 사용

@Slf4j
@RestController
public classLogTestContoller {
	//private final Logger log = LoggerFactory.getLogger(LogTestContoller.class);
  • 어노테이션 등록시 자동으로 사용할 수 있게 해준다.

Request Mapping

@RestController()

@RequestMapping( URL패턴 , method )

  • URL 패턴이 두개가 들어가도 허용된다

  • 두개의 경로 허용

  • method으로 요청 종류를 고정할 수 있다.

  • / hello-basic

  • / hello-basic /

  • 두개는 별개의 패턴이지만 Spring은 더미 슬래쉬로 이해해 처리해준다.

@PathVarilable


@GetMapping("/mapping/{userId}")
	public String mappingPath(@PathVariable("userId") String data){
	return data;
}
  • URL 패턴에 들어가 있는 경로를 바로 변수로 받아 올 수 있다.
  • 회원 아이디 , 페이지 번호 , 주문 번호 등등 여러 정보
  • 파라미터 변수가 아니라 경로 변수이다

@GetMapping("/mapping/{userId}")

  • 경로명과 변수명이 동일하다면 (”path Name”) 을 생략할 수 있다.

@GetMapping(value = "/mapping-get" , params = "mode=test")

  • parameter가 일치해야 접근 가능

@GetMapping(value = "/mapping-header" , headers = "mode=header")

  • header에 일치해야 접근 가능
  • HTTP Header

@GetMapping(value = "/mapping-header" , consumes = "application/json")

  • Content - type이 일치해야 접근 가능
  • 요청의 컨텐츠 타입을 소비하기 때문에 consumes
  • 생산시에는 produce
  • 요청 해더의 Content - Type

@PostMapping(value = "/mapping-produces" , produces = "text/html")

  • 클라이언트에게 해당 자료형으로 보낸다
    • text/html
  • 요청 헤더의 Accept를 기준

MediaType으로 미리 구현이 되어있다.


요청 매핑 API 예시

@RestController
public class MappingClassController {

    @GetMapping("/mapping/users")
    public String user(){return "get users";}

    @PostMapping("/mapping/users")
    public String addUser(){return "add users";}

    @GetMapping("/mapping/users/{userId}")
    public String findUser(@PathVariable String userId){return "find users : " + userId;}

    @PatchMapping("/mapping/users/{userId}")
    public String patchUser(@PathVariable String userId){return "patch users : " + userId;}

    @DeleteMapping("/mapping/users/{userId}")
    public String deleteUser(@PathVariable String userId){return "delete users : " + userId;}
}

@PatchMapping 등으로 매우 편하게 조회할 수 있다.

HTTP Header 정보를 조회하는 방법

필요한 파라미터를 다양한 방식으로 가져올 수 있다.

@RequestMapping("/headers")
    public String headers(HttpServletResponse response,
                          HttpServletRequest request,
                          HttpMethod httpMethod,
                          Locale locale,
                          @RequestHeader MultiValueMap<String,String> headerMap,
                          @RequestHeader("host") String host,
                          @CookieValue(value="myCookie", required = false) String cookie
                          ){
        log.info("{}",request);
        log.info("{}",response);
        log.info("{}",httpMethod);
        log.info("{}",locale);
        log.info("{}",headerMap);
        log.info("{}",host);
        log.info("{}",cookie);

        return "String";
    }
  • MultiValueMap<String,String> ?
    • 하나의 Key에 여러개의 Value를 가질 수 있다.
    • 반환 자료형은 배열(?)
  • @CookieValue(value="myCookie", required = false) String cookie
    • 스프링은 하나의 값을 꺼낼 경우가 발생하면 필수 여부와 디폴트를 항상 지정 할 수 있다.
h.s.b.request.RequestHeaderController    : org.apache.catalina.connector.RequestFacade@590cdf37
h.s.b.request.RequestHeaderController    : org.apache.catalina.connector.ResponseFacade@7844d298
h.s.b.request.RequestHeaderController    : DELETE
h.s.b.request.RequestHeaderController    : ko_KR
h.s.b.request.RequestHeaderController    : {user-agent=[PostmanRuntime/7.29.2], accept=[*/*], postman-token=[7aa5a50d-60cf-4f0c-a66f-c2f338809c56], host=[localhost:8080], accept-encoding=[gzip, deflate, br], connection=[keep-alive]}
h.s.b.request.RequestHeaderController    : localhost:8080
h.s.b.request.RequestHeaderController    : null

HTTP 요청 파라미터

요청의 3 종류

  • GET - 쿼리 파라미터
    • URI 뒤로 연결
  • POST - HTML FORM
    • 메시지 바디에 쿼리파라미터 형식으로 전달ㄴ
  • HTTP Message Body - 데이터를 body에 담아 전달
    • JSON , XML
    • API에서 사용

GET 과 POST는 둘 모두 담기는 위치만 다를 분 같은 데이터 형식임으로 구분 없이 조회 할 수 있다.

  • request.getParameter(”파리미터명”);

파라미터를 받는 방식

------------------------------------------------
--@RequestParam( “ 파라미터 명 “ )  자료형 변수명
@RequestParam("username") String memberName,
@RequestParam("age") int age
------------------------------------------------
-- @RequestParam 자료형 
@RequestParam String username,
@RequestParam int age
------------------------------------------------
-- 자료형 변수명(파라미터명과 동일한 )
String username , *int* age

다만 RequestParam을 완전 생략하는 건 팀의 스프링 숙련도를 고려하는 것이 좋다.

필수 여부를 확인

@RequestParam(required = *true)* String username,

  • required 을 활용해 필수로 받아야 할지 선택적일지를 판단 할 수 있다.
  • 기본값 = 필수 ( true )
  • Int 자료형을 필수로 받을 경우 공백(””)이 넘어오게 되면 문제가 발생한다
    • Integer으로 선언하는 방식으로 해결 가능

기본 값을 대입

@RequestParam(required = *true* , defaultValue = "requi") String username,

  • required 가 필수여서 값이 반드시 있어야 하지만 없을 경우 defaultVaue의 값으로 대체

값을 한번에 받는 방식

@RequestParam *Map*<String,Object> paramMap

  • 파라미터명, 값의 형태로 전달된 모든 파라미터를 받을 수 있다.
  • paramMap.get(”파라미터명”)으로 꺼내쓰면 된다

하나의 키에 여러개의 값을 받는 방식

@RequestParam *MultiValueMap*<String,Object> paramMap

  • 하나의 Key에 여러개의 Value를 가질 수 있다.
  • 잘 쓰는 경우가 없다 정확도가 떨어지고 자주 그럴 일이 없다.

@ModelAttribute

  • 객체 대입을 편하게 해준다.
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
    return helloData.toString();
}

@Data

  • Lombok의 기능
  • 아래의 기능들을 전부 적용해준다.
    • Getter
    • Setter
    • RequiredArgsConstructor
    • ToString
    • EqualsAndHashCode, Value

ModelAttribute가 있는 경우

  1. 해당 객체를 생성
  2. 객체의 파라미터 이름과 동일한 객체 프로퍼티에 세팅한다
    1. 프로퍼티 = Get , Set
  • 타입이 달라 바인딩이 제대로 안될 경우 예외가 발생한다.

    • BindException
  • @ModelAttribute 도 생략이 가능하다

  • String , int , Integer 와 같은 단순 타입 자료형의 경우

    • @RequestParam 으로 인식
  • 그 외 객체 자료형

    • @ModelAttribute 으로 인식

출처

  • 영한님의 Spring MVC 핵심 강의를 기반으로 학습한 내용을 정리한 것입니다.

0개의 댓글