Spring / DB연동, MVC, Request annotation

Cheol·2023년 8월 6일
0

Database 연동

JDBC 사용

Jdbc 기술 사용

pom.xml의 dependency를 추가하여 Maven에서 jar파일을 자동으로 불러와 설치한다.

<dependency>
    <groupId>com.jslsolucoes</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.1.0</version>
</dependency>

DataSource 설정

  1. 커넥션 풀을 이용한 DataSource 설정
  2. JNDI를 이용한 DataSource 설정
  3. DriverManager를 이용한 DataSource설정 (실습)

DataSource를 사용하기 위한 dependency를 추가

<!--DataSource커넥션 풀 추가부분 -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-dbcp2</artifactId>
  <version>2.1</version>
</dependency>

config.xml
driverClassName, url, username, password 설정

<bean id = "myDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
	<property name="driverClassName" value="${jdbc.driver}"></property>
	<property name="url" value="${jdbc.url}"></property>
	<property name="username" value="${jdbc.userid}"></property>
	<property name="password" value="${jdbc.passwd}"></property>
</bean>

TestDAO.java

//config.xml에서 설정한 데이터소스를 멤버변수로 받아올 수 있다.
	@Autowired
	DataSource dataSource;
//커넥션을 dataSource로 바꾼다. 
con = dataSource.getConnection();

JDBCTemplate 클래스 이용

JDBCTemplate를 사용하기 위한 dependency 추가

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>4.3.22.RELEASE</version>
</dependency>

config.xml

<bean id="testDAO" class="com.dao.TestDAO">
<!-- 생성자를 이용하는 방법 -->
<!-- 	<constructor-arg name ="dataSource" ref="myDataSource"></constructor-arg> -->

<!-- set함수를 이용하는 방법 -->
	<property name="jdbcTemplate" ref="myDataSource"></property>
</bean>

TestDAO.java

// dataSource를 config.xml에서 DAO로 reference했다.
	private JdbcTemplate jdbcTemplate;

	public TestDAO(DataSource dataSource) {
		//생성자를 통해 DataSource 주입, JdbcTemplate에 설정
		this.jdbcTemplate = new JdbcTemplate(dataSource);
		//데이터소스 주소 출력
		//jdbcTemplate 주소 출력
	}
	
	public void setJdbcTemplate(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

selectAll()

	public List<TestDTO> select() {
		
		//getConnection, close 필요없음. => mybatis도 getConnection, close 필요없음
		//mapRow를 통해 DTO 리턴시 자동으로 List에 add까지 함.
		
		List<TestDTO> list = jdbcTemplate.query("select * from test",
				new RowMapper<TestDTO>() {
					public TestDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
						TestDTO dto = new TestDTO();
						dto.setNum(rs.getInt(1));
						dto.setUsername(rs.getString(2));
						dto.setAddress(rs.getString(3));
						return dto;
					}
		});
		return list;
	}//end select

insert()

	public void insert(int num, String name, String address) {
		jdbcTemplate.update("insert into test values (?,?,?)",
		num, name, address);
	//커밋도 없어도 된다.
	}//end insert


📌Mybatis

mybatis를 사용하기 위해 pom.xml에 dependency를 추가한다.

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>

OracleDB에 접속하기 위한 jdbc.properties 파일을 따로 만든다.

jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
jdbc.userid=scott
jdbc.passwd=tiger

dept.xml

<!-- 1. properties 등록 -->
<context:property-placeholder location="classpath:com/config/jdbc.properties"/>
<!-- 2. DataSource생성 -->
<bean id = "dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
	<property name="driverClassName" value="${jdbc.driver}"></property>
	<property name="url" value="${jdbc.url}"></property>
	<property name="username" value="${jdbc.userid}"></property>
	<property name="password" value="${jdbc.passwd}"></property>
</bean>

jdbc.properties 파일을 dept.xml에서 사용하기 위해 등록하고 가져온 데이터로 DataSource를 설정한다.

sqlSessionFactory

<!-- 3. SqlSessionFactoryBean생성, mapper지정, alias지정 -->
<bean id="mysqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"></property>
	<property name="mapperLocations">
		<list>
			<value>classpath:com/config/DeptMapper.xml</value>
		</list>
	</property>
	<property name="typeAliases">
		<list>
			<value>com.dto.DeptDTO</value> <!-- dto 클래스에서 alias명 지정 @Alias('alias명') -->
		</list>
	</property>
</bean

sqlSessionTemplate

<!-- 4. 마지막 sqlSessionTemplate 생성, SqlSession과 동일한 기능. 실제 dao에서 사용하는 객체 -->
<bean id="mySqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg name = "sqlSessionFactory" ref="mysqlSessionFactory"></constructor-arg>
</bean>


❗❗Spring Web MVC❗❗

MVC(Model-View-Controller)는 코드를 기능에 따라 Model, View, Controller 3가지 요소로 분리하여 구현하는 개발 방법이다.

Model : 어플리케이션의 데이터와 비즈니스 로직을 담는 객체이다.
View : Model의 정보를 사용자에게 표시한다. 하나의 Model을 다양한 View에서 사용할 수 있다.
Controller : Model과 View의 중계 역할을 담당한다. 사용자의 요청을 받아 Model에 변경된 상태를 반영하고 응답을 위한 View를 선택한다.

  • MVC패턴은 UI코드와 비즈니스 코드를 분리함으로써 종속성을 줄이고 재사용성을 높여서 보다 쉬운 유지보수성을 확보할 수 있다.
  • 오픈소스 Web MVC Framework
    : Spring MVC, Struts, Struts2 등

👌Spring MVC 아키텍쳐

-> 클라이언트 요청이 들어오면 DispatcherServlet이 가장 먼저 요청을 받는다.
-> HandlerMapping이 요청에 해당하는 Controller를 return 한다.
-> Controller는 비즈니스 로직을 수행(호출)하고 결과 데이터를 ModelAndView에 반영하여 return한다.
-> VIewResolver는 논리적인 view 이름을 받아 해당하는 View 객체를 return 한다.
-> 마지막으로 Model을 가지고 최종적으로 보여질 JSP로 포워드 된다.

==> 정리(핵심 Component):

DispatcherServlet : 클라이언트의 요청을 전달받아컨트롤러에게 클라이언트의 요청을 전달하고 컨트롤러가 리턴한 결과값View에게 전달하여 알맞은 응답을 생성하는 역할

HandlerMapping : 클라이언트의 요청 URL어떤 컨트롤러가 처리할지를 결정

Controller : 실제 비즈니스 로직을 처리하는 컴포넌트이다.
               Spring API 또는 POJO형식으로 작성한다.

ModelAndView : 컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 저장
ViewResolver : 컨트롤러의 처리결과를 생성할 뷰를 결정
View : 컨트롤러의 처리 결과 화면을 생성



👌Spring MVC의 IoC 컨테이너 구성

web application에서 동작하는 IoC컨테이너는 2가지 방법으로 만들어진다. ( 일반적으로 같이 사용: 웹기술에 의존적인 부분과 아닌 부분을 분리할 목적 )

가) Servlet Application Context
      : 스프링 어플리케이션의 요청을 처리하는 서블릿안에서 생성
나) Root Application Context
      : 웹 애플리케이션에서 생성
      : 서블릿 레벨에 등록되는 컨테이너들의 부모 컨테이너가 된다.



DispatcherServlet 설정

클라이언트의 요청을 처리할 DispatcherServlet을 web.xml 파일에 등록한다.
웹 어플리케이션에서 사용할 빈들의 설정 파일명은 기본적으로 등록된 서블릿명을 사용한다.
ex :

서블릿명-servlet.xml -> 서블릿 어플리케이션 컨텍스트

  • 웹 어플리케이션에서 사용할 빈들의 설정 파일은 기본적으로 등록된 서블릿명을 사용하지만 명시적으로 설정도 가능하다. 복수설정도 가능.
<servlet>
<servlet-name>dept</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
  <param-name>contextConfigLocation</param-name>

프로젝트 생성 시 com.test.app 같은 형식을 갖는데, 이때 app이 프로젝트의 주소이다.

Controller는 Servlet과 동일하지 않다.
다만, Controller 파일의 함수 하나의 동작은 서블릿의 동작과 동일하다.

return값에 파일속성없이 파일명만 적는다면 .java파일이 아닌 .jsp파일이다.

Servlet에서는 webapp에 jsp, html 파일등을 저장했지만,스프링은 webapp->WEB-INF->views에 저장해야한다.

프로젝트 생성 (레거시 프로젝트, MVC, 패키지명, 주소)-> pom.xml설정 -> maven update -> Controller에 @Controller 설정




❗Controller - RequestMapping 사용법


📕method (GET, POST)

loginForm에서 전달하는 방식을 method를 지정하여 리턴값을 지정할 수 있다.

package com.controller;

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

@Controller
public class TestController {
	
	@RequestMapping("/")
	public String xxx() {
		return "loginForm";
	}

	@RequestMapping(value = "/Login", method = RequestMethod.GET)
	public String yyy() {
		System.out.println("get 요청됨");
		return "loginForm";
	}
	
	@RequestMapping(value = "/Login", method = RequestMethod.POST)
	public String zzz() {
		System.out.println("post 요청됨");
		return "login";
	}
}

📙GET방식의 params 지정

package com.controller;

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

@Controller
public class TestController {
	
	@RequestMapping("/")
	public String main() {
		System.out.println("TestController.main");
		return "login";
	}
	
	//localhost:8080/test_1/login?aaa=bbb
	@RequestMapping(value = "/login", params = "aaa=bbb")
	public String loginForm() {
		System.out.println("TestController.aaa=bbb");
		return "login";
	}

	//localhost:8080/test_1/login?aaa=ccc
	@RequestMapping(value = "/login", params = "aaa=ccc")
	public String login() {
		System.out.println("TestController.aaa=ccc");
		return "login";
	}

	
	//localhost:8080/test_1/login?xxx
	@RequestMapping(value = "/login", params = "xxx")
	public String login2() {
		System.out.println("TestController.xxx=아무값");
		return "login";
	}
	
	//localhost:8080/test_1/login?kkk=b
	@RequestMapping(value = "/login", params = "kkk=b", method = RequestMethod.GET)
	public String x() {
		System.out.println("TestController.x kkk=b");
		return "login";
	}

	//localhost:8080/test_1/login?kkk=c
	@RequestMapping(value = "/login", params = "kkk=c", method = RequestMethod.GET)
	public String y() {
		System.out.println("TestController.x kkk=c");
		return "login";
	}
	
	
}

📒클래스에 RequestMapping 어노테이션 적용

package com.controller;

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

@Controller
@RequestMapping("/hello")
public class HelloController {
		
	@RequestMapping("/login")
	public String hello() {
		System.out.println("hello/login");
		return "login";
	}
}


package com.controller;

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

@Controller
@RequestMapping("/test")
public class TestController {
	
	@RequestMapping("/login")
	public String xx() {
		System.out.println("test/login");
		return "login";
	}

	@RequestMapping("/main")
	public String yy() {
		System.out.println("test/main");
		return "main";
	}
	
}

클래스에 주소 지정 시 접근방법

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	main.jsp
</h1>
<a href="login">test/login.jsp이동</a><br>
<a href="/test_1/hello/login">hello/login.jsp이동</a><br>
<a href="../hello/login">hello/login.jsp이동</a><br>
<a href="main">main 이동</a>
</body>
</html>



😁파라미터 값 받기

폼에서 전달되는 파라미터값을 받기 위한 8가지 방법

package com.controller;

import java.io.InputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

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

import com.dto.LoginDTO;

@Controller
public class TestController {
	
	
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login() {
		return "login";
	}

	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String loginForm() {
		return "loginForm";
	}
	
	@RequestMapping("/login2")
	public String login2(@RequestParam("userid") String id, @RequestParam("passwd") int pw) {
		System.out.println("userid:"+id+" passwd:"+(pw+100));
		return "login";
	}
	
	@RequestMapping("/login3")
	public String login3(@RequestParam("userid") String id, @RequestParam("passwd") double pw) {
		System.out.println(id+"\t"+ pw);
		return "login";
	}

	@RequestMapping("/login4")	//파라미터로 받는 변수명 맞추지 않으면 null뜬다.
	public String login4(String userid, String passwd) {
		System.out.println(userid+"\t"+ passwd);
		LoginDTO dto = new LoginDTO(userid, passwd);
		System.out.println(dto);
		return "login";
	}
	
	@RequestMapping("/login4_1")
	public String login4_1(LoginDTO dto) {
		System.out.println(dto);
		return "login";
	}

	@RequestMapping("/login5")
	public String login5(@RequestParam(required = false, defaultValue = "홍길동")
	String userid, String passwd) {
		System.out.println("/login5 @RequestParam(required = false, defalutValue = \"홍길동\")"+userid + "\t" + passwd);
		return "login";
	}
	
	@RequestMapping("/login6")	//Map형태로 저장. key값은 파라미터로 넘어온 name값
	public String login6(@RequestParam Map<String, String> m) {
		System.out.println("/login6 @RequestParam Map<String, String> m "+m.get("userid")+"\t"+m.get("passwd"));
		return "login";
	}

	@RequestMapping("/login7")
	public String login7(HttpServletRequest request) {
		String id = request.getParameter("userid");
		String pw = request.getParameter("passwd");
		System.out.println(id+'\t'+pw);
		return "login";
	}
}



😁파라미터 값 넘기기 / 받기

package com.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.dto.LoginDTO;

@Controller
public class TestController {
	
	@RequestMapping("/main")
	public String xx() {
		System.out.println("main======");
		return "main";
	}
	//ModelAndView : view페이지 정보, view 전달 데이터 추가
	//컨테이너에게 ModelAndView를 리턴
	@RequestMapping("/aaa")
	public ModelAndView xxx2() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("username","홍길동");	//request.setAttribute와 같은 기능
		mav.addObject("age",20);
		
		LoginDTO dto = new LoginDTO("aaaa");
		mav.addObject("login",dto);
		mav.setViewName("main2");//view 페이지: WEB-INF/views/main2.jsp, viewResolver 사용
		//servlet의 forward(request, response)랑 같은 기능
		
		return mav;	//ModelAndView 리턴
	}
}

mav에 key값을 지정하여 값을 넘긴다.


main2.jsp

<%@page import="javax.lang.model.element.Element"%>
<%@page import="org.springframework.web.servlet.ModelAndView"%>
<%@ 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>
<% 
String username = (String)request.getAttribute("username"); 
String username2 = (String)request.getParameter("username"); 
String username3 = (String)session.getAttribute("username");
%>
<body>
main2.jsp<br>
1.el태그 이름: ${username}<br>
1.el태그 나이: ${age}<br>
1.el태그 dto: ${login.name}<br>
<hr>
2. req.getAtt: <%= username %><br>
3. req.getparam: <%= username2 %>
<hr>
4. session :<%= username3 %>
</body>
</html>

request.getAttributeel태그만 값을 가져온 것을 알 수 있다.



Controller

package com.controller;

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

import com.dto.LoginDTO;

@Controller
public class TestController {
		
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String xx() {
		return "loginForm";
	}
    
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String x(LoginDTO dto) {
		System.out.println(dto);
		//req.setAtt와 동일, key값은 자동으로 소문자시작의 클래스이름, loginDTO
		return "login1";
		//데이터의 자동 forward => req.getAtt 	//key = 소문자 클래스이름으로 생성
		//key = loginDTO
	}
	
	@RequestMapping(value = "/login3", method = RequestMethod.POST)
	public String login3(@ModelAttribute("xxx") LoginDTO dto) {
		System.out.println(dto);
		return "login3";
	}
	
}

LoginForm에서 DTO값을 받아 login1.jsp로 넘겨준다.


login1.jsp

<%@page import="com.dto.LoginDTO"%>
<%@ 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>
<%
LoginDTO dto = (LoginDTO)request.getAttribute("loginDTO");
String userid = dto.getUserid();
String passwd = dto.getPasswd();
%>
<body>
login1.jsp<br>
id: <%=userid %><br>
pw: <%=passwd %><br>
${loginDTO.userid}
<hr>
el태그 \${dto.userid}: ${dto.userid}<br>
el태그의 특징: 바인딩 된 값만 사용한다.
</body>
</html>


login3.jsp

<%@page import="com.dto.LoginDTO"%>
<%@ 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>
<%
// 								key가 없을 경우 소문자 Class이름이 key값
LoginDTO dto = (LoginDTO)request.getAttribute("xxx");
String userid = dto.getUserid();
String passwd = dto.getPasswd();
%>
<body>
login1.jsp<br><br>
getAtt id: <%=userid %><br>
getAtt pw: <%=passwd %><br>
<hr>
el태그 \${xxx.userid}: ${xxx.userid}<br>
el태그 \${xxx.passwd}: ${xxx.passwd}
<hr>
el태그 \${loginDTO.userid}: ${loginDTO.userid}<br>
el태그 \${loginDTO.passwd}: ${loginDTO.passwd}
</body>
</html>


key값을 지정하면 자동으로 지정되는 key값 맨 앞이 소문자인 클래스이름은 지정되지 않는다.




😮Model함수의 매개변수로 받기

package com.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class TestController {
	
	//Model 함수의 매개변수로 받기
	//Model.addAttrivute(key/value) == request.setAttribute
	@RequestMapping(value ="/aaa", method = RequestMethod.GET)
	public String xxx(Model m) {
		m.addAttribute("username","홍길동");	//request.setAttribute와 동일 => req.getAtt로 사용
		return "main";
	}
	
	@RequestMapping(value = "/bbb", method = RequestMethod.GET)
	public String xxx2(Map<String, String> map) {
		map.put("address", "서울");
		map.put("username", "홍길동");
		return "main2";
	}
	
	@RequestMapping(value ="/ccc", method = RequestMethod.GET)
	public String xxx3(HttpServletRequest request) {
		request.setAttribute("username", "홍길동");
		return "main";
	}
	
	//1. Model 2.객체  3.request
}

리턴 타입

package com.controller;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.dto.LoginDTO;

@Controller
public class TestController {
	
	//1. 리턴타입 String => 뷰만알려줌
	@RequestMapping(value = "/aaa", method = RequestMethod.GET)
	public String aaa() {
		System.out.println("aaa()함수 실행");
		return "main";
	}
	
	
	//1-2. redirect: 매핑 주소로 새로운 요청, 매핑주소의 return 페이지가 응답페이지가 됨 
	@RequestMapping(value = "/hhh", method = RequestMethod.GET)
	public String hhh() {
		System.out.println("/hhh ===============");
		return "redirect:aaa";	//redirect시 request.setAtt 사용이 안됨
	}
	
	@RequestMapping("/bbb")
	public ModelAndView mav() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("username", "홍길동");
		mav.setViewName("main2");
		return mav;
	}
	
	@RequestMapping(value ="/ccc", method = RequestMethod.GET)
	public LoginDTO xxx() {
		System.out.println("/ccc ===========");
		LoginDTO dto = new LoginDTO("홍길동", "1234");
		return dto;
	}
	
	@RequestMapping(value ="/ddd", method = RequestMethod.GET)
	@ModelAttribute("xxx")
	public LoginDTO xxx2() {
		System.out.println("/ddd ===========");
		LoginDTO dto = new LoginDTO("홍길동", "1234");
		return dto;
	}
	
	@RequestMapping(value ="/eee", method = RequestMethod.GET)
	@ModelAttribute("yyy")
	public ArrayList<String> eee(){
		System.out.println("/eee ===========");
		ArrayList<String> list = new ArrayList<String>();
		list.add("홍길동1");
		list.add("홍길동2");
		list.add("홍길동3");
		return list;	// eee.jsp 키값은 yyy
	}
	
	@RequestMapping(value="/fff", method=RequestMethod.GET)
	public void fff(HttpServletRequest request) {
		request.setAttribute("username", "홍길동");
		System.out.println("/fff ==============");
	}
	
	@RequestMapping(value="/ggg", method = RequestMethod.GET)
	public void ggg(Model m) {
		m.addAttribute("username", "홍길동");
		System.out.println("/ggg=========");
	}
	
}



Exception처리

1번방법: 컨트롤러에서 직접 ExceptionHandler 어노테이션이 적용된 함수를 만들고 jsp파일에서 맨 위 상단에 isErrorPage="true"를 써준다.

package com.controller;

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

@Controller
public class TestController {
	
	
	@RequestMapping("/aaa")
	public String xxx() {
		if(true) throw new ArithmeticException("ArithmeticException발생---------");
		//Ex발생 후 진행이 안됨
		return "main";
	}
	
	@RequestMapping("/bbb")
	public String bbb() {
		if(true) throw new NullPointerException("NullPointerException발생---------");
		//Ex발생 후 진행이 안됨
		return "main";
	}
	
//	@ExceptionHandler({ArithmeticException.class, NullPointerException.class})
	@ExceptionHandler({Exception.class})
	public String errorPage() {
		return "error";	//에러처리 페이지로 이동 => error.jsp, Exception객체가 전달됨
	}
}

error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<!--     isErrorPage='true' 지정 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
error.jsp<br>
isErrorPage = "true"설정<br>
<%= exception.getMessage() %><br>
<% out.print(exception.getMessage()); %>
</body>
</html>

2번방법: servlet-context.xml에서 예외처리를 한다.

<!-- Exception의 처리 -->
	<beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<beans:property name="exceptionMappings">
			<beans:props>
				<beans:prop key="java.Lang.ArithmeticExcetion">error</beans:prop>	<!-- error.jsp -->
				<beans:prop key="java.Lang.NullPointerExcetion">error</beans:prop>  <!-- error.jsp -->
			</beans:props>
		</beans:property>
	</beans:bean>



URL Mapping

URL을 매핑시키는 다양한 방법들

package com.controller;

import javax.servlet.http.HttpServletRequest;

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

@Controller
public class TestController {
	
	@RequestMapping("/")
	public String main() {
		return "main";
	}
	
	@RequestMapping("/aaa")
	public String aaa() {
		System.out.println("aaa호출 =========");
		return "main";
	}
	
	//2. 매핑값 여러개
	@RequestMapping(value= {"/aaa2", "/aaa3"})
	public String aaa2() {
		System.out.println("aaa2=========");
		return "main";
	}
	
	//3. bbb로 시작하는 요청 /bbba /bbbcccc
	@RequestMapping(value = "/bbb*", method = RequestMethod.GET)
	public String aaa3() {
		System.out.println("aaa3=========");
		return "main";
	}
	
	//4. *는 하나의 문자열 ccc/zzz, ccc/bbb, ccc/bbb/zzz - 안됨
	@RequestMapping(value = "/ccc/*", method = RequestMethod.GET)
	public String aaa4() {
		System.out.println("aaa4=========");
		return "main";
	}
	
	//5. **는 여러경로 가능 ddd/zzz, ddd/zzz/aaa
	@RequestMapping(value = "/ddd/**", method = RequestMethod.GET)
	public String aaa5() {
		System.out.println("aaa5=========");
		return "main";
	}
	
	//6. **는 여러 경로 가능
	@RequestMapping(value = "/eee/**/aaa", method = RequestMethod.GET)
	public String aaa6() {
		System.out.println("aaa6=========");
		return "main";
	}
	
	//7. pathvariable
	//http://localhost:8080/app/hhh/tester/xxx/1234
	@RequestMapping(value = "hhh/{userid}/xxx/{passwd}", method = RequestMethod.GET)
	public String aaa7(@PathVariable("userid") String userid, @PathVariable("passwd") String passwd) {
		System.out.println("aaa7=========");
		System.out.println(userid+"\t"+passwd);
		return "main";
	}
	
	@RequestMapping("/ggg")
	public String ggg(HttpServletRequest request) {
		System.out.println(request.getParameter("id"));
		return "main";
	}
	
	@RequestMapping("/ggg2/{id}")
	public String ggg2(@PathVariable("id") String id) {
		System.out.println("ggg2호출===========");
		System.out.println(id);
		return "main";
	}
	
	@RequestMapping("/kkk")
	public String kkk(HttpServletRequest request) {
		System.out.println(request.getParameter("id"));
		System.out.println(request.getParameter("pass"));
		return "main";
	}
	
	@RequestMapping("/kkk2/{id}/{pass}")
	public String kkk2(@PathVariable("id") String id,@PathVariable("pass") String pass ) {
		System.out.println(id);
		System.out.println(pass);
		return "main";
	}
}



Redirect_forward

redirect와 forward의 비교

package com.controller;

import javax.servlet.http.HttpServletRequest;

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 com.dto.LoginDTO;

@Controller
public class TestController {
	
	@RequestMapping(value = "/main", method = RequestMethod.GET)
	public String main() {
		System.out.println("main=========");
		return "main";
	}
	
//	1. redirect시 request.getParameter("userid") //파라미터로 데이터 전송됨
	@RequestMapping(value = "/redirect", method = RequestMethod.GET)
	public String redirect(Model m, HttpServletRequest request) {
		System.out.println("redirect=========");
//		m.addAttribute("userid","홍길동");	//url에 파라미터로 전송
		request.setAttribute("passwd","1234");	//전달되지 않음
//		return "redirect:main";		//main으로 redirect
		return "redirect:main?userid=aaa&passwd=1234";	//main으로 redirect
	}

	//	1. forward시 request.getAttribute("userid") //getParameter 사용안됨
	@RequestMapping(value = "/forward", method = RequestMethod.GET)
	public String forward(Model m, HttpServletRequest request) {
		System.out.println("forward=========");
		m.addAttribute("userid","홍길동");	//url에 파라미터로 전송
		request.setAttribute("passwd","1234");	//전달되지 않음
		return "forward:main";	//main으로 forward
//		return "main";
	}
	
	@RequestMapping(value = "/main2", method = RequestMethod.GET)
	public String main2(String userid, String passwd) {
		System.out.println("main2=========");
		System.out.println(userid+"\t"+passwd);
		return "test";
	}

	@RequestMapping(value = "/main3", method = RequestMethod.GET)
	public String main2(LoginDTO dto) {
		System.out.println("main3=========");
		System.out.println(dto);
		return "test";
	}
	
	@RequestMapping(value = "/redirect2", method = RequestMethod.GET)
	public String redirect2(Model m, HttpServletRequest request) {
//		return "redirect:main2?userid=aaa&passwd=1234";
		return "redirect:main3?userid=aaa&passwd=1234";
	}
	
	
}



Redirect_flash

<annotation-driven />을 필수적으로 요구한다.

package com.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class TestController {
	
	@RequestMapping(value = "/main", method = RequestMethod.GET)
	public String main() {
		return "main";
	}
	//redirect-flash를 사용하려면
	//servlet-context.xml에서 <mvc:annotation-driven />이 필요하다.
	@RequestMapping(value="/flash", method = RequestMethod.GET)
	public String redirectFlash(RedirectAttributes m) {
		System.out.println("redirectFlash 호출========");
		m.addFlashAttribute("userid", "홍길동");
//		request.setAttr과 동일
		
//		<mvc:annotation-driven />필요함
//		request.getAttrivbute사용. getParameter안됨
		return "redirect:main";	//request가 redirect전달됨
	}
}



Handler Interceptor

1개의 댓글

comment-user-thumbnail
2023년 8월 6일

좋은 정보 감사합니다

답글 달기