Spring Structure

Let's Just Go·2022년 7월 6일
0

Spring

목록 보기
5/26

Spring

MVC Structure


Web Application Structure

  • Web Application Structure

    • Web Application의 일반적 구조

    • Service 계층과 DAO 계층 구조

    • @Service와 @Repository Annotation 활용

    • 순서

      • Controller → Service(연산진행) → DAO → DB

Controller

  • @Controller
    • 요청과 함께 들어오는 데이터의 흐름을 처리할 수 있는 Controller 생성

    • Container에 bean 등록

    • Controller는 Service가 없으면 동작을 할 수 없으므로 @Autowired를 활용해 의존성 주입하고 자동 객체 등록

      package com.spring.basic.controller;
      
      import java.util.List;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.ModelAttribute;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.servlet.mvc.support.RedirectAttributes;
      
      import com.spring.basic.model.ScoreVO;
      import com.spring.basic.service.IScoreService;
      
      @Controller
      // Controller로 bean 등록 
      @RequestMapping("/score")
      // 공통 url 지정 
      public class ScoreController {
      	
      	// Controller는 Service가 무조건 필요하므로 (종속관계)
      	// 컨트롤러와 서비스 계층 사이의 의존성 자동 주입을 위해 변수 선언 
      	@Autowired
      	// autowired를 통해 bean등록한 것을 자동으로 객체 주입
      	private IScoreService service;
      	
      	// 점수 등록 화면을 열어주는 처리를 하는 메서드 
      	@GetMapping("/register")
      	// /score/register 요청이 들어오면 해당 메서드 실행 
      	public String register() {
      		System.out.println("/score/register : GET");
      		return "score/write-form";
      		// register 요청이 들어오면 GET방식으로 score/write-form으로 보내줌
      	}
      	
      	// write-form에서 post방식으로 온 데이터를 처리하는 메서드 
      	@PostMapping("/register")
      	public String register(ScoreVO scores) {
      		// write-form에서의 값의 파라미터 명은 scoreVO의 변수명과 같으므로 커맨드 객체 활용 
      		System.out.println("/score/register : POST");
      		
      		System.out.println(scores.toString());
      		// Service에 scores를 전달해야함
      		// 위에서 생성한 service를 통해 연결
      		service.insertScore(scores);
      		return "score/write-result";
      	}
      	
      	// 점수 전체 처리하는 메서드
      	@GetMapping("/list")
      	public String list(Model model) {
      		// 데이터를 보내야 하기 때문에 Model 객체가 필요 
      		System.out.println("/score/list : GET");
      //		List<ScoreVO> sList = service.listScore();
      		// service에 전체 리스트 값을 가져와라 
      		model.addAttribute("sList", service.listScore());
      		// 모델 객체에 값을 담아줌 
      		// 보낼 경로를 작성하게 되면 Model 객체는 자동으로 이동
      		return "score/list";
      	}
      	
      	// 점수를 삭제하는 요청을 처리하는 메서드
      	@GetMapping("/delete")
      	public String delete(@RequestParam("stuNum") int stuNum, 
      						RedirectAttributes ra) {
      		// delete요청이 들어올 때 stuNum라는 이름의 파라미터 값이 들어오기 때문에 requestParam을 사용
      		// RedirectAttributes 객체를 활용해서 redirect(다시 요청) 진행
      		System.out.println("/score/delete : GET");
      		service.deleteScore(stuNum);
      		ra.addFlashAttribute("message", "학번이 " + stuNum +" 님의 정보가 삭제가 완료되었습니다.");
      		// redirect할 때 표시할 메세지도 객체에 포함시킴 
      		return "redirect:/score/list";
      		// 삭제를 진행한 후 다시 redirect를 통해 list에 다시 요청을 보내도록 함 
      	}
      	
      	// 특정 사람의 점수를 조회하는 메서드
      	@GetMapping("/search")
      	public String search() {
      		System.out.println("/score/search : GET");
      		return "score/search";
      	}
      	
      	// 점수 개별 조회 처리 요청 메서드
      	@GetMapping("/selectOne")
      	public String select(@RequestParam("stuNum") int stuNum,
      						Model model,
      						RedirectAttributes ra) {
      		// 파라미터를 받고 조회가 된다면 조회 결과를 보낼 Model객체, 조회가 되지 않는다면 redirect 객체
      		
      		System.out.println("/score/selectOne : GET");
      		ScoreVO score = service.selectScore(stuNum);
      		// 조회가 된다면 score는 null이 아님
      //		System.out.println(score);
      		
      		if (score == null) {
      			// 객체가 없다면 
      			ra.addFlashAttribute("message", "입력하신 " + stuNum + "의 정보가 없습니다.");
      			return "redirect:/score/search";
      			// 다시 요청 
      		}
      		else {
      			// 객체가 존재한다면
      			model.addAttribute("score", score);
      			return "score/search-result";
      		}
      	}
      }

Service

  • @Service
    • 요청과 함께 들어온 데이터를 바탕으로 연산 및 정제 작업을 진행하며 Controller와 DAO사이에서 데이터가 왔다 갔다 함

    • Service는 Repository가 없으면 동작을 할 수 없으므로 @Autowired를 활용해 의존성 주입하고 자동 객체 등록

    • Controller에서 전달 받은 값을 추가적인 연산 진행하고 Repository에 전달

      package com.spring.basic.service;
      
      import java.util.List;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      import com.spring.basic.model.ScoreVO;
      import com.spring.basic.repository.IScoreDAO;
      
      @Service
      // anotation Service를 추가하게 되면 container에 bean을 등록함
      public class ScoreService implements IScoreService {
      	
      	// service와 dao는 의존성이 있으므로 객체 생성 
      	// Autowired는 container에서 타입에 맞는 객체를 찾아서 자동 주입
      	@Autowired
      	private IScoreDAO dao;
      	
      	
      	@Override
      	public void insertScore(ScoreVO score) {
      		// controller에서 전달된 값을 연산 진행 후 dao에 전달
      		score.calcData();
      		// 총점과 평균을 계산
      		
      		System.out.println(score);
      		// score객체를 dao에게 전달해야함으로 service와 dao는 연관관계가 있음
      		dao.insertScore(score);
      		// dao에 score 객체를 넣어줌
      	}
      
      	@Override
      	public List<ScoreVO> listScore() {
      		
      		return dao.listScore();
      		// controller에 return
      		// Controller에 값을 보내야하고 딱히 데이터를 처리할 필요가 없음 
      	}
      
      	@Override
      	public void deleteScore(int num) {
      		dao.deleteScore(num);
      
      	}
      
      	@Override
      	public ScoreVO selectScore(int num) {
      		
      		return dao.selectScore(num);
      	}
      
      }

Repository

  • @Repository
    • DB와 연결하는 계층이며 Service에서 데이터를 전달받아 DataBase의 CRUD 수행

    • Annotation을 사용하게 되면 Container에 bean 등록 진행

    • Service에서 전달 받은 값을 DB와 연결하여 연산 진행

      package com.spring.basic.repository;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import org.springframework.stereotype.Repository;
      
      import com.spring.basic.model.ScoreVO;
      
      @Repository
      // 자동 bean 등록 annotation (@Repository)
      
      public class ScoreDAO implements IScoreDAO {
      
      	// 학생들의 점수 정보를 저장할 리스트를 생성 (DB 대용)
      	private List<ScoreVO> scoreList = new ArrayList<>();
      	
      	
      	@Override
      	public void insertScore(ScoreVO score) {
      		scoreList.add(score);
      		// db에 넣어주는 작업을 현재에는 list로 작성하고 있으므로 간단하게 끄읏 
      		// service에서 가져온 score를 받아서 값을 넣음
      		
      	}
      
      	@Override
      	public List<ScoreVO> listScore() {
      		
      		return scoreList;
      		// service에게 return
      		// 지금은 DB 연결하지 않아서 간단
      	}
      
      	@Override
      	public void deleteScore(int num) {
      		scoreList.remove(num-1);
      		// 인덱스 값으로 삭제하기 때문에 -1해줌
      	}
      
      	@Override
      	public ScoreVO selectScore(int num) {
      		// 저장되어 있지 않은 정보를 조회할 수 있으므로 조건문 삽입
      		
      		if (num <= scoreList.size()) {
      			return scoreList.get(num-1);
      		} else {
      			// 현재 데이터의 사이즈보다 크다는 것은 잘못된 번호를 입력한 것  
      			return null;
      		}
      	}
      
      }

참고

  • <c:url value='경로' />
    • 만약 context root가 바뀌게 된다면 해당 root를 모두 변경해야 하기 때문에 많이 귀찮을 수 있음

    • jstl을 활용하면 context root를 제외하고 절대 경로로 작성하게 되면 자동으로 context root 작성을 해줌

      • <c:url value=’uri 경로’ />
      • jstl core 패키지 import
    • 나중에 context root가 변경되어도 변경하지 않아도 됨

      <%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%>
      <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
      
      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="UTF-8">
      <title>Insert title here</title>
      </head>
      <body>
      	<h2> 점수 등록 성공 </h2>
      	<p>
      <!-- 		<a href="/basic/score/register">다른 점수 등록하기</a>
       -->	
       		<a href="<c:url value='/score/register' />">다른 점수 등록하기</a>
       		<!-- jstl을 통해 context root를 제외한 경로를 작성해 놓으면 context root를 붙여줌 -->	
       		<a href="<c:url value='/score/list' />">점수 전체 조회하기</a>
      		<a href="">점수 개별 조회하기</a>
      	</p>
      </body>
      </html>
profile
안녕하세요! 공부한 내용을 기록하는 공간입니다.

0개의 댓글