일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Bcrypt
- 스프링 프로젝트 기본 설정
- spring 쇼핑몰
- 스프링 HikariCP
- 쇼핑몰 프로젝트
- 로그인 기능
- 스프링 파일 삭제
- oracle 설치방법
- 스프링 메일 전송
- 스프링 프로젝트
- 정규표현식
- 스프링 게시판 구현
- ResponseEntity
- 스프링 이미지
- 회원가입 기능
- 스프링 포트폴리오
- spring 프로젝트
- 파일 업로드
- BCrypt 적용
- 로그아웃 기능 구현
- 스프링 업로드
- 이미지 출력
- 삭제 구현
- 쇼핑몰 포트폴리오
- 인증번호 전송
- 스프링 프로젝트 설정
- 스프링 게시판
- 스프링 쇼핑몰
- 스프링 쇼핑몰 프로젝트
- arraylist
- Today
- Total
Kim VamPa
[Spring][쇼핑몰 프로젝트][14] 작가등록 기능 구현 -2 본문
프로젝트 Github : https://github.com/sjinjin7/Blog_Project
프로젝트 포스팅 색인(index) : https://kimvampa.tistory.com/188
목표
작가 등록 기능 구현 위한 '제어 계층(Controller Layer)', '프레젠테이션 계층(Presentation Layer)' 작업
작가 등록 기능 구현을 위해서 저번 포스팅에이어서 이번 포스팅에서는 '제어 계층', '프레젠테이션 계층' 작업을 하고자 합니다.
제어 계층 => AuthorController.java 작성
- 뷰(View)로부터의 요청 처리하는 url 맵핑 메서드 작성
프리젠테이션 계층 => authorEnroll.jsp 계층
- 작가 등록에 사용될 데이터를 입력 및 전송할 수 있도록 작성
순서
0. 서비스 단계 테스트
1. url 매핑 메서드 추가 (AdminController.java)
2. 뷰(View) 작성(authorEnroll.jsp)
3. 버튼 작동 스크립트 추가(authorEnroll.jsp)
4. 작가 등록 성공 경고창(authorManage.jsp)
5. 테스트
0. AutherService.java 테스트
저번 포스팅에서 AuthorMapper.java에 구현된 메서드에 대해서는 테스트를 진행하였지만, AuthorMapper.java의 메서드에 대해서는 작성은 하였지만 테스트를 하지 않았습니다. 그에 대한 테스트도 진행하겠습니다.
하나하나 모두 테스트 하는것이 많이 번거롭지만, 오류가 발생했을 때 오히려 시간을 줄여주는 큰 역할을 하기 때문에 되도록이면 기능을 구현했을 때 바로바로 테스트를 해주는 것이 좋습니다.
src/test/java 경로에 com.vam.service 패키지를 생성한 뒤 AuthorServiceTests.java 클래스를 생성합니다.
AuthorService.java 인터페이스의 authorEnroll 메서드를 테스트하기위해서 아래의 코드를 작성한 뒤 Junit 테스트를 진행합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class AuthorServiceTests {
/*AuthoreService 의존성 주입*/
@Autowired
private AuthorService service;
@Test
public void authorEnrollTest() throws Exception {
AuthorVO author = new AuthorVO();
author.setNationId("01");
author.setAuthorName("테스트");
author.setAuthorIntro("테스트 소개");
service.authorEnroll(author);
}
}
|
1. url 매핑 메서드 추가 (AdminController.java)
먼저 AuthorService.java 인터페이스를 의존성 주입해주는 코드를 추가합니다.
1
2
3
4
|
@Autowired
private AuthorService authorService;
|
url이 "authorEnroll.do" 인 POST방식의 URL매핑 메서드를 추가합니다. 파라미터로는 BoardVO타입 변수 RedirectAttributes타입 변수를 추가하였습니다.
- BoardVO 객체는 뷰(View)가 전송하는 작가 관련 데이터를 받기 위해서입니다.
- RedirectAttributes 객체는 해당 메서드가 종료된 뒤 리다이렉트 방식으로 다른 페이지로 전송할 때 성공 메시지를 전송하기 위해서 추가하였습니다. (리다이렉트 방식으로 이동할 때 데이터 전송을 위해 사용되는 Model 객체라고 생각하시면 됩니다. )
1
2
3
4
5
6
|
@RequestMapping(value="authorEnroll.do", method = RequestMethod.POST)
public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception{
}
|
추가한 메서드 구현부에 먼저 해당 메서드에 들어온 기록과 뷰(View)로부터 전달받은 데이터를 확인하기 위한 로그 코드를 추가하였습니다.
1
2
3
4
5
6
7
8
9
|
/* 작가 등록 */
@RequestMapping(value="authorEnroll.do", method = RequestMethod.POST)
public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception{
logger.info("authorEnroll :" + author);
}
|
작가등록 쿼리를 수행하는 mapper메서드를 호출하는 AuthorService.java의 authorEnroll메서드를 호출합니다. 뷰(View)로부터 전달받은 등록할 작가 정보가 담긴 BoardVO 변수를 매개변수로 작성합니다.
1
2
3
4
5
6
7
8
9
10
11
|
/* 작가 등록 */
@RequestMapping(value="authorEnroll.do", method = RequestMethod.POST)
public String authorEnrollPOST(AuthorVO author, RedirectAttributes rttr) throws Exception{
logger.info("authorEnroll :" + author);
authorService.authorEnroll(author); // 작가 등록 쿼리 수행
}
|
리다이렉트 방식으로 작가 목록 페이지로 이동하도록 리턴값을 추가해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/* 작가 등록 */
@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";
}
|
작가등록이 성공적으로 완료되었음을 알리는 데이터를 전송해주는 코드를 추가합니다. 경고창 메시지에 등록된 작가 이름을 표시하기 위해서 등록이 완료된 '작가 이름' 데이터를 전송하였습니다. 뷰(View)로 전송된 데이터가 일회성으로 사용되도록 addFlashAttriubte 메서드를 사용하였습니다.
작가 등록 성공후 이동할 페이지가 [작가 관리] 페이지인데, 해당 페이지가 로드될 때마다 서버로부터 전송받은 '성공 여부 데이터'를 존재 여부를 체크하여 존재할 시 작가 등록에 성공하였다는 경고창을 뜨도록 할 것입니다. 그런데 만약 서버로부터 전송된 데이터가 계속 남아있다면 해당 경고창은 계속 나타날 것입니다. 이러한 일을 방지하고자 데이터가 일회성으로 사용될 수 있도록 addFlashAttribute 메서드를 사용하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/* 작가 등록 */
@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";
}
|
2. 뷰(View) 작성(/admin/authorEnroll.jsp)
class 속성 값 'admin_content_subject'인 <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>
조심해야 할 몇몇 태그만 살펴보겠습니다.
먼저 form태그입니다. action 속성 값에 작가등록 기능을 수행하는 url을 작성하였고, 해당 url 매핑 메서드가 POST방식이기 때문에 method 속성 값을 POST를 작성하였습니다.
1
2
3
4
5
|
<form action="/admin/authorEnroll.do" method="post" id="enrollForm">
</form>
|
작가 등록 기능을 수행하는 url 매핑 메서드가 작가 등록에 사용할 데이터를 AuthorVO객체를 파라미터로 전달 받기 때문에 AuthorVO클래스에 정의한 변수 이름과 authorEnroll.jsp 에 정보가 입력될 <input><select> 태그의 name 속성 값이 일치하도록 작성해야 합니다. 일치하지 않는다면 데이터는 서버로 전송되지 않습니다.
1
2
3
4
|
<input name="authorName">
<select name="nationId">
<input name="authorIntro" type="text">
|
소속 국가 정보를 입력할때 <input>을 사용하지 않고 <select>를 사용하였습니다. '국내', '국외' 두 정보중 한 가지를 선택하도록 강제하기 위해서 <select>를 사용하였습니다.
1
2
3
4
5
6
7
|
<select name="nationId">
<option value="none" selected>=== 선택 ===</option>
<option value="01">국내</option>
<option value="02">국외</option>
</select>
|
3. 버튼 작동 스크립트 추가(authorEnroll.jsp)
'취소' 버튼과 '작가 등록'버튼 두개가 있습니다. 두 개의 버튼이 작동되도록 스크립트 코드를 작성하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script>
/* 등록 버튼 */
$("#enrollBtn").click(function(){
$("#enrollForm").submit();
});
/* 취소 버튼 */
$("#cancelBtn").click(function(){
location.href="/admin/authorManage"
});
</script>
|
'취소' 버튼을 누르면 작가 관리 페이지(authorManage.jsp)로 이동하도록 하였고, '등록' 버튼을 누르면 작가 등록 기능이 실행되도록 작성하였습니다.
4. 작가 등록 성공 경고창(authorManage.jsp)
앞서 [1. url 매핑 메서드 추가]에서 작가 등록을 수행 후 '작가 관리'페이지에 이동함과 동시에 등록이 성공하였음을 알리는 데이터("enroll_result")를 전송하엿습니다. 이 데이터를 활용하여 성공을 알리는 경고창을 띄우는 코드를 작성합니다.
authorManage.jsp 하단에 <script> 태그를 추가 후 페이지가 로드될 때 반드시 실행이 되는 익명 함수를 추가합니다.
1
2
3
4
5
6
7
8
|
<script>
$(document).ready(function(){
});
</script>
|
함수 구현부에 서버에서 전송되는 데이터를 체크 후, 존재 할 시에 작가 등록 성공 메시지를 알리는 경고창을 띄우는 코드를 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<script>
$(document).ready(function(){
let result = "${enroll_result}";
checkResult(result);
function checkResult(result){
if(result === ''){
return;
}
alert("작가'${enroll_result}' 을 등록하였습니다.");
}
});
</script>
|
작성한 코드 그대로 사용하더라도 정상적으로 작동을 하지만 ${enroll_result} 는 사용자가 작성한 값을 그대로 전송되기 때문에 XSS 공격과 같이 스크립트 코드를 주입시키는 웹사이트 공격에 취할 수 있습니다. 예를 들면 ${enroll_result}는 작가 등록 때 작성한 작가 이름인데, 사용자가 <script> alert('공격');</script>을 작가 이름에 작성을 한다면 '작가 관리(authorManage)' 페이지에 alsert() 문이 실행될 수 있습니다.
이를 방지하기 위해서 작가이름 작성을 할 때 유효성 검사를 통해 스크립트 코드를 작성하지 못하도록 할 수도 있습니다. 더불어 스크립트 코드가 입력되더라도 출력되는 값(${})에도 스크립트 코드가 실행이 되지 않도록 할 수 있는 방법이 있는데 JSTL의 <c:out>을 사용하는 방법입니다. <c:out>는 변수의 내용을 출력할 때 사용되는 태그인데 해당 태그에 HTML 문자를 탈락(escpae)시키는 기능이 있기 때문입니다.
따라서 표현언어(EL)인 "${enroll_result}"에 <c:out>을 적용시키고자 합니다. 먼저 JSTL 라이브러리 코드를 추가합니다.
1
2
3
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
기존 ${enroll_result}를 <c:out> 태그를 적용 합니다.
1
2
3
4
5
6
7
|
// 변경 전
let result = "${enroll_result}";
// 변경 후
let result = '<c:out value="${enroll_result}"/>';
|
5. 테스트
5.1 취소 버튼 테스트
취소 버튼을 눌러서 정상적으로 '작가 관리(authorManage.jsp)'로 이동하는지를 확인합니다.
5.2 등록 테스트
다음 3가지가 정상적으로 구현되는지를 확인합니다.
1) 작가 정보 데이터베이스 등록
2) '작가 관리(authorManage.jsp)' 페이지 이동
3) 등록 성공 경고창 확인
REFERENCE
DATE
- 2020.02.09
'스프링 프레임워크 > 쇼핑몰 프로젝트' 카테고리의 다른 글
[Spring][쇼핑몰 프로젝트][15] 작가목록 기능 구현 - 1 (0) | 2021.03.10 |
---|---|
[Spring][쇼핑몰 프로젝트][14] 작가등록 기능 구현 - 3 (0) | 2021.02.10 |
[Spring][쇼핑몰 프로젝트][14] 작가등록 기능 구현 -1 (2) | 2021.02.08 |
[Spring][쇼핑몰 프로젝트][13] 작가 테이블 구성 & 기타 작업(로고,footer영역, 관리자 페이지) - 2 (10) | 2021.02.05 |
[Spring][쇼핑몰 프로젝트][13] 작가 테이블 구성 & 기타 작업(로고,footer영역, 관리자 페이지) - 1 (11) | 2021.02.05 |