Maven -> 빌더
빌드 뿐만 아니라 내부에서 필요로하는 jar파일을 배포할 수 있다
현업에서는 라이브러리들을 다운받을 수 있는 서버를 별도로 둔다(Sonatype)
외부에 있는 서버에 접근할 수 있는 url로 해서 공유
(현업에서 큰 규모의 프로젝트 내부망만 활용 가능, 개발 시에 Copy & Paste 불가)
# 스프링에서 중요한 개념
- IOC(Inversion Of Control)
- AOP(Aspect Oriented Programming)
- Interceptor
- web.xml + Filter
AOP, Interceptor, Filter 개념은 유사해보일 수 있다(특히, AOP와 Interceptor)
Browser -> WAS로 Request 넘어옴!
이 때, 넘어온 요청에 대해서 Filter 동작. 그렇게 되면 Ctrl에서 한글 Encoding과 같은 동작을 처리할 필요 없어짐.
(Filter는 Request 자체에 대해서, 웹에 대해 처리하는 것)
Ctrl 실행 전 또는 실행 후의 앞단에서 처리되는 것이 Interceptor
(Interceptor는 Framework에 대해서 처리할 수 있는 것)
Ctrl에서 Service로 넘어가면서 Business를 처리하기 전 처리되는 것이 AOP
Spring 설정파일
Servlet-context.xml(Controller)
root-context.xml(AOP)
# filter 및 서버 설정
web.xml
<url-pattern>*.do</url-pattern>
...
<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>
servlet-context.xml
...
<context:component-scan base-package="com.sinc.intern.**" />
톰캣 서버추가(window-preferences-Server-Runtime Environment)
# Framework에서 XML 설정파일 의미
servlet-context.xml 내부의
bean 태그를 통해 인스턴스가 생성되면 Framework에서 해당 인스턴스를 관리할 수 있음
Spring Framework에서는 FrontController에서 ViewResolver(경로와 확장자)를 하나 더 거치게 됨
분기할 페이지 정보와 경로를 얻어옴
Dispatcher가 ViewResolver에 Forward 되어야 할 페이지 이름만 넘겨주면
ViewResolver가 .jsp를 붙여서 해당 페이지를 Forward 해줘서 넘겨준다
xml 파일 통한 설정 > 스키마 기반의 설정
이렇게 되면 복잡성이 증대되니까 이런 것보다는 어노테이션 기반의 설정 사용 (현업에서는 믹스해서 사용)
@통해서 객체를 생성하고 이를 Framework에서 관리한다
@Controller = HomeController homeController = new HomeController() ;
이러한 구조를 통해 Framework에서 관리된다
@Component를 상속받는 3가지 어노테이션 클래스
- @Controller
- @Service
- @Repository
일반적으로 컨트롤러 @Controller 어노테이션을 통해서 등록 후
하나의 컨트롤러 내부에서 여러 메서드 처리
Request와 Response가 없는데 어떻게 파라미터 받을까?
-> 넘어오는 파라미터와 객체 이름이 동일하면 알아서 바인딩 시켜줌(Setter 자동 호출)
# 다음과 같이 login.do로 들어가면 return을 통해 home.jsp 뷰를 띄워준다(String)
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.sinc.intern.user.model.vo.UserDTO;
@Controller
public class UserCtrl {
// 보편적으로 String, ModelAndView
// 그 중에서도 String을 제일 많이 Return(매개변수는 상관 무)
@RequestMapping("/login.do")
public String login(UserDTO dto) {
// Request와 Response가 없는데 어떻게 파라미터 받을까?
// -> 넘어오는 파라미터와 객체 이름이 동일하면 알아서 바인딩 시켜줌
System.out.println("ctrl login");
return "home" ; // home.jsp로 보내기(이름만으로 알아서 mapping)
}
@RequestMapping("/logout.do")
public String logout() {
return null;
}
@RequestMapping("/join.do")
public String join() {
return null;
}
@RequestMapping("/search.do")
public String search() {
return null;
}
}
package com.sinc.intern.user.model.vo;
public class UserDTO {
private String id, pwd ;
public UserDTO() {
super();
// TODO Auto-generated constructor stub
}
public UserDTO(String id, String pwd) {
super();
this.id = id;
this.pwd = pwd;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "UserDTO [id=" + id + ", pwd=" + pwd + "]";
}
}
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> This is a Spring Framework by J.S.LIM </P>
</body>
</html>
# 다음과 같이 코드 변경 후 DTO를 GET 방식으로 넘겨받을 수 있다
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.sinc.intern.user.model.vo.UserDTO;
@Controller
public class UserCtrl {
// 보편적으로 String, ModelAndView
// 그 중에서도 String을 제일 많이 Return(매개변수는 상관 무)
@RequestMapping("/login.do")
public String login(UserDTO dto) {
// Request와 Response가 없는데 어떻게 파라미터 받을까?
// -> 넘어오는 파라미터와 객체 이름이 동일하면 알아서 바인딩 시켜줌
System.out.println("ctrl login");
System.out.println("UserDTO : "+ dto);
return "home" ; // home.jsp로 보내기(이름만으로 알아서 mapping)
}
@RequestMapping("/logout.do")
public String logout() {
return null;
}
@RequestMapping("/join.do")
public String join() {
return null;
}
@RequestMapping("/search.do")
public String search() {
return null;
}
}
3가지를 맞춰야 한다!!
화면단(View) , VO/DTO 변수의 이름, Table Column의 이름을 맞춰야한다(_언더바 사용 자제)
# void 형 반환형
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.sinc.intern.user.model.vo.UserDTO;
@Controller
public class UserCtrl {
// 보편적으로 return 타입 String, ModelAndView, void
// 그 중에서도 String을 제일 많이 Return(매개변수는 상관 무)
@RequestMapping("/login.do")
public String login(UserDTO dto) {
// Request와 Response가 없는데 어떻게 파라미터 받을까?
// -> 넘어오는 파라미터와 객체 이름이 동일하면 알아서 바인딩 시켜줌
System.out.println("ctrl login");
System.out.println("UserDTO : "+ dto);
return "home" ; // home.jsp로 보내기(이름만으로 알아서 mapping)
}
// void 타입 반환형은 치고 들어온 이름으로 jsp 페이지를 찾음(logout.jsp)
@RequestMapping("/logout.do")
public void logout() {
System.out.println("ctrl logout");
}
// View에 대한 정보와 데이터에 대한 정보 하나로 실어 보내기
@RequestMapping("/join.do")
public ModelAndView join(ModelAndView mv) {
System.out.println("ctrl join");
mv.addObject("msg", "Hi, SWYOON");
mv.setViewName("home");
return mv;
}
@RequestMapping("/search.do")
public String search() {
return null;
}
}
# ModelAndView 반환형
ModelAndView mv에서 addObject했던 데이터들이 그대로 넘어옴을 확인할 수 있다
(해당 jsp에서 EL 표현식으로 표현가능)
# String 반환형 + Model 매개변수
가장 추천하는 방식
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.sinc.intern.user.model.vo.UserDTO;
@Controller
public class UserCtrl {
...
// 가장 추천하는 유형
// 모델은 따로 넘기고 View는 string으로 넘긴다
@RequestMapping("/search.do")
public String search(Model model) {
System.out.println("ctrl search");
model.addAttribute("msg", "using model 섭쌤 추천~~");
return "home";
}
}
# AJAX 비동기 통신
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.sinc.intern.user.model.vo.UserDTO;
import com.sinc.intern.user.model.vo.UserVO;
@Controller
public class UserCtrl {
...
// AJAX는 하나 더 필요!
@RequestMapping("/ajax.do")
@ResponseBody // 비동기 통신
public UserVO ajax() {
System.out.println("ctrl ajax");
return new UserVO("swyoon", "swyoon", "윤신웅", 1000, "EMART");
}
}
Controller는 업무당 하나의 Controller로 구성하여 개발
package com.sinc.intern;
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);
@RequestMapping("/main.do")
public String home() {
System.out.println("ctrl main");
return "home";
}
}
/*// 보편적으로 return 타입 String, ModelAndView, void
// 그 중에서도 String을 제일 많이 Return(매개변수는 상관 무)
@RequestMapping("/login.do")
public String login(UserDTO dto) {
// Request와 Response가 없는데 어떻게 파라미터 받을까?
// -> 넘어오는 파라미터와 객체 이름이 동일하면 알아서 바인딩 시켜줌
System.out.println("ctrl login");
System.out.println("UserDTO : "+ dto);
return "home" ; // home.jsp로 보내기(이름만으로 알아서 mapping)
}
// void 타입 반환형은 치고 들어온 이름으로 jsp 페이지를 찾음(logout.jsp)
@RequestMapping("/logout.do")
public void logout() {
System.out.println("ctrl logout");
}
// View에 대한 정보와 데이터에 대한 정보 하나로 실어 보내기
@RequestMapping("/join.do")
public ModelAndView join(ModelAndView mv) {
System.out.println("ctrl join");
mv.addObject("msg", "Hi, SWYOON");
mv.setViewName("home");
return mv;
}
// 가장 추천하는 유형
// 모델은 따로 넘기고 View는 string으로 넘긴다
@RequestMapping("/search.do")
public String search(Model model) {
System.out.println("ctrl search");
model.addAttribute("msg", "using model 섭쌤 추천~~");
return "home";
}
// AJAX는 하나 더 필요!
@RequestMapping("/ajax.do")
@ResponseBody // 비동기 통신(이를 활용해서 JSON 양식 선언 필요 x)
public UserVO ajax() {
System.out.println("ctrl ajax");
return new UserVO("swyoon", "swyoon", "윤신웅", 1000, "EMART");
}*/
# User 백엔드 구현
package com.sinc.intern.user.ctrl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.sinc.intern.user.model.vo.UserDTO;
@Controller
public class UserCtrl {
// 로그인 폼을 띄워주기
@RequestMapping("/loginForm.do")
public String loginForm() {
System.out.println("user loginForm");
return "user/loginPost" ;
}
// DTO로 파라미터 받아서 로그인 시도
@RequestMapping(value="/login.do" , method=RequestMethod.POST)
public String login(UserDTO dto) {
System.out.println("user login dto : " + dto);
return null ;
}
}
package com.sinc.intern.user.service;
// 서비스를 인터페이스를 통해 구현함으로써 다형성 발현
public interface UserService {
public Object login(Object obj) ;
}
@Autowired // 의존성 주입
원래 Service는 private 자료형으로 가지고 관리해야 하지만 이를 통해 손쉽게 관계 맺고 관리 가능
그러나, 상황에 따라 여러 서브 타입이 필요할 수 있다. 그럴 때는 어떻게 해야하나
@Resource(name="") // 해당 이름의 별칭으로 담아서 관리하기
package com.sinc.intern.user.ctrl;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.sinc.intern.user.model.vo.UserDTO;
import com.sinc.intern.user.service.UserService;
@Controller
public class UserCtrl {
@Resource(name="userS")
private UserService service;
// 로그인 폼을 띄워주기
@RequestMapping("/loginForm.do")
public String loginForm() {
System.out.println("user loginForm");
return "user/login" ;
}
// DTO로 파라미터 받아서 로그인 시도
// HttpSession으로 받아오기
@RequestMapping(value="/login.do" , method=RequestMethod.POST)
public String login(UserDTO dto, HttpSession session) {
System.out.println("user login dto : " + dto);
Object user = service.login(dto);
if(user != null) {
session.setAttribute("loginUser", user) ;
}
return null ;
}
}
package com.sinc.intern.user.service;
// 서비스를 인터페이스를 통해 구현함으로써 다형성 발현
public interface UserService {
public Object login(Object obj) ;
}
package com.sinc.intern.user.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.sinc.intern.user.model.sql.UserDao;
// 빈 괄호로 활용시 해당 클래스 이름의 대문자만 소문자로 바꿔서 Framework에서 관리
@Service("userS")
public class UserServiceImpl implements UserService {
@Resource(name="userD")
private UserDao dao ;
@Override
public Object login(Object obj) {
System.out.println("user service login : " +obj);
return dao.loginRow(obj);
}
}
'Archived(Programming) > Spring #1(기초)' 카테고리의 다른 글
Spring_data 처리(글 목록) (0) | 2020.02.06 |
---|---|
Spring_Mybatis 연동 (0) | 2020.02.04 |
Web_Spring (0) | 2020.02.03 |
Web_JSON (0) | 2020.02.03 |
Web_JSON (0) | 2020.02.02 |