학습하며 정리한 내용을 올리는 것이니, 참고용으로만 봐 주시길 바랍니다.
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌

MVC를 이용한 웹 서비스

  1. MVC의 기본 구조: M1 구조에 비해 유지보수 및 기능개선에 이점

    브라우저 <-> Controller - Service - DAO <- (Model) -> DB
                 |
                View
    .
    Controller: 이것들을 Control(기능, 뷰 등을 Control)
    Service: 기능
    View: 사용자에게 보여주는 부분
    Dao: DB와 연동 
  2. 스프링 MVC 프레임워크 구조

               HandlerMapping   HandlerAdapter <-> Controller
                     |           / 
    브라우저 <-> DispatcherServlet <
                     |           \
                    View         ViewResolver

    2.1. 클라이언트가 브라우저를 통해 요청을 보내면 DispatcherServlet이 받는다.
    2.2. DispatcherServlet은 이를 HandlerMapping에게 보내 가장 적합한 Controller를 찾아준다.
    2.3. DispatcherServlet은 HandlerAdapter에게 요청을 보내고 HandlerAdapter는 HandlerMapping이 찾아준 Controller 객체 아래에 있는 메소드들 중 가장 적합한 메소드가 무엇인지 찾아준다. 그 후, 처리된 결과를 Model(View 포함)이라는 데이터를 가지고와서 DispatcherServlet에게 건네준다.
    2.4. 결과(?Model?, View)를 가지고 DispatcherServlet은 ViewResolver에게 보내 View에 해당하는 가장 적합한 JSP 문서를 찾아달라고 요청하여, ViewResolver는 View를 선택해준다.
    2.5. 찾아진 JSP가 있는 View에게 가서 응답(JSP)을 클라이언트에게 보내 주도록 한다.

  3. DispatcherServlet 설정하기

    // WEB-INF/web.xml
    //
    <servlet>
     <servlet-name>appServlet</servlet-name> // 서블릿 별칭
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> // 서블릿명(패키지 이름을 포함한 전체 서블릿 명)
     <init-param> // 초기 파라미터
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> // 스프링 설정파일 (DispatcherServlet이 등록될 때 스프링 설정파일까지 설정해 주도록 함)
     </init-param>
     <load-on-startup>1</load-on-startup>
    </servlet>
    //
    <servlet-mapping>
     <servlet-name>appServlet</servlet-name> // 위에서 별칭으로 지정한 appServlet이
     <url-pattern>/</url-pattern> // root(/)로 들어오는 모든 요청을 처리하도록
    </servlet-mapping>
    • DispatcherServlet 설정 시 위의 초기 파라미터(init-param)에서 지정한 파일을 이용해 스프링 컨테이너를 생성한다. 초기 파라미터를 지정하지 않은 경우 서블릿별칭(appServlet-context.xml)(이 파일이 존재해야함.)을 이용해 스프링 컨테이너를 생성한다.
    • 이를 통해 HandlerMapping, HandlerAdapter, ViewResolver가 생성된다.
    1. Controller 객체
      1. Controller 생성 방법
    // servlet-context.xml
    //
    <annotation-driven /> // 스프링 컨테이너 사용을 위한 부가적인 클래스들이 빈 객체로 스프링 설정파일에 등록됨.
    // Controller 객체로 사용할 클래스 정의
    //
    @Controller
    public class HomeController {
      ...
    }

    4.2. @RequestMapping
    :사용자로부터 들어오는 요청을 Controller가 메소드로 맵핑

    http://localhost:8090/ch08/success (ch08: project path?name?)
    //
    @RequestMapping("/success")
    public String success(Model model) {
     return "success";
    }

    4.3. Model 타입의 파라미터
    : Controller는 Model 객체에 데이터를 담아 DispatcherServlet에 전달

    @RequestMapping("/success")
    public String success(Model model) {
     model.setAttribute('tempData', "model has data");
    //
     return "success";
    }

    4.3. view 객체
    : 스프링 설정파일에 ViewResolver를 생성

    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <beans:property name="prefix" value="/WEB-INF/views/" />
     <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    @RequestMapping("/success")
    public String success(Model model) {
     return "success";
    }

    : return값의 success 앞뒤로 ViewResolver의 prefix, suffix를 붙여주어 /WEB-INF/views/success.jsp 라는 View를 만들어준다.

스프링 MVC 웹 서비스 파일의 구성

  1. web.xml

    • DispatcherServlet을 등록한다.
    • 사용자의 모든 요청을 받기 위해 서블릿 맵핑 경로를 /로 설정한다.
  2. servlet-context.xml

    • DispatcherServlet을 서블릿으로 등록할 때 contextConfigLocation이라는 초기화 파라미터를 servlet-context.xml로 지정하고 있었다.
    • 이는 스프링 설정파일이다.
    • 클래스로부터 객체(bean)을 생성하고 조립하는 역할을 한다.
    • 웹 구동을 위한 resource(jsp, html, css) 등을 맵핑해 준다.
    • InternalResourceViewResolver의 prefix, suffix를 정의하여 View로써 response를 응답하도록 해 준다.

Service Annotation

: 스프링 설정파일(servlet-context.xml)에 Bean 객체를 생성하지 않아도, 서비스 객체마다 @Service Annotation을 붙여주면 자동으로 스프링 컨테이너에 담겨지고, Controller에서 @Autowired만 붙여주면 자동으로 서비스 객체를 사용할 수 있음.
: @Component, Repository
: Dao 또한 동일하게 사용가능
: @Repository("memService"), @Repository(name="memService") 와 같이 key-value 형식으로 특정 이름을 지정할 수 있으나 권장되진 않음.

HttpServletRequest 대신 RequestParam 사용하기

@RequestMapping(value="/memLogin", method=RequestMethod.POST)
// public String memLogin(Model model, HttpServletRequest request) {
public String memLogin(Model model, @RequestParam("memId") String memId, @RequestParam("memPw") String memPw) {    
//    String memId = request.getParameter("memId");
//    String memPw = request.getParameter("memPw");
//    
    Member member = service.memberSearch(memId, memPw);
<form action="/lec17/memLogin" method="post">
    ID : <input type="text" name="memId" ><br>
    PW : <input type="password" name="memPw" ><br>
    <input type="submit" value="Login" >
</form>
  • @RequestParam(value="memPW", required=false, defaultValue="1234") 와 같이 필수로 넘겨주어야 하는지 여부, default 값 을 설정할 수 있다. 잘 사용되지는 않는다.

커맨드 객체를 이용한 HTTP 정보 얻어오기

// public String memJoin(Model model, HttpServletRequest request) {
public String memJoin(Member member) {
//
//  String memId = request.getParameter("memId");
    ...
//    
//    service.memberRegister(memId, ...);
    service.memberRegister(member.getMemId(), ...);

//    model.addAttribute("memId", memId);
      ...
//
    return "memJoinOk";
    <h1> memJoinOk </h1>
//  ID : ${memId}<br />
    ID : ${member.memId}<br />
    ...

MemberAttribute 사용하기

  1. 기존의 커맨드 객체를 이용하는 방식에서 커맨드 개체의 변수명을 사용하는 것이 아니라 닉네임을 사용할 수 있도록 한다.
    public String memJoin(Member member)
    -> ${member.memId}

    public String memJoin(@ModelAttribute("mem") Member member)
    -> ${mem.memId}

  2. 함수 위에 @ModelAttribute("serverTime")을 지정하면, 다른 함수가 호출되어도 항상 @ModelAttribute를 지정한 함수도 같이 호출된다.

    @ModelAttribute("serverTime")
    public String getServerTime(Locale locale) {
     ...
    }
    //   
    @RequestMapping(value="/memJoin", method=RequestMethod.POST) {
     ...
    }

    Model & ModelAndView

    : Model을 뷰에 데이터만을 전달하기 위한 객체이고,
    ModelAndView는 데이터와 뷰ㅜ의 이름을 함께 전달하는 객체이다.

    ////////// Model
    public String memModify(Model model, Member member) {
     ...
     model.addAttribute("memBef", value);
     return "memModifyOk";
    }
    //
    ///////// ModelAndView
    public ModelAndView memModify(Member member) {
     ...
     ModelAndView mav = new ModelAndView();
     mav.addObject("memBef", value);
     mav.setViewName("memModifyOk");
    //    
     return mav;
    }

+ Recent posts