Spring : 1일차

지환·2023년 12월 18일

Spring

목록 보기
3/7

@RestController // @Controller 다르게 응답이 page가 아니라 text/plain이다.
@RequestMapping("/step1/*") // 공통url 매핑
public class HomeController {
    // url -> http://localhost:8000/step1/home
    @GetMapping("home") // doGet을 의미한다.
    public String home(String param) {
        // url -> http://localhost:8000/step1/home?param=1이라고 하면 param에 1이 담겨진다.
        // 스프링에서는 request.getParameter를 쓰지 않고도 파라미터 자리에 넣어주는 것 만으로 자동으로 담긴다.(928page)
        return "반환되는 문자열";
    }

}
  • http://localhost:8000/step1/home?param=1이라고 하면 param에 1이 담겨진다.

  • @RestController : @Controller와 다르게 응답이 Page가 아니라 text/plain이다.(마임타입)

    • 페이지 출력이 아닌 모든 경우에 사용이 가능하다.
  • 스프링에서는 서블릿과 다르게 메소드마다 url매핑이 가능하다.

 @GetMapping("home") // doGet을 의미한다.
    public String home(String param) {
        return "반환되는 문자열";
    }
  • 메소드가 자동으로 호출된다.

위애서

@RestController // @Controller 다르게 응답이 page가 아니라 text/plain이다.
@RequestMapping("/step1/*") // 공통url 매핑
public class HomeController {
    @GetMapping("home") // doGet을 의미한다.
    public String home(String param) {

        return "반환되는 문자열";
    }
}

이렇게 class에서 @RequestMapping으로 경로를 잡아둔다면,

url -> http://localhost:8000/step1/home 로 해석된다.

메소드에 @GetMapping() 으로 경로 설정을 하고

public String home(String param)으로 설정한다면

mapping 종류 2번에 해당한다.

  1. exact mapping - /basic/hello.do -> http://localhost/basic/hello.do

  2. path mapping - /basic/*

    http://localhost/basic/hello.do
    http://localhost/basic/hello
    http://localhost/basic/
    http://localhost/basic/test

  3. extension mapping - .do, .gd
    :확장자가 do로 끝나기만 한다면 내가 가로챌께
    http://localhost/basic/hello.do
    http://localhost/basic/login.do
    http://localhost/basic/logout.do

  4. default mapping
    :위에서 부터 따져보다가 어디에도 해당되지 않으면 디폴트가 적용됨
    http://localhost/basic/hello.do
    http://localhost/basic/hello
    http://localhost/basic/
    http://localhost/basic/test


Test를 해보자.

url : http://localhost:8000/step1/home?param=안녕

이라고 했을 떄,
step1 : 클래스 @RequestMapping(step1)
home : 메소드 @GetMapping(home)

    @GetMapping("home") // doGet을 의미한다.
    public String home(String param, HttpServletRequest res) {
        // url -> http://localhost:8000/step1/home?param=1이라고 하면 param에 1이 담겨진다.
        // 스프링에서는 request.getParameter를 쓰지 않고도 파라미터 자리에 넣어주는 것 만으로 자동으로 담긴다.(928page)
        logger.info(param);
        return "반환되는 문자열";
        // return "home";
    }


Json으로 해보자 ㅎㅎ

Test Case : http://localhost:8000/step1/jsonTest

 @GetMapping("jsonTest") // doGet을 의미한다.
    public String jsonTest() {
        logger.info("jsonTest");
        List<Map<String, Object>> rList = new ArrayList<>();
        Map<String, Object> rmap = new HashMap<>();
        rmap.put("deptno", 10);
        rmap.put("dname", "총무부");
        rmap.put("loc", "인천");
        rList.add(rmap);
        logger.info(rList.toString());
        Gson g = new Gson();
        String temp = g.toJson(rList);

        return temp;
        // return "home";
    }


스프링의 특징

  • 스프링에서는 클래스와 빈은 같은 말이다. <bean id = myDuck class MallardDuck>

  • 스프링에선 빈관리를 해주고, spring-context.jar -> ApplicationContext에서 관리한다.

    • 스프링을 사용하면 객체에 대한 라이프사이클 관리를 뺴앗아간다.

    • 개발자는 객체에 대한 관리책임을 쥐고 있지 않는다.

  • 컨트롤 계층에 이라면, 응답페이지 처리에 대한 책임이 있다.

    • 필요할 때 요청객체응답객체를 사용할 수도 있다.

    • 메소드의 파리미터 개수에 제약이 없다.

      @GetMapping("home") // doGet을 의미한다.
       public String home(String param, HttpServletRequest res) {
           logger.info(param);
           return "반환되는 문자열";
           // return "home";
       }
      
    • req,res를 상속 받지 않았지만, 사용이 가능하다.

  • 관심사는 3가지이다. 입력(@RequestParam-HashMapBinder) - 처리 - 출력

페이지경로에 대하여

Test case : http://localhost:8000/user/loginForm

  • ModelAndView를 쓰고 있다는 건 WEB-INF로 간다는 것.
@Controller
@RequestMapping("/user/*")
public class UserController {
    Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("loginForm")
    public String loginForm() {
        return "./loginForm";
        // return "user/loginForm" 도 가능
    }
}

이 말은

둘 중에 하나가 응답한다. (/user/*)이여서 하지만 ModelAndView인 경우에는 WEB-INF안에 있는 경로가 되므로, views/user/loginForm이 된다.

[WEBINF-loginForm.jsp]

<%@ page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>로그인화면 - {WEB-INF}</title>
  </head>
  <body>
    <H2>로그인화면 - {WEB-INF}</H2>
  </body>
</html>

이 경로에 대한 설정을 스프링에선 .yml 파일에서 경로를 잡아주고 있다.

경로설정이 잘못되어있다. 답을 보지말고 설정해보자.

@Controller
@RequestMapping("/user/*")
// http://localhost:8000/user 이 말은 폴더위치를 webapp에서 찾는다는 것.
// url : http://localhost:8000/user/loginForm
public class UserController {
    Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("loginForm")
    public String loginForm() {
        return "user/loginForm";
    }
}

http://localhost:8000/user/loginForm 로 다시 시도해보자.

  • jsp파일을 적지 않았는데 어떻게 자동매핑 됐는가?

[application.yml]

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

redirect와 forward로도 해보자 ㅋ

url : http://localhost:8000/user/loginForm.jsp

뒤에 .jsp가 붙냐 안붙냐 차이점 존재함.

@Controller
@RequestMapping("/user/*")
// http://localhost:8000/user 이 말은 폴더위치를 webapp에서 찾는다는 것.
// url : http://localhost:8000/user/loginForm
public class UserController {
    Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("loginForm")
    public String loginForm() {
        return "redirect:/user/loginForm.jsp";
    }
}
  • /에 대한 설명은?

[application.yml]

server:
port: 8000
servlet:
  context-path: /
  encoding:
    charset: UTF-8
    enabled: true
    force: true

두개의 큰 차이점은 뒤에 .jsp가 붙어있지 않고 url매핑안에 user가 들어있는데 왜 ? http://localhost:8000/user/loginForm 이렇게 테스트 케이스를 가져가는가?

  • 그렇다면 RequestMapping을 왜 쓰는가?
@Controller
@RequestMapping("/user/*")
// http://localhost:8000/user 이 말은 폴더위치를 webapp에서 찾는다는 것.
// url : http://localhost:8000/user/loginForm
public class UserController {
    Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("loginForm")
    public String loginForm() {
        return "redirect:./loginForm.jsp";
    }
}

  • @RequestMapping(/user/*) : 요청시 이미 알고있다.

ModelAndView도 해보자.

@Controller
@RestController
@RequestMapping("/user/*")
// http://localhost:8000/user 이 말은 폴더위치를 webapp에서 찾는다는 것.
// url : http://localhost:8000/user/loginForm
public class UserController {
    Logger logger = LoggerFactory.getLogger(UserController.class);


    @GetMapping("loginForm2")
    public ModelAndView loginForm2() {
        return new ModelAndView();
    }
}
  • WEB-INF/views/user/loginForm2.jsp : 검색 시 사용

    • ModelAndView :
      • WEB-INF에서 찾는다.
      • Forward 유효범위를 갖는다.
      • Scope : Request이다. (url은 그대로 + 화면 바뀐다)
  • 지난 번 Pojo에서는

 [스프링버전]
    
    @GetMapping("loginForm2")
    public ModelAndView loginForm2() {
        return new ModelAndView();
    }
====================================================
 [Pojo버전]
 
    ModelAndView mav = new ModelAndView();
    mav.setViewName("loginForm2");  ==> @GetMapping("loginForm2")
    return mav;
  • 화면 이름을 생략하면 메소드 이름이 화면이름이 된다.(스프링이 주입한다.) -> 지금은 loginForm2가 없으니깐 404번이다.

생성 후 Test 해보자.

url : http://localhost:8000/user/loginForm2

return new ModelAndView() : 이렇게 줬을 뿐인데 스프링에서 알아서 매핑해준다.. 참 신기하네 ㅋ

mav.setViewName("loginForm2"); ==> @GetMapping("loginForm2")

Jsp - Action 컨트롤러에 대한 선택

Test Case : http://localhost:8000/user/login?mem_id=kiwi&mem_pw=123

Get방식은 화면이 없이도 Test를 할 수 있다.

    @GetMapping("login")
    public String login(HttpServletRequest req) {
        String mem_id = req.getParameter("mem_id");
        String mem_pw = req.getParameter("mem_pw");
        logger.info("mem_id" + mem_id + "mem_pw" + mem_pw);

        return "redirect:/index.jsp";
    }

쿼리스트링 : http://localhost:8000/user/login 이렇게 준다면,

이렇게 나온다.

매 번 req.getParameter를 쓸 것인가? -> 다른 방법을 찾아보자.

    @GetMapping("login")
    public String login(@RequestParam("mem_id") String mem_id, @RequestParam("mem_pw") String mem_pw) {
        logger.info("mem_id : " + mem_id + "mem_pw : " + mem_pw);

        return "redirect:/index.jsp";
    }
  • @RequestParam("mem_id") String mem_id

  • @RequestParam("mem_pw") String mem_pw

이렇게 쓰는 것도 가능하지만, 이것도 불편하다...

개선할 수는 없을까? @RequestParam() 를 생략하여

쿼리스트링으로 받아오는 타입만 맞춰주자.

  @GetMapping("login")
    public String login(@RequestParam("mem_id") String mem_id, @RequestParam("mem_pw") String mem_pw) {
        logger.info("mem_id : " + mem_id + "mem_pw : " + mem_pw);

        return "redirect:/index.jsp";
    }
    
 ============================================ ============================================

    @GetMapping("login")
    public String login(String mem_id, String mem_pw) {
        logger.info("mem_id : " + mem_id + "mem_pw : " + mem_pw);

        return "redirect:/index.jsp";
    }
  • 두 개는 다르다.
public String login
(@RequestParam("mem_id", required = false) String mem_id 
@RequestParam("mem_pw", required = false) String mem_pw)
  • required = false : 선택사항
    • 반드시 전달할 (필수매개변수인 경우 true)와 (그렇지 않은 경우 false)를 설정할 수 있다.

url : http://localhost:8000/user/login3 ==> mem_id = null

url : http://localhost:8000/user/login3?mem_id ==> mem_id="" js로 연결되는 부분은 주의해야된다.(빈 문자열이 들어간다)

  • @RequestParam :
    • 필수 입력사항일 떄, 메소드의 파라미터의 자리에 사용할 수 있는 어노테이션이다.
    • @RequestParam을 쓰지 않고도 파라미터로 자동으로 담아준다.

required 테스트 케이스

    @GetMapping("login4")
    public String login4(@RequestParam String mem_id, String mem_pw) {
        logger.info("mem_id : " + mem_id + "mem_pw : " + mem_pw);
        return "redirect:/index.jsp";
    }

Test URL : http://localhost:8000/user/login4

  • 쿼리스트링으로 @RequestParam 디폴트가 true인데. 입력하지 않아서 발생하는 에러이다.

Test URL : http://localhost:8000/user/login4?mem_id=kiwi

  • 이렇게 @RequestParam 디폴트 값으로 들어간 required = true이므로 값을 주면 에러가 해결된다. 두 번째 파라미터인 경우 값을 주지 않으면 null값이 출력된다.

  • @RequestParam : 생략 했을 경우에는 입력하지 않았을 때 null값이 표시된다.

Map으로 해보자.

Test URL : http://localhost:8000/user/login5?mem_id=kiwi&mem_pw=123

    @GetMapping("login5")
    public String login5(@RequestParam Map<String, Object> pmap) {
        logger.info("mem_id : " + pmap.get("mem_id") + "mem_pw : " + pmap.get("mem_pw"));
        return "redirect:/index.jsp";
    }


Map을 이용해서 여러 값을 받아올 수 있다.


profile
아는만큼보인다.

0개의 댓글