백엔드/Spring

스프링 일기 6 - Spring Legacy Project 만들어보기

들쮜 2023. 6. 13. 17:04

Spring 컨테이너 조차도 자동으로 만들어주는 Spring 정말 편리합니다.

 

사실 이건 Spring의 편리성이라기 보다는 STS가 만들어준거긴 하고, 설정 하는게 여간 복잡한게 아니라는 점이 좀 불편하긴 합니다.

 

설정이 오래 걸리기는 하지만, 설정만 해두면 간단하게 프로젝트를 만들 수 있다! 가 장점인 것 같은데

 

Django는 설정도 오래 걸리지 않았었다구요...

 

Spring보다 Django가 더 좋아보이지만, Spring은 Enterprise급의 프로젝트에 적합하다고 하니 알아두는게 좋을 것 같습니다.


package com.duljji.springweb;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

Spring Legacy Project에서 기본으로 제공해주는 HelloController입니다.

 

Controller를 이용하여 Bean으로 등록을 해줍니다. 컨트롤러는 servlet-context 에서 component-scan가 되고 있습니다.

 

RequestMapping의 value를 통하여 url을 매핑해주고, viewResolver가 home을 보여주는 것 까지는 알겠는데 model은 무엇일까요?

 

model은 django의 context와 같은 역할을 한다고 보면 됩니다. django는 render함수를 이용해서 파라미터로 context값을 넘겨주었지만, 

 

Spring은 model객체를 이용하여 view와 controller 사이의 데이터를 주고 받습니다.

 

필요없는 부분들을 일단 지우고 진행을 해보도록 하겠습니다.

 

package com.duljji.springweb;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Model model) {
		
		String msg = "컨트롤러에서 보낸 메세지";
		model.addAttribute("msg", msg);
		
		
		return "home";
	}
	
}

필요한 부분만 남겨두고 home.jsp에 데이터를 쏴보도록 하겠습니다. jsp에서 ${msg}를 이용하면 controller에서 보낸 메세지, model 객체에 담아뒀던 그 변수 값을 사용할 수가 있게 됩니다.

 

그리고 실행을 시킨 뒤 url에 접근을 해보면?

 네... 글자가 깨지고 난리가 났습니다.

 

이 글자가 깨지는 것을 방지하기 위해 web.xml에 filter값을 주어 encoding을 해줄 수가 있습니다.

 

filter 또한 Spring에서 가지고 있습니다.

 

<filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

이렇게 web.xml에 filter를 설정해주고 CharacterEncodingFilter 클래스를 이용해서 UTF-8로 encoding을 해줍니다.

 

그리고 모든 url에 적용을 해줍니다. 그럼 이제 됐을까요?

네... 매우 번거롭습니다. Controller에서 전한 메세지는 잘 전달이 된 것 같지만, jsp에서 기본으로 입력한 한글이 깨집니다.

 

이걸 해결하기 위해선 jsp에 페이지 인코딩을 따로 해주어야 합니다.

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

<html>
<head>
    <meta charset="UTF-8">

	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P> 메세지 : ${msg } </P>
</body>
</html>

meta에 charset으로 utf-8 인코딩을 해주면 될 것이라고 생각해서 넣었지만, page 인코딩을 하는 방법이 따로 있었습니다.

 

윗줄에 <%@ %> 을 이용하여 추가로 pageEncoding을 해줘야 값이 제대로 나옵니다.

이제 제대로 된 값이 나오는 걸 확인할 수 있습니다.

 

아주 좋습니다. 내친김에 데이터를 받았으니 데이터를 전송해주는 것도 해보도록 하겠습니다.

 

form태그를 만들어 보고, 자신의 url에게 데이터를 전달해 주도록 합니다.

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<html>
<head>
<meta charset="UTF-8">

<title>Home</title>
</head>
<body>
	<h1>Hello world!</h1>

	<P>메세지 : ${msg }</P>

	<form action="/">
		<label for="id">아이디 : </label> <input id="id" name="id" type="text" />
		<input type="submit">
	</form>
</body>
</html>

이제 자신의 url에 데이터를 전달해주는 태그가 만들어졌습니다. name은 id이니 이것을 한번 컨트롤러에서 받아보도록 합시다.

package com.duljji.springweb;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Model model, String id) {
		
		String msg = "컨트롤러에서 보낸 메세지";
		model.addAttribute("msg", msg);
		model.addAttribute("id", id);
		
		return "home";
	}
	
}

String id 값을 받고, 그 값을 다시 model에 담아서 id값으로 출력하게끔 만들어보겠습니다.

 

 

이제 데이터를 넘겨주는 것도 가능하게 되었습니다!!

 

하지만, 이렇게 ID만 보내는 것은 일반적이지 않습니다. 아이디와 비밀번호 그리고 나이를 한 번 보내보도록 하겠습니다.

 

Django에서는 get함수를 이용해서 하나하나 인자를 받았던 것이 기억이 납니다. 

 

하지만 자바는 객체지향 언어입니다. 클래스를 만들어두면 해당 클래스의 변수들을 한번에 받아올 수가 있습니다.

 

일단 객체를 하나 만들어주도록 합시다.

 

dto 패키지를 하나 만들어 Member 클래스를 하나 선언해주도록 합시다.

package com.duljji.springweb.dto;

public class Member {

	String id;
	String password;
	int age;
	public Member(String id, String password, int age) {
		super();
		this.id = id;
		this.password = password;
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}

코드를 만들었으니 이제 사용해보겠습니다.

 

html태그에서 name으로 지정해준 이름과 같은 필드에 자동으로 데이터가 들어가게 됩니다.

package com.duljji.springweb;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.duljji.springweb.dto.Member;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.POST)
	public String home(Model model, Member member) {
		String id = member.getId();
		String password = member.getPassword();
		int age = member.getAge();
		
		model.addAttribute("id", id);
		model.addAttribute("password", password);
		model.addAttribute("age", age);
		model.addAttribute("member", member);
		
		
		return "home";
	}
	
}

각 값들이 잘 들어갔는지 테스트를 해보도록 하겠습니다.

package com.duljji.springweb.dto;

import org.springframework.stereotype.Component;

@Component
public class Member {

	String id;
	String password;
	int age;
	public Member() {};
	public Member(String id, String password, int age) {
		super();
		this.id = id;
		this.password = password;
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String toString() {
		return this.id + " " + this.password + " " + this.age;
	}
	
}

DTO는 이런식으로 만들어주었습니다. Component로 DTO도 빈으로 관리할 수 있도록 해주었습니다.

 

값이 잘 들어가는 것을 알 수 있습니다.

 

객체를 model에 넣어주게 되면 toString이 호출된다는 것도 확인할 수 있었습니다.

 

이제 페이지를 만들어 데이터를 주고받고 DTO를 통해서 클래스로 여러 변수들을 한번에 받는 방법도 알았습니다.

 

ReqeustMapping을 이용하여 value값으로 url을 지정해주고, method도 RequestMethod 값을 이용하여 지정해줄 수 있었습니다.