본문 바로가기

Archived(Programming)/Spring #1(기초)

Web_0204

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");
	}
}

 

Bootstrap JSP 적용 전에 설정

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