반응형

 

트랙잭션

 

: 데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위

 

네임스페이스 하나에 스키마(url)가 2개 추가됨

 

 

  • 설정

root-context.xml

상단에 수정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

 

</beans> 안에 추가

   <!-- 트랜잭션 관리자의 빈을 정의 -->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
   </bean>
   
   <!-- 에너테이션 기반의 트랜잭션 제어를 활성화 함 -->
   <tx:annotation-driven/>

 

=> dataSource를 쓰기 위해선 DB 정보가 필요함

더보기

root-context.xml 파일에 추가 되어있어야 함

 

root-context.xml

	<bean id="dataSource" 
	   class="org.apache.commons.dbcp2.BasicDataSource" 
	   destroy-method="close">
	   <property name="driverClassName" 
	   value="oracle.jdbc.driver.OracleDriver" />
	   <property name="url" 
	   value="jdbc:oracle:thin:@localhost:1521:xe" />
	   <property name="username" value="pc10_2" />
	   <property name="password" value="java" />
	</bean>

 

 

 

  • 실습

EmployeeServiceImpl.java

상단에 @Transactional 추가

	//root-context.xml로 인해서 오류 발생 시 롤백을 해줌
	@Transactional
	@Override
	public int createPost(EmployeeVO employeeVO) {
		/*
		EmployeeVO(empNo=A111, empName=김, empAddress=대전 1, empTelno=010-111-2222, empSalary=100, filename=null, 
		licenseVOList=[
			LicenseVO(empNo=null, licNo=A1111, licNm=언어영역, licDt=Fri May 03 00:00:00 KST 2024), 
			LicenseVO(empNo=null, licNo=A1112, licNm=수학영역, licDt=Sat May 04 00:00:00 KST 2024)
		])
		 */
		//1) EMPLOYEE 테이블에 insert
		//employeeVO.getUploadFile() : MultipartFile
		int result = this.employeeDao.createPost(employeeVO);
		
		List<LicenseVO> licenseVOList = employeeVO.getLicenseVOList();
		log.info("createPost->licenseVOList : " + licenseVOList);
		
		for (LicenseVO licenseVO : licenseVOList) {
			//2) LicenseVO(empNo=A111, licNo=A1111, licNm=언어영역, licDt=Fri May 03 00:00:00 KST 2024),
			licenseVO.setEmpNo(employeeVO.getEmpNo());
			result += this.employeeDao.insertLicenseVO(licenseVO);
		}
		
		//3) 파일업로드
		MultipartFile uploadFile = employeeVO.getUploadFile();
											// 파일 객체	, attachVO.globalCode
		result += uploadController.uploadOne(uploadFile, employeeVO.getEmpNo());
		
		//4) employeeVO.filename=null
		//글로벌 코드를 조건으로 하여 첫번쨰 첨부파일 객체를 가져옴
		AttachVO attachVO = this.attachDao.getFileName(employeeVO.getEmpNo());
		log.info("attachVO(2) : " + attachVO);
		
		//5) employeeVO.filename을 업데이트
		result += this.employeeDao.updateFileName(attachVO);
		
		return result;
	}

 

 

 

예외처리

 

: 특정한 문제가 일어났을 때 처리를 중단하고 다른 처리를 하는 것

 

상태 코드를 이용하여 오류 페이지 설정을 할 수 있음

 

- 예외 종류

스프링 프레임워크 예외

사용자 정의 예외

의존 라이브러리에서 발생한 예외

시스템 예외

 

 

 

  • HTTP 오류 코드 
오류 코드 설명
400 Bad Request. 문법 오류(잘못 입력한 url)
404* Not Found. 요청한 문서를 찾지 못함(url확인 및 캐시 삭제가 필요한 상태)
405 Method not allowed. 메소드 허용 안됨(메소드 매핑이 안 될 때 발생)
415 서버의 요청에 대한 승인 거부. (ContentType, Content Encoding 데이터 확인 필요)
500* 서버 내부 오류. (웹 서버가 요청사항을 수행할 수 없을 때 발생)
505 HTTP Version Not Supported.

 

 

 

  • 실습

web.xml

상단 변경

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   https://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">

 

</web-app> 안에 추가

	<error-page>
		<error-code>400</error-code>
		<location>/error/error400</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/error/error404</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/error/error500</location>
	</error-page>
	<!-- HTTP 상태 코드를 사용하여 오류 페이지 설정 끝 -->

 

 

ErrorController.java

package kr.or.ddit.utils;

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

@Controller
public class ErrorController {
	
	//요청 URI : /error/error400
	@GetMapping("/error/error400")
	public String error400() {
		//forwarding : jps
		return "error/error400";
	}
	
	//요청 URI : /error/error404
	@GetMapping("/error/error404")
	public String error404() {
		//forwarding : jps
		return "error/error404";
	}
	
	//요청 URI : /error/error500
	@GetMapping("/error/error500")
	public String error500() {
		//forwarding : jps
		return "error/error500";
	}
}

 

 

error400.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="content-wrapper pt-5">
  <section class="content">
    <div class="error-page">
      <h2 class="headline text-warning">400</h2>
      <div class="error-content">
        <h3><i class="fas fa-exclamation-triangle text-warning"></i> Oops! Page not found.</h3>
        <p>
          	잘못된 요청 정보입니다. <a href="{% link index.md %}">return to 메인</a>.
        </p>
      </div>
    </div>
  </section>
</div>

 


error404.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="content-wrapper pt-5">
  <section class="content">
    <div class="error-page">
      <h2 class="headline text-warning">404</h2>
      <div class="error-content">
        <h3><i class="fas fa-exclamation-triangle text-warning"></i> Oops! Page not found.</h3>
        <p>
          	잘못된 요청 정보입니다. <a href="/">return to 메인</a>.
        </p>
      </div>
    </div>
  </section>
</div>

 


error500.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="wrapper">
    <!-- Main content -->
    <section class="content">
      <div class="error-page">
        <h2 class="headline text-danger">500</h2>

        <div class="error-content">
          <h3><i class="fas fa-exclamation-triangle text-danger"></i> Oops! Something went wrong.</h3>

          <p>
            We will work on fixing that right away.
            Meanwhile, you may <a href="/">return to dashboard</a> or try using the search form.
          </p>

          <form class="search-form">
            <div class="input-group">
              <input type="text" name="search" class="form-control" placeholder="Search">

              <div class="input-group-append">
                <button type="submit" name="submit" class="btn btn-danger"><i class="fas fa-search"></i>
                </button>
              </div>
            </div>
            <!-- /.input-group -->
          </form>
        </div>
      </div>
      <!-- /.error-page -->
</div>
<!-- ./wrapper -->

 

결과 화면1 : 404 예시

 

 

LprodController.java

	/*
	요청URI : /lprod/list or /lprod/list?currentPage=2 or /lprod/list?currentPage=
	요청파라미터 : {keyword=개똥이}
	요청방식 : get
	*/
	@RequestMapping(value="/list", method=RequestMethod.GET)
	public ModelAndView list(ModelAndView mav, 
					@RequestParam(value="currentPage", required=false, defaultValue="1") int currentPage, 
					@RequestParam(value="keyword",required=false,defaultValue="") String keyword) {
		log.info("list에 왔다");
		log.info("keyword : " + keyword);
		
		
		System.out.println(10/0);
		
		
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("keyword",keyword);
		map.put("currentPage",currentPage);
		
		//전체 행의 수
		int total = this.lprodService.getTotal(map);
		log.info("list->total : " + total);
		
		//Model(데이터)
		//상품분류 목록
		List<LprodVO> lprodVOList = this.lprodService.list(map);
		log.info("list->lprodVOList : " + lprodVOList);
		
		
		mav.addObject("articlePage", new ArticlePage<LprodVO>(total, currentPage, 10, lprodVOList, keyword));
		
		//View(jsp)
		mav.setViewName("lprod/list");
		
		return mav;
	}

 

결과 화면2

 

 

 

예외 타입을 이용한 에러 페이지 설정

 

: 예외 타입을 확실하게 기입해놓아 에러를 처리하는 방식

 

 

- 설정 방법

1. 웹 컨테이너(tomcat서버) 설정 파일(web.xml)의 exception-type 태그 요소에 예외 타입을 설정

2. 웹 컨테이너(tomcat서버) 설정 파일(web.xml)의 location 요소에 이동 대상 페이지 및 URI를 지정함

IOException, SQLException, NullPointerException, ArrayIndexOutOfBoundsException, ArtimeticException(0으로 나눌경우)

 

 

 

  • 실습

web.xml

</web-app> 안에 추가

	<error-page>
		<exception-type>java.lang.ArithmeticException</exception-type>
		<location>/error/errorException</location>
	</error-page>

 

 

ErrorController.java

하단에 추가

	//요청 URI : /error/errorException
	@GetMapping("/error/errorException")
	public String errorException() {
		//forwarding : jps
		return "error/errorException";
	}

 

 

errorException.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="content-wrapper pt-5">
  <section class="content">
    <div class="error-page">
      <h2 class="headline text-warning">errorException</h2>
      <div class="error-content">
        <h3><i class="fas fa-exclamation-triangle text-warning"></i> Oops! Page not found.</h3>
        <p>
          	숫자를 0으로 나눌 수 없습니다. <a href="/">return to 메인</a>.
        </p>
      </div>
    </div>
  </section>
</div>

 

결과 화면3

 

 

 

  • 기본 오류 페이지 설정

web.xml

	<!-- 기본 오류 페이지 설정 시작 -->
	<error-page>
	   <location>/error/errorDefault</location>
	</error-page>
	<!-- 기본 오류 페이지 설정 시작 -->

 

 

 

예외 처리 애너테이션

 

 

대표적으로 5가지의 종류가 있음

IOException

SQLException

NullPointerException

ArrayIndexOutOfBoundsException

ArithmeticException

 

 

CommonExceptionHandler.java

package kr.or.ddit.exception;

import java.io.IOException;
import java.sql.SQLException;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import lombok.extern.slf4j.Slf4j;

//스프링 컨트롤러에서, 발생하는 예외를 처리하는 핸들러 클래스임을 명시함
//web.xml, errorPage, try~catch.. 말고 컨트롤러에서 처리함
@Slf4j
@ControllerAdvice
public class CommonExceptionHandler {

	//괄호 안에 설정한 예외 타입을 해당 메서드가 처리한다는 의미
	//IOException, SQLException, NullPointerException, 
	//ArrayIndexOutOfBoundsException, ArithmeticException   
	@ExceptionHandler(Exception.class)
	public String handle(Exception e, Model model) {
		log.error("CommonExceptionHandler->handle : " + e.toString());
		
		//예외에 대한 내용을 Model 객체를 이용해서 전달하여 뷰(View) 화면에서 출력이 가능함
		model.addAttribute("exception", e);
		
		//forwarding : jsp
		return "error/errorCommon";
	}
}

 

 

errorCommon.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<p>${exception.getMessage()}</p>
<p>
	<c:forEach var="stack" items="${exception.getStackTrace()}" varStatus="stat">
		<h3>${stack.toString()}</h3>
	</c:forEach>
</p>

 

결과 화면4

 

 


errorCommon.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<section class="content">
   <div class="error-page">
   <!-- model.addAttribute("exception", e); -->
      <h2 class="headline text-warning">${exception.getMessage()}</h2>
      <div class="error-content">
         <c:forEach var="stack" items="${exception.getStackTrace()}" varStatus="stat">
            <h3>
               <i class="fas fa-exclamation-triangle text-warning"></i>${stack.toString()}
            </h3>
         </c:forEach>
         <p>
             만약, 메인으로 이동하고자 하면
            <a href="/">메인</a> 을 클릭해주세요.
         </p>
         <form class="search-form">
            <div class="input-group">
               <input type="text" name="search" class="form-control"
                  placeholder="Search">
               <div class="input-group-append">
                  <button type="submit" name="submit" class="btn btn-warning">
                     <i class="fas fa-search"></i>
                  </button>
               </div>
            </div>

         </form>
      </div>

   </div>

</section>

 

결과 화면5

 

 

 

404 에러 페이지 처리

 

 

404를 프로그래밍적으로 처리하고 싶다면 404 발생 시 예외를 발생시키도록 설정해야 한다. (기본적으로 404는 exception 상황이 아니다.) 

 

=> web.xml에서 DispatcherServlet을 등록할 때 throwExceptionIfNoHandlerFound 초기화 파라미터를 true로 설정

 

 

 

web.xml
servlet-context.xml의 하단 </init-param> 바로 아래에 추가

		<!-- 404오류를 처리할 수 있도록 설정 -->
		<init-param>
			<param-name>throwExceptionIfNoHandlerFound</param-name>
			<param-value>true</param-value>
		</init-param>

 

 

CommonExceptionHandler.java

하단에 추가

	@ExceptionHandler(NoHandlerFoundException.class)
	@ResponseStatus(HttpStatus.NOT_FOUND) // 상태코드가 not found => 404
	public String handle404(Exception e) {
		log.error("CommonExceptionHandle->handle : " + e.toString());
		
		return "error/error404";
	}

 

결과 화면6

 

 

반응형