Spring MVC Project
- Spring의 Web Project
- Legacy Project 에서 선택해서 생성 - 전자정부 프레임워크나 기업이 프레임워크에서 선택해서 만드는 프로젝트의 기본 모양으로 전자정부 프레임워크에서는 여기에 데이터베이스 연동하는 코드가 추가되어 있다.
- spring mvc project 나 android, iOS 프로젝트에서는 기본 패키지이름을 3level 이상으로 만들도록 강제합니다
- 회사도메인을 역순으로 기재하고 프로젝트이름이나 기술이름을 추가합니다.
- 회사도메인이 없을 때는 이메일 주소를 이용하는 것을 권장합니다.
ex)
com.gmail.hiwony7933.springmvc
kr.co.norelove.pringmvc
패키지 이름을 만들면 패키지의 3번째 부분이 도메인 이름이 됩니다.
1.디렉토리 구조
1) java Resources
src/main/java : 컴파일 되어야 하는 java 파일이 위치해야 하는 디렉토리
- 패키지가 생성되어 있고 그 안에 HomController가 생성되어 있다.
- 패키지 안에 클래스를 만들때
@Controller
,@Service
,@Repository
,@Component
를 붙이면 bean이 자동 생성되도록 설정되어 있다.
src/main/resources : 컴파일 할 필요가 없는 파이들이 위치하는 디렉토리
- 이 디렉토리와 java 디렉토리는 나중에 합쳐진다.
- 이 디렉토리의 내용들은 컴파일 하지 않습니다.
- 이 디렉토리에 만든 파일들은 java 디렉토리에 만들어도 되지만 java 디렉토리에 만드는 .java 파일은 이 디렉토리에 만들면 안된다.
- 주로 여기에는 설정 파일들이 위치 합니다.
src/test/java 와 resources : 테스트용 자바 파일과 설정파일을 저장하는 디렉토리
- 배포할 때 없어지고, 소스 차원에서만 존재합니다.
src/main/webapp : html, css, js, jsp 등 뷰와 관련된 파일들이 위치하는 디렉토리
- 이 디렉토리가 배포될 때는 WebContent 와 같은 역할
2.생성된 파일
1) web.xml (제일먼저 봐야한다)
<!-- 웹 애플리케이션이 시작되면 WEB-INF 디렉토리의
applicatonContext.xml 파일의 내용을 읽어서 수행한다는 설정 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- applicationContext.xml 파일의 경로를 변경하는 설정 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- /는 .jsp를 제외한 모든 요청
.jsp를 제외한 모든 요청을 param-value에 설정된 파일에서 만드는
Controller가 처리하도록 하는 설정
FrontController의 역할을 수행하는 설정 파일의 경로를 설정-->
<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>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2) root-context.xml
- 애플리케이션 내의 모든 곳에서 사용할 수 있는 bean을 생성 (만들어놓고 공유하는것)
- 대표적인 bean 은 데이터베이스 연동하는 bean을 이 파일에서 생성
3) servlet-context.xml
<!-- spring mvc 프로젝트에서 사용해야 하는 여러 설정을 한번에 해주는 태그 (절대삭제X) -->
<annotation-driven />
<!-- location에 파일에 위치시키면 자동으로 캐싱이 되도록 해주는 태그 -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Controller가 리턴한 뷰 이름을 가지고 prefix를 앞에 붙이고
suffix를 뒤에 추가해서 실제 출력할 뷰 파일을 선택하도록 해주는 설정 -->
<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>
<!-- 어노테이션이 붙은 클래스의 bean을 자동으로 생성해주는 패키지 설정 -->
<context:component-scan base-package="com.gmail.hiwony7933" />
4) homeController.java
- 기본적으로 제공되는 Controller
package com.gmail.hiwony7933;
//Controller 클래스를 만들어주고 Bean을 자동생성해주는 어노테이션
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
// / 요청이 GET 방식으로 오면 처리하는 메소드 설정
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
//model에 attribute를 저장하면 request 객체에 저장됩니다.
//문자열을 리턴하면 이 문자열이 view 이름입니다.
// /(기본 요청)요청이 오면 serverTime이라는 attribute를 request에 저장해서
// home -> WEB-INF/views/home.jsp 로 포워딩합니다.
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";
}
}
3. 실행
- 프로젝트를 선택하고 [Run As] - [Run on Server]를 선택
- 처음 실행하는 경우에는 WAS를 선택해야 합니다.
기본틀을 주고, 여러명이 만들수 있도록 구조를 만들어준다.
전자정부, 애니프레임 은 DB 연동까지도 되어있다.
4.pom.xml
- Maven Project의 설정파일
라이브러리 의존성이나 build 옵션을 설정하는 파일
properties : 자주 사용하는 버전을 이름으로 저장해놓은 설정
- repositories : 중앙 저장소 이외의 곳에서 다운로드 받을 수 있도록 해주는 설정
dependencies : 다운로드 받아서 프로젝트에서 사용할 라이브러리를 설정
java 나 spring 버전을 properies 태그에서 설정하고 외부 라이브러리를 사용해야 하는 경우가 생기면 repositories 나 dependencies 태그에 설정
5.요청을 만들고 Controller를 이용해서 처리해서 결과를 보여주는 페이지 작성
1) home.jsp 파일을 지우고 새로 생성
- 한글도 깨지고 하니까 새로 만들어
<a href="display">jsp 출력 </a><br/>
2) homeController.java 클래스에 display 요청을 처리하는 메소드 추가
// 1. display 라는 요청이 왔을 때 처리하는 메소드
@RequestMapping(value="/display", method=RequestMethod.GET)
public String display(Model model) {
// 2. 처리 할내용
String msg = "spring MVC";
// 3. 데이터 저장 - request.setAttrubute 와 동일
model.addAttribute("msg", msg);
// 4. 출력할 veiw 이름설정
return "display";
}
3) WEB-INF/view 디렉토리에 display.jsp 를 작성하고 메소드 추가
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
데이터 : ${msg}
</body>
</html>
4) 과정
- Web Application 실행 ->
- pom.xml(필요한 라이브러리를 다운로드 해서 사용할수 있도록 해줌니다.) ->
- web.xml 파일을 읽어서 애플리케이션 설정을 합니다. ->
/WEB-INF/spring/root-context.xml
파일을 읽어서 필요한 작업을 수행 ->/WEB-INF/spring/appServlet/servlet-context.xml
파일을 읽어서 필요한 작업을 수행 ->- HomeController 설정에 따라서
/
요청이 오면 home.jsp 를 출력
display 라는 요청을 전송 -> web.xml 설정에 따라서 servlet-context.xml 이 만든 HomeController에서 요청을 처리해주는 메소드를 찾고 없으면 404에러가 발생하면 메소드가 있으면 메소드의 내용을 수행하고 return 하는 문자열을 가지고 servlet-context.xml의 ViewResolver 설정을 읽고 실제 출력할 view의 이름을 결정해서 출력
6. Spring에서 web.xml에 설정할 수 있는 URL Pattern
1) /*
: 모든 요청
2) /
: .jsp를 제외한 모든 요청 - spring에서만 사용 가능
3) /디렉토리/*
: 디렉토리가 포함된 모든 요청 - 최근에 디렉토리를 이용해서 서비스를 구분하는 경우가 많다.
4) .확장자
: 확장자로 끝나는 모든 요청 - 이전에 *.do
로 많이 사용
5) /경로명
: 경로명에 해당하는 하나의 요청
- 기본 설정이
/
로 되어 있는데 작은 규모의 웹 애플리케이션에서는 변경하지 않고 사용한다. 서비스가 많아져서 하나의 웹 애플리케이션으로는 처리하기 힘든 경우 설정을 변경한다.
url-pattern 은 여러개 설정 가능
7.파라미터 인코딩 설정
- parameter : 클라이언트가 서버에게 전달하는 데이터
- html 이나 jsp 에서 만들게 됨
1) 파라미터 작성 방법
- URL 뒤에 ?를 추가하고
이름=값&이름=값...
의 형태로 작성 가능 - GET - form에서 name을 갖는 객체를 생성하면 form이 submit 될 때 파라미터로 만들어서 전달 - GET, POST
- ajax와 같은 요청에서 parameter를 별도로 만들어서 전송
- 프로그래밍 언어에서 Web Application 에게 요청을 보낼때도 ajax와 유사한 방식-GET,POST
2) 파라미터 전송 방식
- GET : URL 뒤에 파라미터를 붙여서 전송하는 방식, 자동 재전송 기능이 있지만 보안이 되지 않고 파라미터 길이에 제한이 있습니다.
- POST : 파라미터를 header에 숨겨서 전송하는 방식, 파라미터가 URL에서 보이지 않아서 보안이 GET보다도 우수하고 파라미터 길이에도 제한이 없다.
- password, textarea, file 이 있는 경우는 반드시 POST 방식을 사용
- 최근에는 form의 데이터는 대부분 POST 방식으로 전송하는 것을 권장
- 검색을 요청하는 form을 제외하고 대부분 POST 방식
- 링크를 이용해서 전송하는 경우는 대부분 GET 방식을 사용
3) 파라미터 인코딩
- GET 방식은 WAS가 처리하고 POST 방식은 서버의 코드가 처리
- spring에서는 web.xml 파일에 filter를 이용해서 처리가 가능
- Spring Web Project에서 무조건 설정 - 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>
Controller
- URL 요청이 오면 필요한 서비스를 호출하고 그 결과를 저장해서 View를 선택해주는 클래스
1.Controller 생성
- spring에서는 POJO 클래스 위에
@Controller
를 추가하면 됩니다. - Bean의 생성은 설정 파일의 Component-Scan을 이용
2.요청 처리 메소드의 기본 모양
- 포워딩으로 처리
@RequestMapping(value="처리할 URL", method=RequestMethod.전송방식)
public String 이름(Model model) {
// 전달할 데이터
model.setAttribute("이름", 데이터);
// 출력할 View
return "뷰이름";
}
- 여러개의 요청 처리
value={"URL1", "URL2", "URL3"...}
- display 라는 요청이 GET 방식으로 오면 request에 msg라는 이름으로 데이터를 저장해서 display라는곳으로 포워딩
@Controller
public class HomeController{
@RequestMapping(value="/display", method=RequestMethod.GET)
public String display(Model model) {
// 2. 처리 할내용
String msg = "spring MVC";
// 3. 데이터 저장 - request.setAttribute 와 동일
model.addAttribute("msg", msg);
// 4. 출력할 veiw 이름설정
return "display";
}
}
3.Spring 에서의 파라미터 처리
1) HttpServletRequest 이용
2) @RequestParam
이용
3) Command(DTO와 유사) 객체 이용
- HttpServletRequest를 이용하는 방법은 java의 모든 web project에서 사용가능
- 하지만 나머지 방법은 Spring Project에서만 가능
4.HttpServletRequest 를 이용한 파라미터 처리
1) String getParameter("파라미터 이름")
2) String [] getParameterValues("파라미터이름")
5.@RequestParam을 이용하는 방식
- Controller의 요청 처리 메소드 안에
@RequestParam("파라미터이름") 자료형 변수명
으로 설정 - 변수에 파라미터의 값을 대입주는데 형변환은 자동
6.Command 객체를 이용하는 방식
- 모든 파라미터 이름으로 구성된 DTO 클래스를 생성
- Controller의 요청 처리 메소드 안에
클래스이름 변수명
을 작성하면 모든 파라미터들이 변수에 대입
- Controller의 요청 처리 메소드 안에
7.파라미터 처리 실습
1) home.jsp 파일에 링크를 생성
<a href="param?num=10">Request를 이용한 파라미터 처리 </a><br/>
2) HomeController에 위의요청 param 요청을 처리하는 메소드를 생성
- param?num=10을 처리
@RequestMapping(value="/param", method=RequestMethod.GET)
public String param(Model model, HttpServletRequest request) {
String num = request.getParameter("num");
System.out.println(num);
return "";
}
3) home.jsp 파일에 form을 생성
<form action="get" method="get">
검색어:<input type="text" name="keyword" />
<input type="submit" value="검색"/>
</form>
4) HomeController 클래스에 get 요청을 처리하는 메소드를 생성
@RequestMapping(value="/get", method=RequestMethod.GET)
public String get(Model model,
@RequestParam("keyword") String keyword) {
System.out.println(keyword);
return "";
}
5) home.jsp 파일에 아이디 와 비밀번호를 입력받는 form을 생성
<form action="login" method="post">
<input type="text" name="id"
placeholder="아이디를 입력하세요!" required='required'/><br/>
<input type="password" name="pw"
placeholder="비밀번호를 입력하세요!" required='required'/><br/>
<input type="submit" value="로그인"/>
</form>
6) id 와 pw를 저장할 수 있는 클래스 생성
public class User {
private String id;
private String pw;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPw() {
return pw;
}
public void setPw(String pw) {
this.pw = pw;
}
@Override
public String toString() {
return "User [id=" + id + ", pw=" + pw + "]";
}
}
7) Controller 에 요청을 처리하는 메소드를 생성
@RequestMapping(value="/login", method=RequestMethod.POST)
public String login(Model model,
User user) {
System.out.println(user);
return "";
8.최근에 파라미터가 1개인 경우 처리
- 상세보기가 이러한 형태로 많이 구현
- 최근에는 파라미터가 1개이면 파라미터로 만들지 않고 URL의 마지막에 추가하는 형태를 많이 사용한다
https://ggangpae1.tistory.com/304
304가 글 번호 입니다.
- spring에서는 위와 같은 파라미터를
@PathVariable
이라는 어노테이션을 이용해서 처리
@RequestMapping(value="/경로/{num}")
public String ?(@PathVariable 자료형 num) 형태로 처리
- { } 안에 입력한 이름과 변수명은 일치해야 합니다.
1) hom.jsp 파일에 요청을 생성
<a href="article/20">20번 글 </a><br/>
2) HomeController에 위의 요청을 처리하는 메소드를 생성
@RequestMapping(value="/article/{num}", method=RequestMethod.GET)
public String detail(Model model,
@PathVariable int num) {
System.out.println(num);
return "";
}
View에게 데이터 전달
- Controller의 요청 처리 메소드에 HttpServletRequest를 추가해서 전달
- 이방식은 포워딩 할 때만 유효
request.setAttribute("이름", 데이터")
- Controller의 요청 처리 메소드에 HttpSesstion을 추가해서 전달
- 이동 방법에 상관없이 데이터를 직접 삭제할 때 까지 유효
session.setAttribute("이름", 데이터")
- Controller의 요청 처리 메소드에 Model을 추가해서 전달
- 이 방식은 포워딩 할 때만 유효
model.addAttribute("이름", 데이터)
- Controller의 요청 처리 메소드에 RedirectAttributes를 추가해서 전달
- 리다이렉트로 이동할 때 하번마 사용할 수 있는 데이터를 저장
attr.addFlashAttribute("이름", 데이터)
출력할 View 선택
요청 처리 메소드에서 String을 리턴해서 View을 결정
void로 리턴이 없도록 만들면 요청 URL이 View 이름이 됩니다.
리다이렉트 하고자 하는 경우에는 redirect:URL