2024. 7. 9. 12:40ㆍWebBack/Spring
Spring 주제 | URL |
원격 프로그램은 어떻게 실행될까? | https://ycraah.tistory.com/37 |
AWS에 배포하기 | https://ycraah.tistory.com/38 |
HTTP 요청을 받아 화면에 출력하기 | https://ycraah.tistory.com/39 |
resourse폴더 이용하기 | https://ycraah.tistory.com/40 |
URL에서 포트 번호 생략하는 법 | https://ycraah.tistory.com/42 |
1. 관심사의 분리
이번에는 OOP 5대 설계 원칙중에 SRP(단일책임원칙)에 따라 기존의 코드는 크게 수정할 예정이다. SRP는 쉽게 관리하고 유지보수하는 코드를 구현하기 위한 개발 지침이다. 그 지침은 다음과 같다. "한 클래스는 한 기능만 책임진다"(Real-World Software Development 실전 자바 소프트웨어 개발, p.27)
아래의 코드는 크게 3부분으로 나눌 수 있다. 이를 각각 관심사라고 부른다. 한 클래스에 여러 기능을 책임지고 있기 때문에 이 코드는 좋은 코드가 아니다. 따라서 각 기능마다 클래스를 분리하는 것이 필요하다.
1. 입력
2. 작업
3. 출력
@Controller
public class YoilTeller {
@RequestMapping("/getYoil")
public void main(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1. 입력
String year = request.getParameter("year");
String month = request.getParameter("month");
String day = request.getParameter("day");
int yyyy = Integer.parseInt(year);
int mm = Integer.parseInt(month);
int dd = Integer.parseInt(day);
//2.작업
Calendar cal = Calendar.getInstance();
cal.set(yyyy, mm - 1, dd);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
char yoil = " 일월화수목금토".charAt(dayOfWeek);
//3.출력
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<body>");
out.println(year + "년 " + month + "월 " + day + "일은 ");
out.println(yoil+ "요일입니다.");
out.println("</body>");
out.println("</head>");
out.println("</html>");
}
}
2. MVC 패턴
그런데 대부분의 코드를 살펴보면 입력 -> 처리 -> 출력 순으로 진행된다. 게다가 입력 부분은 대부분 코드가 비슷하다. 그래서 입력 부분을 따로 분리하면 중복 문제를 해결할 수 있다.
마찬가지로 출력도 분리를 해보자. 그런데 입력과 출력이 다른 클래스로 분리되면서 기존의 값을 불러들일 수 없게 된다. 그래서 중간에 값을 전달할 Model 객체를 만들어야 한다. 이렇게 작업을 하는 영역(Controller) / 출력하는 영역(View) / 데이터를 주고 받는 영역 (Model)으로 나누는 것을 MVC 패턴이라고 한다.
3. 입력의 분리
@Controller
public class YoilTeller {
@RequestMapping("/getYoil")
public void main(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1. 입력
String year = request.getParameter("year");
String month = request.getParameter("month");
String day = request.getParameter("day");
int yyyy = Integer.parseInt(year);
int mm = Integer.parseInt(month);
int dd = Integer.parseInt(day);
기존의 코드에서는 request 객체를 매개변수로 삼아서 작업을 했다. URL에 입력된 내용을 request 객체에 저장해서 이를 다시 숫자로 변환하는 번거로운 작업을 했다. 하지만, 매개변수를 직접 받는 것도 가능하다.
@Controller
public class YoilTellerMVC {
@RequestMapping("/getYoil")
public void main(String year, String month, String day, HttpServletResponse response) throws IOException {
//1. 입력
int yyyy = Integer.parseInt(year);
int mm = Integer.parseInt(month);
int dd = Integer.parseInt(day);
그리고 매개변수를 숫자로 받는 것도 가능하다. 그러면 코드가 아래처럼 확 줄일 수 있다.
@Controller
public class YoilTellerMVC {
@RequestMapping("/getYoilMVC")
public void main(int year, int month, int day, HttpServletResponse response) throws IOException {
그리고 이제 결과를 model에 저장할 것이기 때문에 HttpServletResponse도 바꾸어준다.
@Controller
public class YoilTellerMVC {
@RequestMapping("/getYoilMVC")
public void main(int year, int month, int day, Model model) throws IOException {
매개변수에 맞추어 작업에서 사용된 변수 이름도 바꾸어준다.
//2.작업
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day);
3. 출력의 분리
출력 파일은 다음 위치로 이동시킬수 있다. [src] -> [main] -> [webapp] -> [WEB-INF] -> [views]
여기에 출력할 내용을 담은 yoil.jsp와 오류가 날 때 출력할 화면인 yoilError.jsp를 저장해놓자. yoil에는 다음과 같이 저장한다. ${year } 이 부분은 나중에 모델 객체에서 값을 받아와서 넣는다.
<html>
<head>
<title>Home</title>
</head>
<body>
<P>${year }년 ${month }월 ${day }일은 ${yoil }입니다. </P>
</body>
</html>
*오류가 발생하면 해당 코드를 잘라내기한 뒤에 다시 붙여넣으면 없어진다.
*인코딩 문제가 있으니 각 파일 상단에 <%@ page contentType="text/html;charset=utf-8" %>를 상단에 넣어주어야 한다.
아래는 yoilEroor.jsp에 들어갈 내용이다.
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
잘못된 요청입니다. 년, 월, 일을 모두 올바르게 입력해주세요.
</h1>
</body>
</html>
그리고 작업 부분에 'return "yoil"을 추가한다. 이 return을 통해 보여줄 view를 선택할 수 있다. "yoil"을 선택하면 위에서 적은 yoil.jsp을 통해 출력하게 된다.
//2.작업
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
char yoil = " 일월화수목금토".charAt(dayOfWeek);
return "yoil";
return이 문자열로 바뀌면서 반환 형식도 문자열로 바꾸었다.
public String main(int year, int month, int day, HttpServletResponse response) throws IOException
4. 유효성 검사
만약 클라이언트측에서 URL을 올바른 형식으로 보내지 않을 경우를 대비하여 유효성 검사를 진행해야한다. 오류가 발생하면 yoilError.jsp가 출력된다.
//1.유효성 검사
if(!isValid(year, month, day))
return "yoilError";
private boolean isValid(int year, int month, int day) {
return true;
}
5. 작업 분리
기존의 요일도 클래스를 따로 분리시켰다.
private char getYoil(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
return " 일월화수목금토".charAt(dayOfWeek);
}
6. 결과를 Model에 저장
그리고 이렇게 얻은 값을 Model에 저장시킨다. 그러면 jsp 파일이 Model의 값을 읽어서 출력할 수 있게 된다.
*참고로 return "yoil"도 생략할 수 있다. 그리고 메인의 반환 타입도 없애고 void로 변경해도 오류가 발생하지 않는다. 이렇게 하면 view의 이름은 맵핑에 적은 URL에 따라 결정된다. 여기서는 getYoilMVC.jsp로 결과가 전달된다.
//3. 계산한 결과를 model에 저장
model.addAttribute("year", year);
model.addAttribute("month", month);
model.addAttribute("day", day);
model.addAttribute("yoil", yoil);
return "yoil";
7. 결과
올바르게 작동된다.
반면에, 코드는 훨씬 간결해졌다.
@Controller
public class YoilTellerMVC {
@RequestMapping("/getYoilMVC")
public String main(int year, int month, int day, Model model) throws IOException {
//1.유효성 검사
if(!isValid(year, month, day))
return "yoilError";
//2.요일 계산
char yoil = getYoil(year, month, day);
//3. 계산한 결과를 model에 저장
model.addAttribute("year", year);
model.addAttribute("month", month);
model.addAttribute("day", day);
model.addAttribute("yoil", yoil);
return "yoil";
}
'WebBack > Spring' 카테고리의 다른 글
[Spring] 자바 버전을 바꿔보자 (0) | 2024.07.09 |
---|---|
[Spring] 어떻게 view로 전달이 될까? (0) | 2024.07.09 |
[Spring] URL에서 포트 번호를 생략하는 방법 (0) | 2024.07.08 |
[Spring] Httpservlet 메서드 (0) | 2024.07.08 |
[Spring] resource 폴더 이용하기 (0) | 2024.07.08 |