[Spring][쇼핑몰 프로젝트] 18. 상품 등록(3)

YB·2023년 2월 22일
0

쇼핑몰

목록 보기
28/40
post-thumbnail

목표

'카테고리 리스트'데이터를 뷰(View)로 전송하여, 사용자가 카테고리를 선택할 수 있도록 전송받은 데이터 가공한 뒤 출력하는 방법이 있습니다. 첫 번째는 작가 목록 구현때와 같이 리스트 데이터를 객체 통째로 전달하는 방법으로 뷰에서는 넘겨받은 데이터를 JSTL코드를 통해 조건을 부여하여 출력시킬 수 있을 것입니다. 두 번째 방법은 케터고리 리스트 데이터를 JSON타입으로 변환하여 뷰(view)로 넘기는 것입니다. 뷰(view)에선 Javascript를 통해 전달받은 JSOn타입의 데이터를 가공하여 출력시킬 수 있습니다.

2개의 방법중 JSON타입으로 변환하는 방식으로 구현하고자 합니다. 자바의 객체 데이터를 JSON으로 변환시켜주는 라이브러리 Jackson을 활용할 것입니다.

1. 카테고리 리스트 객체

카테고리 리스트 객체를 DB로부터 호출할 수 있도록 Mapper, Service메서드를 먼저 만들 것입니다. 데이터를 반환받는 방식은 게시판의 모록 데이터를 가져오는 방식처럼 List방식을 사용합니다. 먼저 카테고리 테이블(test_bcate)의 데이터를 저장할 그릇이 VO클래스부터 작성 후 Mapper,Service순으로 작업합니다.

1) CateVO 클래스

com.test.model패키지에 CateVO.java클래스를 생성한 뒤 아래의 변수를 추가하고 Lombok을 사용해 @Getter / @Setter / @ToString을 추가해줍니다.

@Getter
@Setter
@ToString
public class CateVO {
	
	/* 카테고리 등급 */
	private int tier;
	
	/* 카테고리 이름 */
	private String cateName;
	
	/* 카테고리 넘버 */
	private String cateCode;
	
	/* 상위 카테고리 */
	private String cateParent;

}

2) AdminMapper.java

카테고리 리스트 데이터를 요청할 메서드를 작성합니다.

	/* 카테고리 리스트 */
	public List<CateVO> cateList();

3) AdminMapper.xml

AdminMapper 인터페이스에 추가한 메서드가 실행할 쿼리문을 작성합니다. test_bcate테이블의 모든 리스트를 코드번호(catecode) 번호순으로 출력되도록 쿼리문을 작성하였습니다.

	<!-- 카테고리 리스트 -->
	<select id="cateList" resultType="com.test.model.CateVO">
		select * from test_bcate order by catecode
	</select>

4) AdminService.java

추가한 Mapper 메서드를 호출할 메서드 선언부를 작성합니다.

	/* 카테고리 리스트 */
	public List<CateVO> cateList();

5) AdminServiceImpl.java

오버라이딩하여 AdminServiceImpl인터페이스에서 선언한 메서드의 구현부를 완성해줍니다.

	@Override
	public List<CateVO> cateList() {
		
		log.info("(service)cateList......");
		
		return adminMapper.cateList();
	}

6) AdminController.java

우리는 카테고리 리스트 데이터를 'goodsEnroll.jsp'에 전달해주어야하기 때문에 해당 url매핑 메서드에 카테고리 리스트 데이터를 반환하는 Service메서드를 호출하여 'list'에 저장합니다.

List list = adminService.cateList();

2. JSON 데이터 변환

우리는 카테고리 리스트 데이터를 담고 있는 객체인 'list'가 있습니다. 이제 해당 객체를 JSON형식의 String데이터로 변환해야합니다.

1) Jackson-databind 라이브러리 추가

pom.xml에 Jackson-databind라이브러리 코드를 추가해줍니다.

        <!-- JSON변환 Jackson-databind 라이브러리 추가 -->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.12.1</version>
		</dependency>

2) JSON 형식 데이터 변환

우리가 사용할 Jackson-databind의 메서드는 static메서드가 아니기 때문에 바로 사용할 수는 없습니다.

  • ObjectMapper클래스를 인스턴스화하여 사용해야 합니다. 따라서 ObjectMapper타입의 'mapper'변수를 선언한 후 ObjectMapper객체로 초기화합니다.
  • 사용해야 할 메서드는 writeValueAsString()메서드입니다. Java객체를 String타입의 JSON형식 데이터로 변환해줍니다.
  • 뷰(view)로 데이터를 넘겨주기 위해서 url매핑 메서드의 파라미터에 Model을 부여해준 후 addAttribute()를 사용하여 "cateList"속성에 String타입의 'cateList'변수의 값을 저장시킵니다.
	/* 상품 등록 페이지 접속 */
	@RequestMapping(value="goodsEnroll", method=RequestMethod.GET)
	public void goodsManageGET(Model model) throws Exception {
		
		logger.info("상품 등록 페이지 접속");
		
		ObjectMapper objm = new ObjectMapper();
		
		List list = adminService.cateList();
		
		String cateList = objm.writeValueAsString(list);
		
		model.addAttribute("cateList", cateList);
		
	}

3. <select>, <option>태그 추가

카테고리를 출력시킬 기본적인 틀로서 <select>, <option>태그를 추가합니다. '책 카테고리'에 있던 기존의 <input>태그를 지우고 아래의 코드를 삽입합니다.

사용자가 '대분류'를 선택하게 되면 그에 맞는 '중분류'<option>이 세팅이 되고, '중분류'를 선택하면 그에 맞는 '소분류'<option>태그가 세팅하게 됩니다. 그리고 '소분류'를 선택하는 것은 상품 등록에 필요로 한 "cateCode"데이터를 선택하는 것이기 때문에 '소분류'의 <select>태그에 name속성을 부여하였습니다.

			<div class="cate_wrap">
				<span>대분류</span>
				<select class="cate1">
					<option selected value="none">선택</option>
				</select>
			</div>
			<div class="cate_wrap">
				<span>중분류</span>
				<select class="cate2">
					<option selected value="none">선택</option>
				</select>
			</div>
			<div class="cate_wrap">
				<span>소분류</span>
				<select class="cate3" name="cateCode">
					<option selected value="none">선택</option>
				</select>
			</div> 

추가한 태그들에 css설정을 추가해주기 위해 'goodsEnroll.css'파일에 아래의 코드를 추가해줍니다.

.form_section_content select {		/* 카테고리 css 설정 */
    width: 92%;
    height: 35px;
    font-size: 20px;
    text-align-last: center;
    margin-left: 5px;
}
.cate_wrap span {
    font-weight: 600;
}
.cate_wrap:not(:first-child) {
    margin-top: 20px;
}

4. JSON 데이터 변환

현재의 'cateList'객체에는 '대분류', '중분류', '소분류'모두 섞여 있는 상태입니다. 이 객체를 각 등급(tier)에 맞게 분류하여 배열에 저장시킬 것입니다. 각 배열에는 'cateName', 'cateCode', 'cateParent'변수와 그 값을 가지고 있는 객체가 저장될 것입니다.

서버로부터 전달받은 JSON데이터를 Javascript가 바로 사용할 수는 없습니다. JSON데이터를 Javascript객체로 변환해주어야 합니다. Javascript에서는 JSON문자열 데이터를 Javascript객체로 변환해주는 메서드를 제공하고 있습니다.
Javscript객체 변환 메서드

위 링크의 메서드를 활용하여 "cateList" 속성에 담긴 JSON데이터를 객체로 변환해주어 'cateList'변수에 저장합니다.

let cateList = JSON.parse('${cateList}');
  • 9개의 변수를 선언합니다. 각 등급에 사용될 배열, 객체입니다. cateSelct변수는 <select>태그에 쉽게 접근하기 위해 변수로 선언하였습니다.
  • 동일한 형태의 for문을 3번 작성하여야 하기 때문에 for문을 재사용할 수 있도록 메서드화 하였습니다.
  • 작성한 메서드를 활용하여 각 tier의 배열을 모두 초기화시켜줍니다.
/* 카테고리 */
let cateList = JSON.parse('${cateList}');

let cate1Array = new Array();
let cate2Array = new Array();
let cate3Array = new Array();
let cate1Obj = new Object();
let cate2Obj = new Object();
let cate3Obj = new Object();

let cateSelect1 = $(".cate1");		
let cateSelect2 = $(".cate2");
let cateSelect3 = $(".cate3");

/* 카테고리 배열 초기화 메서드 */
function makeCateArray(obj,array,cateList, tier){
	for(let i = 0; i < cateList.length; i++){
		if(cateList[i].tier === tier){
			obj = new Object();
			
			obj.cateName = cateList[i].cateName;
			obj.cateCode = cateList[i].cateCode;
			obj.cateParent = cateList[i].cateParent;
			
			array.push(obj);				
			
		}
	}
}

/* 배열 초기화 */
makeCateArray(cate1Obj,cate1Array,cateList,1);
makeCateArray(cate2Obj,cate2Array,cateList,2);
makeCateArray(cate3Obj,cate3Array,cateList,3);

5. 대분류 <option>

'for'문과 Jquery의 'append'를 이용해서 <select>태그 내부에 <option>태그를 추가해줄 것입니다. <script>태그 내부에 아래의 Javascript코드를 추가합니다.

/* 대분류 <option> 태그 */
for(let i = 0; i < cate1Array.length; i++){
	cateSelect1.append("<option value='"+cate1Array[i].cateCode+"'>" + cate1Array[i].cateName + "</option>");
}

6. 중분류 <option>

메서드 내에서 처리할 작업의 순서는 다음과 같습니다.

대분류 선택값 가져오기
=> 중분류 <option>태그 모두 지우기
=> 중분류 기본 <option>태그 추가
=> 대분류 선택 값과 일치하는 'cateParent'값을 가진 중분류 <option> 태그 출력

굳이 <option>태그를 모두 지우고 다시 추가하는 이유는 사용자가 대분류 선택하고 다시 다른 대분류를 선택했을 때 기존의 <option>태그들을 없애기 위함입니다.

중분류 <select>태그에 <option>태그를 추가되도록 해야 하는데, 대분류의 옵션이 선택되었을 때 출력이 되어야 합니다.

  • 대분류 옵션이 선택되었을 때 실행하는 메서드를 추가합니다.
  • 중분류 <option>태그를 지우고 기본적인 <option>태그를 추가하는 코드를 추가합니다.
  • 대분류 선택 값과 일치하는 'cateParent'값을 가진 중분류 <option>태그를 출력하는 코드를 추가합니다.
/* 중분류 <option> 태그 */
$(cateSelect1).on("change",function(){
	
	let selectVal1 = $(this).find("option:selected").val();	
	
	cateSelect2.children().remove();
	
	cateSelect2.append("<option value='none'>선택</option>");
	
	for(let i = 0; i < cate2Array.length; i++){
		if(selectVal1 === cate2Array[i].cateParent){
			cateSelect2.append("<option value='"+cate2Array[i].cateCode+"'>" + cate2Array[i].cateName + "</option>");	
		}
	}
	
});

7. 소분류 <option>

메서드 내에서 처리할 작업의 순서는 다음과 같습니다.

중분류 선택값 가져오기
=> 소분류 <option>태그 모두 지우기
=> 소분류 기본 <option>태그 추가
=> 중분류 선택 값과 일치하는 'cateParent'값을 가진 소분류 <option> 태그 출력

소분류도 중분류와 동일한 형태의 코드를 작성해야 합니다. 소분류 <option>태그가 출력되어야 할 시점은 중분류를 선택하였을 때입니다.

  • 중분류의 선택 값을 가져오는 코드를 추가합니다.
  • 소분류 <option>태그를 모두 지우고, 기본 <option>태그를 추가하는 코드를 작성합니다.
  • 소분류 <option>을 출력하는 코드를 추가합니다.
/* 소분류 <option>태그 */
$(cateSelect2).on("change",function(){
	
	let selectVal2 = $(this).find("option:selected").val();
	
	cateSelect3.children().remove();
	
	cateSelect3.append("<option value='none'>선택</option>");		
	
	for(let i = 0; i < cate3Array.length; i++){
		if(selectVal2 === cate3Array[i].cateParent){
			cateSelect3.append("<option value='"+cate3Array[i].cateCode+"'>" + cate3Array[i].cateName + "</option>");	
		}
	}
	
});

8. 중분류 메서드 추가 작업

현재의 코드에는 문제가 하나 있습니다. 대분류, 중분류, 소분류 순으로 선택을 한 뒤 다시 대분류를 선택을 하게 되면 중분류는 정상적으로 기존의 코드가 없어지고 기본 <option>태그가 출력이 되는데 소분류는 기존의 <option>태그가 그대로 있습니다.

이는 중분류 선택이 변경되었을 때만 소분류가 초기화되도록 작성하였기 때문입니다. 이를 해결하기 위해선 대분류가 변경되었을 때도 소분류가 초기화 되도록 코드를 추가해주어야합니다. 중분류 <option>태그를 출력하는 메서드에 아래의 코드를 추가해줍니다.

cateSelect3.children().remove();
cateSelect3.append("<option value='none'>선택</option>");

9. 테스트


profile
개인이 공부한걸 작성하는 블로그입니다..

0개의 댓글