AuthorMapper.java에 구현된 메서드에 대해서는 테스트를 진행하였고 AuthorService.java의 메서드에 대해서는 작성은 하였지만 테스트를 하지 않았다. 그에 대한 테스트도 진행하려 한다.src/test/java경로에 com.store.service패키지를 생성한 뒤 AuthorServiceTests.java 클래스를 생성한다.package com.store.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.store.model.AuthorVO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file/src/main/webapp/WEB-INF/spring/root-context.xml")
public class AuthorServiceTests {
	
	/* AuthorService 의존성 주입 */
	@Autowired
	private AuthorService service;
	
	@Test
	public void authorEnrollTest() throws Exception {
		
		AuthorVO author = new AuthorVO();
		
		author.setNationId("01");
		author.setAuthorName("테스트");
		author.setAuthorIntro("테스트 소개");
		
		service.authorEnroll(author);
	}
}
package com.store.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.store.model.AuthorVO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml") // 수정
public class AuthorServiceTests {
	
	/* AuthorService 의존성 주입 */
	@Autowired
	private AuthorService service;
	
	@Test
	public void authorEnrollTest() throws Exception {
		
		AuthorVO author = new AuthorVO();
		
		author.setNationId("01");
		author.setAuthorName("테스트");
		author.setAuthorIntro("테스트 소개");
		
		service.authorEnroll(author);
	}
}
 

AuthorService.java 인터페이스를 의존성 주입해주는 코드를 추가한다.@Controller
@RequestMapping("/admin")
public class AdminController {
	
	private static final Logger logger = LoggerFactory.getLogger(AdminController.class);
	
	@Autowired
	private AuthorService authorService;
authorEnroll.do인 POST방식의 url매핑 메서드를 추가한다.BoardVO타입 변수 RedirectAttributes타입 변수를 추가하였다.BoardVO객체는 뷰가 전송하는 작가 관련 데이터를 받기 위해서이다.RedirectAttributes 객체는 해당 메서드가 종료된 뒤 리다이렉트 방식으로 다른 페이지로 전송할 때 성공 메시지를 전송하기 위해서 추가했다.(리다이렉트 방식으로 이동할 때 데이터 전송을 위해 사용되는 Model 객체라고 생각하면 됨)package com.store.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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;
import com.store.model.AuthorVO;
import com.store.service.AuthorService;
@Controller
@RequestMapping("/admin")
public class AdminController {
	
	private static final Logger logger = LoggerFactory.getLogger(AdminController.class);
	
	@Autowired
	private AuthorService authorService;
	
	/* 관리자 메인 페이지 이동 */
	@RequestMapping(value = "main", method = RequestMethod.GET)
	public void adminMainGET() throws Exception {
		
		logger.info("관리자 페이지 이동");
	}
	
	
	/* 상품 관리 페이지 접속 */
	@RequestMapping(value = "goodsManage", method = RequestMethod.GET)
	public void goodsManageGET() throws Exception {
		logger.info(">>>>>>>>>> 상품 관리 페이지 접속");
	}
	
	/* 상품 등록 페이지 접속 */
	@RequestMapping(value = "goodsEnroll", method = RequestMethod.GET)
	public void goodsEnrollGET() throws Exception {
		logger.info(">>>>>>>>>> 상품 등록 페이지 접속");
	}
	
	/* 작가 관리 페이지 접속 */
	@RequestMapping(value = "authorManage", method = RequestMethod.GET)
	public void anthorManageGET() throws Exception {
		logger.info(">>>>>>>>>> 작가 관리 페이지 접속");
	}
	
	/* 작가 등록 페이지 접속 */
	@RequestMapping(value = "authorEnroll", method = RequestMethod.GET)
	public void authorEnrollGET() throws Exception {
		logger.info(">>>>>>>>>> 작가 등록 페이지 접속");
	}
	
	/* 작가등록 */
	@RequestMapping(value = "authorEnroll.do", method = RequestMethod.POST)
	public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception {
		
	}
	
}
	/* 작가등록 */
	@RequestMapping(value = "authorEnroll.do", method = RequestMethod.POST)
	public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception {
		
		logger.info("authorEnroll : " + author);
	}
AuthorService.java의 authorEnroll메서드를 호출한다. 뷰로부터 전달받은 등록할 작가 정보가 담긴 BoardVO변수를 매개변수로 작성한다.	/* 작가등록 */
	@RequestMapping(value = "authorEnroll.do", method = RequestMethod.POST)
	public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception {
		
		logger.info("authorEnroll : " + author);
		
		authorService.authorEnroll(author); // 작가 등록 쿼리 수행
	}
	/* 작가등록 */
	@RequestMapping(value = "authorEnroll.do", method = RequestMethod.POST)
	public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception {
		
		logger.info("authorEnroll : " + author);
		
		authorService.authorEnroll(author); // 작가 등록 쿼리 수행
		
		return "redirect:/admin/authorManage";
	}
addFlashAttribute메서드를 사용하였다.addFlashAttribute메서드를 사용하였다.	/* 작가등록 */
	@RequestMapping(value = "authorEnroll.do", method = RequestMethod.POST)
	public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception {
		
		logger.info("authorEnroll : " + author);
		
		authorService.authorEnroll(author); // 작가 등록 쿼리 수행
		
		rttr.addFlashAttribute("enroll_result", author.getAuthorName()); // 등록 성공 메시지(작가이름)
		
		return "redirect:/admin/authorManage";
	}
admin_content_subject인 <div>태그 바로 아래에 작가 정보를 작성하고 전송할 수 있는 버튼이 있는 태그 코드들을 추가하였다.<%@ 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>
<link rel="stylesheet" href="../resources/css/admin/authorEnroll.css">
 
<script
  src="https://code.jquery.com/jquery-3.4.1.js"
  integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
  crossorigin="anonymous"></script>
</head>
</head>
<body>
 
    <div class="wrapper">
        <div class="wrap">
            <!-- gnv_area -->    
            <div class="top_gnb_area">
                <ul class="list">    
                    <li><a href="/main">메인 페이지</a></li>
                    <li><a href="/member/logout.do">로그아웃</a></li>
                    <li>고객센터</li>            
                </ul>
            </div>
            <!-- top_subject_area -->
            <div class="admin_top_wrap">
                <span>관리자 페이지</span>
                
            </div>
            <!-- contents-area -->
            <div class="admin_wrap">
                <!-- 네비영역 -->
                <div class="admin_navi_wrap">
                  <ul>
                      <li >
                          <a class="admin_list_01" href="/admin/goodsEnroll">상품 등록</a>
                      </li>
                      <li>
                          <a class="admin_list_02" href="/admin/goodsManage">상품 관리</a>
                      </li>
                      <lI>
                          <a class="admin_list_03" href="/admin/authorEnroll">작가 등록</a>                            
                      </lI>
                      <lI>
                          <a class="admin_list_04" href="/admin/authorManage">작가 관리</a>                            
                      </lI>
                      <lI>
                          <a class="admin_list_05">회원 관리</a>                            
                      </lI>                                                                                             
                  </ul>
                </div>
                <div class="admin_content_wrap">
                    <div class="admin_content_subject"><span>작가 등록</span></div>
                    <!-- 작가 정보 작성 및 전송 코드 추가 -->
                    <div class="admin_content_main">
                    	<form action="/admin/authorEnroll.do" method="post" id="enrollForm">
                    		<div class="form_section">
                    			<div class="form_section_title">
                    				<label>작가 이름</label>
                    			</div>
                    			<div class="form_section_content">
                    				<input name="authorName">
                    			</div>
                    		</div>
                    		<div class="form_section">
                    			<div class="form_section_title">
                    				<label>소속 국가</label>
                    			</div>
                    			<div class="form_section_content">
                    				<select name="nationId">
                    					<option value="none" selected>=== 선택 ===</option>
                    					<option value="01">국내</option>
                    					<option value="02">국외</option>
                    				</select>
                    			</div>
                    		</div>
                    		<div class="form_section">
                    			<div class="form_section_title">
                    				<label>작가소개</label>
                    			</div>
                    			<div class="form_section_content">
                    				<input name="authorIntro" type="text">
                    			</div>
                    		</div>
                   		</form>
                   			<div class="btn_section">
                   				<button id="cancelBtn" class="btn">취 소</button>
	                    		<button id="enrollBtn" class="btn enroll_btn">등 록</button>
	                    	</div> 
                    </div>
                    <!-- 작가 정보 작성 및 전송 코드 추가 -->
                </div>
                <div class="clearfix"></div>
            </div>
        
        <!-- Footer 영역 -->
        <div class="footer_nav">
            <div class="footer_nav_container">
                <ul>
                    <li>회사소개</li>
                    <span class="line">|</span>
                    <li>이용약관</li>
                    <span class="line">|</span>
                    <li>고객센터</li>
                    <span class="line">|</span>
                    <li>광고문의</li>
                    <span class="line">|</span>
                    <li>채용정보</li>
                    <span class="line">|</span>
                </ul>
            </div>
        </div> <!-- class="footer_nav" -->
        
        <div class="footer">
            <div class="footer_container">
                
                <div class="footer_left">
                    <img src="../resources/img/Logo.png">
                </div>
                <div class="footer_right">
                    (주) 이름없는 회사    대표이사 : OOO
                    <br>
                    사업자등록번호 : ooo-oo-ooooo
                    <br>
                    대표전화 : oooo-oooo(발신자 부담전화)
                    <br>
                    <br>
                    COPYRIGHT(C) <strong>yoonbitnara.github.io</strong>    ALL RIGHTS RESERVED.
                </div>
                <div class="clearfix"></div>
            </div>
        </div> <!-- class="footer" -->        
        
    </div>    <!-- class="wrap" -->
</div>    <!-- class="wrapper" -->
 
</body>
</html>

<form action="/admin/authorEnroll.do" method="post" id="enrollForm">
 
</form>
<input>, <select>태그의 name 속성 값이 일치하도록 작성해야 한다. 일치하지 않으면 데이터는 서버로 전송되지 않는다.<input name="authorName">
    <select name="nationId">
    <input name="authorIntro" type="text">
<input>을 사용하지 않고 <select>를 사용하였다. 국내, 국외 두 정보중 한 가지를 선택하도록 강제하기 위해 <select>를 사용하였다.<select name="nationId">
	<option value="none" selected>=== 선택 ===</option>
	<option value="01">국내</option>
	<option value="02">국외</option>
</select>
<script>
/* 등록버튼 */
$("#enrollBtn").click(function(){
	$("#enrollForm").submit();
});
/* 취소버튼 */
$("#cancelBtn").click(function() {
	location.href="/admin/authorManage";
});
</script>
enroll_result)를 전송하였다. 이 데이터를 활용하여 성공을 알리는 경고창을 띄우는 코드를 작성한다.authorManage.jsp하단에 <script>태그를 추가 후 페이지가 로드될 때 반드시 실행이 되는 익명 함수를 추가한다.<script>
$(document).ready(function() {
	
});
</script>
$(document).ready(function() {
	
	let result = "${enroll_result}";
	
	checkResult(result);
	
	function checkResult(result) {
		
		if (result == "") {
			
			return;
		}
	alert("작가'${enroll_result}' 님을 등록하였습니다.");
	}
	
});
${enroll_result}는 사용자가 작성한 값이 그대로 전송되기 때문에 XSS 공격과 같이 스크립트 코드를 주입시키는 웹사이트 공격에 취약할 수 있다.${enroll_result}는 작가 등록 때 작성한 작가 이름인데 사용자가 <script>alert('공격');</script>을 작가 이름에 작성을 한다면 작가 관리 페이지에 alert문이 실행될 수 있다.<c:out>을 사용하는 방법이다.<c:out>는 변수의 내용을 출력할 때 사용되는 태그인데 해당 태그에 HTML문자를 escape하는 기능이 있기 때문이다.${enroll_result}에 <c:out>을 적용시키고자 한다. 먼저 JSTL 라이브러리 코드를 추가한다.<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
${enroll_result}를 <c:out> 태그를 적용 한다.	// 변경 전
    let result = "${enroll_result}";
 
    // 변경 후
    let result = '<c:out value="${enroll_result}"/>';




