※ 이클립스 대신 STS를 사용하겠다.
STS3은 스프링 / STS4는 스프링 부트용
STS3 설치
1.다운로드
https://github.com/spring-attic/toolsuite-distribution/wiki/Spring-Tool-Suite-3
Spring Tool Suite 3
the distribution build for the Spring Tool Suite and the Groovy/Grails Tool Suite - spring-attic/toolsuite-distribution
github.com
이 링크에서 다운로드 받도록 하겠다.
작성일인 23년8월7일 기준으로 작성자는 이클립스 2020-03버전(4.15.0)을 이용중이며, jdk 환경도 고려하여 알맞은 버전을 설치해주어야한다
이렇게 검색을 하다보면 4.15 버전의 것을 다운로드 받을 것 인데 링크주소를 읽어보면 우리가 잘 구분하여 다운로드 받을 수 있다.
버전이 4.15라면 4.15와 같거나 조금 더 낮은 버전으로 다운로드를 진행해도 된다. 작성자는 4.15로 진행했다.
2. 설치
압축파일이기때문에 특별한 과정 없이 일단 원하는 경로에 압축 파일을 풀어주도록 하자.
우리가 위에서 sts를 압축을 풀어 두었던 경로를 잘 기억해두자.
이곳에 LOMBOK가 설치될 예정이다.
폴더내의 STS.exe를 눌러주면 실행이 잘된다
이와 같이 화면이 오류 없이 뜬다면 성공이다.
이클립스와 근본적으로 차이가 없는 모양을 보여주고 있기때문에 encoding설정이나 dark 테마 등등 우리가 사용하던 셋팅을 그대로 정해주자.
이후의 폰트 설정이 끝나고
서버설정까지도 기존의 apache tomcat 9.0을 사용하겠다.
이렇게 서버설정도 끝나겠다.
server의 web.xml에서 filter와 filter mapping을 찾아 설정하고 포트번호의 설정도 동일하다.
3. 새로운 프로젝트 생성
이번 진행은 spring legacy project로 진행 되겠다.
선택후
이름을 입력 후 MVC 프로젝트로 만든다.
여기도 Yes를 눌러 바로 진행하자.
※여기에서 가장 높은 레벨의 패키지 명을 정할때
.(dot)를 2개 포함하는 주소로 만들어주자. 도메인네임을 만들어감에 있어서 거꾸로 만들어주어 충돌을 막기 위함이다.
이후 finish를 눌러 마무리짓자.
이러한 패키지가 생성이 됐다면 성공이다!
생성이 됐다면 pom.xml을 보자.
우리의 자바 버전은 1.8이었다.
저 부분을 1.8로 수정 후 저장해주자.
xml문서이기때문에 오타를 허용하지 않으므로 다른부분을 고쳐 에러가 발생하지 않도록 하자.
※여기에서도 주로 사용되는 규칙 ![]() groupId부분은 웹사이트의 도메인 명을 역순으로 넣은것 artifactId부분은 프로젝트의 이름을 띄게 만들어진다. |
그외 나머지 성질들은 우리가 읽다보면 알수 있다. snapshot은 임시버전이며, release는 정식 출시버전이다.
스프링을 진행 해줌에 있어서 매우 중요한 개념중 하나인 의존성이다.
우리가 이 프로젝트에서 의존하게 될 라이브러리에 대한 정보를 언급하는 부분이 dependencies이고, 이러한 라이브러리가 많이 존재하기때문에 스프링은 당연하게도 이클립스에 비하여 조금 더 무거운 프로그램이 된다.
반가운 얼굴인 jstl도 이미 dependency에 등록되어있으므로 우리가 더이상 불러오지 않아도 된다.👍
AOP(Aspect Oriented Programming)
핵심 비즈니스 로직 외에 부가적인 기능(예외처리, 트랜젝션처리, 로깅처리 등)을 효율적으로 관리하도록 하여 응집도가 높은 코드를 유지할 수 있도록 함
정보처리기사 필기에서 다뤘더 내용과 동일하다.
모듈의 독립성은 결합도(Coupling)를 약하게, 응집도(Cohesion)를 강하게, 모듈의 크기가 작을 때 독립성이 높아진다.
응집도(Cohesion)는 명령어나 호출문 등의 모듈의 내부 요소들의 서로 관련있는 정도, 즉 모듈이 독립적인 기능으로 구성됐는지 정도를 의미한다 응집도가 높을수록 좋은 모듈이다.
결합도(Coupling)는 모듈 간에 상호 의존하는 정도 또는 두 모듈 사이의 연관 관계를 의미한다. 결합도가 약할수록 독립적인 모듈. 결합도는 약할수록 좋다.
Logger
log4j를 지원하는 핵심 클래스이다.
로그의 출력여부가 레벨에 따라 정해진다.
가장 높은 레벨부터
FATAL - 조기 종료를 유발하는 심각한 오류가 발생하는 상태를 뜻한다
ERROR - 기타 런타임오류 or 예기치 않는 상태
WARN - 경고성메세지. 사용되지 않는 api사용
바람직하지 않거나 예기치 않는 런타임 상황
INFO - 정보제공용 메세지
DEBUG - 디버그 용도
TRACE - 가장 하위 로깅 레벨. 모든 로그에 대한 상세한 정보
이외에도 여러가지 우리가 쓰던것들을 dependency를 통해 불러올 수 있다.
※여러 dependency를 불러오는 과정에 온라인이 아니라 우리가 직접 파일을 넣어주어야하는 경우가 있다.
이와 같이 에러가 발생 한 경우 알맞은 경로에 파일을 넣고
위치에 잘 들어갔따면
이것을 눌러 보자
이제는 인식이 되어 에러 없이 잘 인식이 되는 모습이다.
추가된 내용
<!-- 230807에 추가한 dependency 1번째 -->
<!-- 파일업로드 라이브러리
commons-fileupload 와 commons-io 필요 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- 썸네일 이미지 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<!-- 230807에 추가한 dependency 1번째 끝 -->
<!-- 230807에 추가한 dependency 2번째 -->
<!-- JSON관련: JSON을 Java Object로 변환,Java Object를 JSON형태로 변환 라이브러리
jackson-annotations라이브러리 &
jackson-core라이브러리에 의존 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- 230807에 추가한 dependency 2번째 끝 -->
<!-- 230807에 추가한 dependency 3번째 -->
<!-- tiles라이브러리 : 화면Layout템플릿 -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>2.2.2</version>
</dependency>
<!-- 230807에 추가한 dependency 3번째 끝 -->
<!-- 230807에 추가한 dependency 4번째 -->
<!-- mysql연동 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.24</version>
</dependency>
<!-- JDBC 연동을 위한 라이브러리 -->
<!-- spring-jdbc : 커넥션 풀 설치를 위한 라이브러리 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- commons-dbcp2 : 실제 커넥션 풀을 처리하기 위한 라이브러리 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<!-- 데이터소스 관련 라이브러리 등록 -->
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2</version>
</dependency>
<!-- 230807에 추가한 dependency 4번째 끝 -->
<!-- 230807에 추가한 dependency 5번째 -->
<!-- mybatis관련 라이브러리 등록 -->
<!-- mybatis : mybatis를 위한 라이브러리 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.0</version>
</dependency>
<!-- mybatis-spring : mybatis와 spring를 연결 라이브러리 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.0</version>
</dependency>
<!-- 오라클연동 라이브러리 -->
<dependency>
<groupId>oracle.jdbc</groupId>
<artifactId>OracleDriver</artifactId>
<version>11.2.0</version>
<scope>system</scope>
<!-- 시스템에 설치된 oracle을 사용한다는 의미 -->
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/ojdbc6.jar</systemPath>
</dependency>
<!-- 230807에 추가한 dependency 5번째 끝 -->
이만큼의 내용을 넣었으니 각자 무슨역할을 하는지 다시 한번 잘 읽어보자.
이제 이렇게 만들어진 의존성 들은
이렇게 사용자 경로 아래의 .m2라는 폴더에 repository폴더 내에 모두 만들어 져 있다.
5. web.xml에서 한글인코딩 설정
<!-- 한글인코딩 시작 -->
<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>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 한글인코딩 끝 -->
jsp에서의 페이지 출력때 한글이 깨지지않게 하기 위해 했던 방식과 동일하다.
※ 이러한 설정들은 꼭!!!! 프로젝트 초기에 공통으로 맞추어 두고 시작해야한다.
web.xml과 root-context.xml의 관계
설정할때 있어 web.xml과 root-context.xml의 관계는 이러하다.
웹페이지의 설정인 web.xml은 이미 시작부터 root-context.xml을 먼저 읽고 온다는 부분이 드래그 되어있다.
root-context는 기본적으로 포함되어야 할 것들을 말한다.
Spring에서의 Controller와 view의 연결
1. 연결 위치의 확인
앞의 설정이 끝났으면 우리는 이제 실제로 화면을 띄워보겠다.
일단 자바쪽의 폴더를 열어보자.
이렇게 작성이 되어있는것을 우리가 확인 할 수 있다.
여기에서 우리가 봐야할 것은
파일의 가장 마지막에 작성되어있는 home 이다.
저기에 적혀있는 return "home"이란 것은 home.jsp를 찾아서 지금 자바에서 작성한 내용을 포함하여 return을 하겠다는 뜻이다.
이때 그 home 의 위치는
이곳이다. 잘 기억해두자.
2.parameter의 수신 / attribute의 지정
package com.mycom.app;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Response;
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;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 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.
*/
//요청주소 http://localhost:8081/app/test?id=hongid&age=15
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String home(Locale locale, Model model,
HttpServletRequest request, HttpServletResponse response,
@RequestParam("id") String rpid, @RequestParam("age") int rpage) {
logger.info("Welcome home! The client locale is {}.", locale);
//1. 파라미터 받기
//jsp방식
String id = request.getParameter("id");
int age = Integer.parseInt(request.getParameter("age"));
System.out.println("파라미터id"+id);
System.out.println("파라미터age"+(age-1));
logger.info("직접 받은 파라미터id {}",id);
logger.info("직접 받고 파싱한 파라미터age {}",(age-1));
logger.info("한방에 받은 어노테이션 파라미터id {}",rpid);
logger.info("한방에 받은 어노테이션 파라미터age {}",(rpage-1));
//2. 비즈니스 로직
//3. 모델
//jsp방식
response.setCharacterEncoding("utf-8");
String name = "조중현";
request.setAttribute("name", name);
//spring 방식
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
//4. 뷰지정
return "home";
}
}
배운 내용을 토대로 작성된 HomeController이다. 이것에 대해 하나씩 뜯어보겠다.
1.
@RequestMapping(value = "/test", method = RequestMethod.GET)
이 주소 test는 server의 기본 contextpath의 뒤에 붙을 주소를 의미한다.
path인 /app 뒤에 이 주소를 사용하면 우리가 지금 불러오는 페이지를 view로 사용하겠다는 뜻이다.
따라서
http://localhost:8081/app/test 이 주소가 이제 home.jsp의 내용물을 view로 보여주는 페이지가 되겠다.
2.
public String home(Locale locale, Model model,
HttpServletRequest request, HttpServletResponse response,
@RequestParam("id") String rpid, @RequestParam("age") int rpage) {
구분하여 살펴보자.
Locale locale, Model model은 우리가 jsp에서 CommandHandler를 implements 했을때 나오던 것과 동일하게 자동으로 작성되며,
파라미터자리에 우리가 HttpServletRequest request, HttpServletResponse response 와
@RequestParam("id") String rpid, @RequestParam("age") int rpage 를 추가로 작성해주었다.
HttpServletRequest request, HttpServletResponse response 이것은 우리가 이전에 사용하던것과 용도가 동일하지만 parameter를 수신했을때 무조건 string이 되어야한다는 단점이 있었는데
@RequestParam("id") String rpid, @RequestParam("age") int rpage으로 수신할 경우엔 이제 특별한 형변환 없이 annotation을 곁들인 방식으로 한번에 수신이 가능하다. 수신 된 것은 어떻게 수신됐는지 아래의 logger.info를 사용하는 방식으로 알아보자.
3.
String id = request.getParameter("id");
int age = Integer.parseInt(request.getParameter("age"));
System.out.println("파라미터id"+id);
System.out.println("파라미터age"+(age-1));
logger.info("직접 받은 파라미터id {}",id);
logger.info("직접 받고 파싱한 파라미터age {}",(age-1));
logger.info("한방에 받은 어노테이션 파라미터id {}",rpid);
logger.info("한방에 받은 어노테이션 파라미터age {}",(rpage-1));
위의 코드 중 알아 볼 수 있는부분인 request.getParameter 와 Syso는 생략하고 말하겠다.
logger.info는 2개의 파라미터를 받는 메소드이다.
앞에서 작성한 syso와 동일한 형태를 가지나 첫번째 parameter의 String 내용에 {}이 있다면, 그자리에 뒤에 담긴 변수를 출력해준다. 이전에 사용하던 bind(?)를 이용해 set해주던것과 유사한 구조이다.
그리고 2번에서 받았던 rpid, rpage를 출력했을때
이와같이 console 창에서 바로 확인 할 수 있다.
우리가 지금까지 어떤 java 파일에서 어떤 변수인지 선언했던 방식에 비하면 한번에 모든 정보를 알려주기때문에 아주 편안한 방식이라고 생각이 된다.
스프링은 이와같이 다양한 방식으로 Parameter를 수신하여 사용 할 수 있다!
간략하게 지나갈 내용
logger.info("Welcome home! The client locale is {}.", locale);
locale은 지구상의 현재 위치를 나타내는 것으로 보인다.
이렇게 console에서 반응 하는것으로 확인이 된다.
//jsp방식
response.setCharacterEncoding("utf-8");
String name = "조중현";
request.setAttribute("name", name);
//spring 방식
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
이 내용 또한 우리가 이전의 jsp에서 진행했던 방식과 동일하머 이것을 jsp페이지에서 EL을 통해 불러왔을때 문제없이 잘 불러와지는 것을 확인 할 수 있다.
2-1. 다양한 방식의 parameter 수신 및 jsp페이지와 실제 연동
<form id="frm1" action="form01Rs" method="post">
*이름:
<input type="text" name="userName" id="userName"
size="10" autofocus="autofocus" placeholder="이름입력하세요"/>
<br/>
*관심사(취미): <%-- hobby=coffee&hobby=movie&hobby=darama --%>
<input type="checkbox" name="hobby" id="h0" value="coffee" checked="checked"/><label for="h0">커피내리기</label>
<input type="checkbox" name="hobby" id="h1" value="movie"/><label for="h1">영화감상</label>
<input type="checkbox" name="hobby" id="h2" value="darama"/><label for="h2">드라마보기</label>
<input type="checkbox" name="hobby" id="h3" value="toon"/><label for="h3">웹툰보기</label>
<input type="checkbox" name="hobby" id="h4" value="music"/><label for="h4">음악감상</label>
<input type="checkbox" name="hobby" id="h5" value="book"/><label for="h5">독서</label>
<br/>
<input type="submit" value="전송" />
<input type="reset" value="취소" />
</form>
이러한 식으로 두가지의 정보를 받아 전달 해보겠다.
하나는 text type이며, name은 userName이다.
다른 하나는 checkbox이기 때문에 String 타입의 정보이나 배열이므로 String[]이다.
그리고 주소는 우리가 @RequestMapping 을 통해 전달하는 주소로 맞춰 주겠다.
form 주소와 mapping 주소가 일치한다면 입력한 정보가 제대로 도착 할 것이다.
그리고 @RequestMapping을 이용하여 다시한번 parameter를 수신하겠다.
대신 이번엔 추가적으로 언급할 것이 있다.
※1. 주소만 언급할때는 @RequestMapping 뒤에 주소만 String으로 입력하면 된다.
예시)
※2. RequestParam을 이용할때 input의 name과 RequestParam의 변수 이름이 같다면 뒤에 소괄호를 이용해 name을 다시 언급할 필요가 없다.
name이 다른경우)
name이 같은 경우)
▶form측의 name을 먼저 확인하자
▶name이 일치하는 변수를 RequestParam 뒤에서 선언하는 방식
이러한 방식의 차이를 보이니 가능하면 우리는 name을 맞추어 사용하는것이 좋을 것으로 보인다.
※2. 객체를 받아서 전부 출력하고 싶을때 logger.info에서 사용하는 방식
hobby라는 객체는 String 배열인데 이것을 일단 여러개를 선택하여 전달했을때
logger.info("취미~ {}",hobby);
이것을 이용하여 출력하면
배열임에도 1개씩 출력되는 모습이 보인다.
이것을 원하는대로 배열로 나타내고자하면
logger.info("취미~ {}",(Object)hobby);
logger.info("취미~ {}",hobby, hobby);
logger.info("취미~ {},{},{},{},{},{},{}",hobby);
이와 같이 여러가지 방식으로 나타낼 수 있다.
위의 2가지는
이와 같이 배열에 맞춰 출력되나
아래의 것은
비어있는 bind의 개수가 맞지 않는다면 빈 bind가 출력되거나 필요한 정보만큼이 출력되지 않기때문에 좋은 방식으로는 보이지 않는다. 변수의 개수가 확실하지 않다면 이 방식은 지양해야겠다.
'Web > Spring국비지원 수업 정리' 카테고리의 다른 글
<Spring 국비지원 수업> lombok (0) | 2023.08.17 |
---|---|
<Spring 국비지원 수업> mybatis를 사용한 mvc 패턴 (0) | 2023.08.11 |
<Spring 국비지원 수업> mybatis (1) | 2023.08.10 |
<Spring 국비지원 수업> parameter수신방식2, model과 view의 지정 (0) | 2023.08.08 |