Spring 기본

vencott·2021년 5월 19일
0

sinc 인턴교육

목록 보기
15/18
post-thumbnail

Spring 이론

개요

Spring에서 꼭 알아야 하는 3가지 개념

  1. IOC(Inversion Of Control)
    • DL(Dependency Lookup)
    • DI(Dependency Injection)
  2. AOP(Aspect Oriented Programming)
  3. Interceptor

AOP / Interceptor / Filter

요청이 넘어오는 시점에 앞단에서 뭔가 작업

설정 파일

web.xml + Filter

모든 request(/*)에 encodingFilter 설정

현업에 가면 web.xml을 열어 어떤 listener, filter들이 설정되어 있는지 보는 것이 가장 먼저 할 일

servlet-context.xml

  • 스키마 기반의 설정
    • xml파일에 설정
  • 어노테이션 기반의 설정
    • 코드상에서 설정

<beans:bean>

  • 객체를 생성해준다
  • ViewResolver가 해당 경로에서 오는 요청들을 포워딩 방식으로. jsp를 붙여
    분기

<context:component-scan>

  • Spring에서 MVC 컨트롤러 팩토리의 자바 코드는 설정 파일에 들어가 있다
  • Spring 내부의 xxxMapper가 사용자의 요청이 들어오면 명세된 패키지를 기반으로 해서 Controller를 스캔하고 알맞은 Controller를 찾아냄

Tomcat 서버 사용하기

서버 추가하기

포트 넘버 충돌을 피하기 위해 바꿔준다

Root Path로 변경

Controller

Annotation

Annotation을 사용해 Framework에게 클래스, 인스턴스 관리를 위임 → 제어의 역행

@Component

-- @Controller

-- @Services

-- @Repository

// UserCtrl.java
package com.sinc.intern.user.ctrl;

import org.springframework.stereotype.Controller;

@Controller
public class UserCtrl {

}

Controller의 리턴 타입

Controller의 리턴 타입은 String으로 주는 경우가 많다 -> jsp 파일 이름

메서드의 리턴 타입이나 매개변수 등 구문 형식에 제약이 없다

사용자의 request를 Controller의 메서드와 mapping 시켜주는 Annotation

// UserCtrl.java
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;

@Controller
public class UserCtrl {

	@RequestMapping(value="/login.do", method=RequestMethod.POST) // 설정 가능
	public String login() {

	}

	@RequestMapping("/logout.do")
	public String logout() {

	}

	@RequestMapping("/join.do")
	public String join() {

	}

	@RequestMapping("/search.do")
	public String search() {

	}
}

jsp 파일의 위치

무조건 views 디렉터리 내에 jsp 파일을 넣어야 한다

// home.jsp
<%@ 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>

Controller 리턴값

Controller의 메서드는 확장자를 제외한 파일의 논리적인 이름 리턴

// UserCtrl.java
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()
	public String login(UserDTO dto) {
		System.out.println("ctrl login");
		System.out.println("UserDTO: " + dto);
		return "home";
	}

	@RequestMapping("/logout.do")
	public String logout() {
		return null;
	}

	@RequestMapping("/join.do")
	public String join() {
		return null;
	}

	@RequestMapping("/search.do")
	public String search() {
		return null;
	}
}

UserVO와 UserDTO 생성

// UserVO.java
package com.sinc.intern.user.model.vo;

public class UserVO {
	private String id, pwd, name;
	private double point;
	private String dept;

	public UserVO() {
		// TODO Auto-generated constructor stub
	}

	public UserVO(String id, String pwd, String name, double point, String dept) {
		super();
		this.id = id;
		this.pwd = pwd;
		this.name = name;
		this.point = point;
		this.dept = dept;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPoint() {
		return point;
	}

	public void setPoint(double point) {
		this.point = point;
	}

	public String getDept() {
		return dept;
	}

	public void setDept(String dept) {
		this.dept = dept;
	}

	@Override
	public String toString() {
		return "UserVO [id=" + id + ", pwd=" + pwd + ", name=" + name + ", point=" + point + ", dept=" + dept + "]";
	}

}
// UserDTO.java
package com.sinc.intern.user.model.vo;

public class UserDTO {
	private String id, pwd;

	public UserDTO() {
		// 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 + "]";
	}

}

Controller의 리턴 타입이 void인 경우

사용자의 요청 url을 기준으로 찾는다(logout.do 이므로 logout.jsp)

// UserCtrl.jsp
	@RequestMapping("/logout.do")
	public void logout() { // 리턴타입이 void
		System.out.println("ctrl logout");
	}

ModelAndView return

// UserCtrl.java
	@RequestMapping("/join.do")
	public ModelAndView join(ModelAndView mv) {
		System.out.println("ctrl join");
		mv.addObject("msg", "Hi, JSLIM");
		mv.setViewName("home");
		return mv;
	}
// home.jsp
<%@ 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 ${msg}</P>
</body>
</html>

ModelAndView에서 Model만 떼어서 사용 가능(추천)

// UserCtrl.java
	@RequestMapping("/search.do")
	public String search(Model model) {
		System.out.println("ctrl search");
		model.addAttribute("msg", "using model 섭쌤 추천~~~~~~~");
		return "home";
	}

UserVO return

// UserCtrl.java
	@RequestMapping("/ajax.do")
	@ResponseBody // 비동기 통신
	public UserVO ajax() {
		System.out.println("ctrl ajax");
		return new UserVO("jslim", "jslim", "임정섭", 1000, "EMART");
	}

UserCtrl 전체

// UserCtrl.java
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 {

	@RequestMapping()
	public String login(UserDTO dto) { // 리턴타입이 String
		System.out.println("ctrl login");
		System.out.println("UserDTO: " + dto);
		return "home";
	}

	@RequestMapping("/logout.do")
	public void logout() { // 리턴타입이 void
		System.out.println("ctrl logout");
	}

	@RequestMapping("/join.do")
	public ModelAndView join(ModelAndView mv) {
		System.out.println("ctrl join");
		mv.addObject("msg", "Hi, JSLIM");
		mv.setViewName("home");
		return mv;
	}

	@RequestMapping("/search.do")
	public String search(Model model) {
		System.out.println("ctrl search");
		model.addAttribute("msg", "using model 섭쌤 추천~~~~~~~");
		return "home";
	}

	@RequestMapping("/ajax.do")
	@ResponseBody // 비동기 통신
	public UserVO ajax() {
		System.out.println("ctrl ajax");
		return new UserVO("jslim", "jslim", "임정섭", 1000, "EMART");
	}

}

로그인 기능 구현

Welcome page

index.jsp에서 main.do로 url연결

// index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<script type="text/javascript">
	location.href = "main.do";
</script>

HomeController에서 main.do url을 실제 홈페이지 jsp 파일인 home.jsp로 연결해서 반환

// HomeController
package com.sinc.intern;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

	@RequestMapping("/main.do")
	public String home() {
		System.out.println("ctrl main");
		return "home";
	}
}

Service

@Service를 통해 Service임을 명세함과 동시에 별칭을 부여

컨트롤러에서 @Resource를 통해 해당 별칭을 가진 타입의 객체를 생성해서 할당

// UserCtrl.java
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";
	}

	@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 "redirect:/main.do";
	}
}

인스턴스가 생성되는 UserServiceImpl 클래스에 @Service를 까먹지 않도록 주의

// UserService.java
package com.sinc.intern.user.service;

public interface UserService {

	public Object login(Object obj);

}

// UserServiceImpl.java
package com.sinc.intern.user.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.sinc.intern.user.model.sql.UserDao;

@Service("userS") // Annotation 까먹지 않도록 주의, 별칭 부여 가능
public class UserServiceImpl implements UserService {

	@Resource(name = "userD")
	private UserDao dao;

	@Override
	public Object login(Object obj) {
		System.out.println("user service login");
		return null;
	}

}

@Service("userS")를 클래스 파일에 명시하는 것(어노테이션 기반의 설정)

root-context.xml에 bean 태그를 이용해 명세해 놓는 것(스키마 기반의 설정)은 동일하다

// root-context.xml

<bean id="userS" class="com.sinc.intern.user.service.UserServiceImpl">
</bean>

단, 의존성을 주입할 때는 @Resources 어노테이션을 사용하는 것이 월등히 편하기 때문에,

현업에서는 서비스 명세와 의존성 주입 모두 어노테이션 기반으로만 하거나, 서비스 명세는 스키마 기반, 의존성 주입은 어노테이션 기반으로 혼용해서 사용한다

Dao

@Repository를 통해 Dao임을 명세함과 동시에 별칭을 부여

서비스에서 @Resource를 통해 해당 별칭을 가진 타입의 객체를 생성해서 할당

// UserServiceImpl.java
package com.sinc.intern.user.model.sql;

import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

@Repository("userD")
public class UserDaoImpl implements UserDao {

	@Resource(name = "sqlSession")
	private SqlSession session;

	@Override
	public Object loginRow(Object obj) {
		System.out.println("user dao loginRow: " + obj);
		System.out.println("user dao conn: " + session);
		return null;
	}

}

인스턴스가 생성되는 UserDaoImpl 클래스에 @Repository를 까먹지 않도록 주의

// UserDao.java
package com.sinc.intern.user.model.sql;

public interface UserDao {

	public Object loginRow(Object obj);

}

// UserDaoImpl.java
package com.sinc.intern.user.model.sql;

import org.springframework.stereotype.Repository;

@Repository("userD")
public class UserDaoImpl implements UserDao {

	@Override
	public Object loginRow(Object obj) {
		System.out.println("user dao loginRow");
		return null;
	}

}

DAO-MyBatis로 데이터 꺼내오기

// UserDaoImpl.java
package com.sinc.intern.user.model.sql;

import javax.annotation.Resource;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

@Repository("userD")
public class UserDaoImpl implements UserDao {

	public static final String PREFIX = "com.sinc.intern.test";

	@Resource(name = "sqlSession")
	private SqlSession session;

	@Override
	public Object loginRow(Object obj) {
		System.out.println("user dao loginRow: " + obj);
		System.out.println("user dao conn: " + session);

		Object result = session.selectOne(PREFIX + ".login", obj);
		System.out.println("dao loginRow result: " + result);

		return result;
	}

}

testMapper.xml에 SQL문 작성

절대 세미콜론(;) 쓰면 안된다

// testMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.sinc.intern.test">
	<select id="login" parameterType="userdto" resultType="uservo">
		SELECT ID, PWD, NAME, POINT, DEPT
		FROM INTERN_USER_TBL
		WHERE ID = #{id} AND PWD = #{pwd}
	</select>
</mapper>

SQL에서 사용할 parameter와 result 타입 명세

절대 세미콜론(;) 쓰면 안된다

// mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<typeAliases>
		<typeAlias type="com.sinc.intern.user.model.vo.UserDTO"
			alias="userdto" />
		<typeAlias type="com.sinc.intern.user.model.vo.UserVO"
			alias="userdto" />
	</typeAliases>

</configuration>

JSP의 form 태그

login.do로 접속해 폼 태그 안에 있는 id, pwd 값을 UserCtrl의 login 메서드로 전달

// login.jsp
			<form action="login.do" method="post">
				<div class="form-group has-feedback">
					<input type="text" name="id" class="form-control"
						placeholder="USER ID" /> <span
						class="glyphicon glyphicon-envelope form-control-feedback"></span>
				</div>
				<div class="form-group has-feedback">
					<input type="password" name="pwd" class="form-control"
						placeholder="Password" /> <span
						class="glyphicon glyphicon-lock form-control-feedback"></span>
				</div>
				<div class="row">
					<div class="col-xs-8">
						<div class="checkbox icheck">
							<label> <input type="checkbox" name="useCookie">
								Remember Me
							</label>
						</div>
					</div>
					<!-- /.col -->
					<div class="col-xs-4">
						<button type="submit" class="btn btn-primary btn-block btn-flat">Sign
							In</button>
					</div>
					<!-- /.col -->
				</div>
			</form>
// UserCtrl.java
	@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 "redirect:/main.do";
	}

출처: SHINSEGAE I&C 인턴십

profile
Backend Developer

0개의 댓글