16주차 - Spring (15) 키워드로 파일에서 원하는 목록을 찾아보자

2022. 10. 24. 13:49Spring framwork

이번의 목표

01. 디스크에 저장된 JSON파일에서 키워드를 통해 원하는 리스트를 찾아보자.


지난 시간에는 디스크에 저장된 json파일을 화면에 테이블의 형태로 출력하는 것을 공부했습니다.

이번에는 키워드를 검색하고 키워드가 제목에 포함된 리스트만 출력되는 기능을 공부해 보겠습니다.

이전에는 파일의 텍스트를 읽어 하나의 String으로 변환하여 이를 그대로 사용했습니다.

하지만 위의 기능을 구현 하기 위해서는 파일을 읽어오면서 json의 내용을 객체화 시킬 필요가 있습니다.

그러기 위해서 사용되는것이 이전에 설치한 Gson입니다.

 

페이지에서 변경되는 점은 send() 메서드를 사용할 때, 입력한 데이터를 매개변수로 전달하는 것만 추가가 되었으며 알아볼 부분은 컨트롤러 입니다.

 

이번에 새로이 추가되어 배울것은 Gson의 fromJson() 메서드,

JsonObject, JsonArray 객체입니다.

fromJson()은 FileReader 객체, 반환 자료형 을 매개변수로 받습니다.

사용 예시는 아래와 같습니다.

gson.fromJson(fileReader,JsonObject.class)

 위 코드는 반환값을 JsonObject형으로 받겠다는 것입니다.

※이때, fileReader는 매개변수의 자료형이 FileReader입니다. 파일의 경로를 String으로 입력해서는 안됩니다.

 

 

01. 페이지 코드
02. 컨트롤러 코드
03. 실행 화면

 

01. 페이지 코드

<head>
<meta charset="UTF-8">
<title>ex05</title>
<script type="text/javascript">

var req;

function send() {
		req = new XMLHttpRequest();
		req.onreadystatechange = changeText
		req.open('post','ex05')
		req.setRequestHeader('Content-Type',"application/json; charset=UTF-8")
		var title = document.getElementById('title').value
		req.send(title)
	}

	function changeText() {
		if(req.readyState==4 && req.status==200){
			var tbody = document.getElementById('tbody')
			tbody.innerHTML = "아직은 데이터가 없음"
			var resData = JSON.parse(req.responseText)
			var printData =''
			for(i = 0; i < resData.cd.length; i++){
				printData += "<tr><td>"+resData.cd[i].title+"</td>"
				printData += "<td>"+resData.cd[i].artist+"</td>"
				printData += "<td>"+resData.cd[i].price+"</td></tr>"
			}
			tbody.innerHTML = printData
		}
	}

</script>
</head>
<body>
<input type="text" id="title"> 
<button type="button" onclick="send()">실행</button>
<table border="1">
	<thead>
		<tr>
			<th>title</th>
			<th>artist</th>
			<th>price</th>
		</tr>
	</thead>
	<tbody id="tbody"></tbody>
</table>

</body>

02. 컨트롤러 코드

	@GetMapping("ex05")
	public String ex05Get() {
		return "ajax/ex05";
	}
	
	@ResponseBody
	@PostMapping(value="ex05", produces = "application/json; charset=UTF-8")
	// String title이라는 변수가 없어도 에러가 발생하지 않도록 required = false 입력.
	// String title이라는 매개변수가 없다면 title에는 null이 저장된다.
	public String ex05Post(@RequestBody(required = false) String title) throws FileNotFoundException, IOException {
		
		ClassPathResource resource = new ClassPathResource("ex05.json");
		FileReader reader = new FileReader(resource.getFile());
		
		// BufferedReader대신 사용할 Gson 객체의 생성
		Gson gson = new Gson();
		
		
		// gson을 이용해 reader의 경로에 해당하는 파일에 접근
		JsonObject obj = gson.fromJson(reader, JsonObject.class);
		// reader 경로의 파일에서 읽겠다는 뜻, 반환값은 JsonObject의 자료형으로 반환하겠다는 뜻
		// 위에서 첫번째 매개변수는 FileReader의 자료형이 요구 되기때문에 경로를 String으로 입력해서는 안됨
		// 그래서 반환값이 JsonObject이므로 JsonObject 자료형인 obj에 저장한다
		
		if(title == null) {
			return obj.toString();
		}
		
		// obj에 있는 cd의 값을 저장
		JsonArray array = obj.get("cd").getAsJsonArray();
		
		//검색값이 없다면 모두 출력하기 위해서 체크할 변수
		boolean check = true;
		
		//반환값인 resData의 생성
		String resData ="{\"cd\":[";
		
		for(int i =0;i<array.size();i++) {
			
			// array에 있는 i번째 목록을 저장
			JsonObject obj2 = array.get(i).getAsJsonObject();
			
			// 지금까지 검색된 목록에 다음 노래 제목이 이미 들어가있다면 이번 반복은 건너뛰기
			if(resData.contains(obj2.get("title").getAsString())) {
				continue;
			}
			
			// 대소문자를 구분하지 않기 위해 둘다 소문자로 통일
			String track = obj2.get("title").getAsString().toLowerCase();
			title = title.toLowerCase();
			
			if(track.contains(title)) {
				check=false; //검색된 노래가 있으면 check=false
				resData += "{\"title\":" + obj2.get("title").toString();
				resData += ", \"artist\":"+obj2.get("artist").toString();
				resData += ", \"price\":"+obj2.get("price").toString()+"},";
			}
		}
		
		// 마지막에 들어가는 쉼표를 없애주기 위해 줄의 마지막 글자를 삭제하는 부분
		resData = resData.substring(0, resData.length()-1);
		
		resData += "]}";

		//검색된 노래가 하나도 없다면 check는 true인 상태 이므로 모든 노래를 반환
		if(check) {
			return obj.toString();
		}

		return resData;
	}

03. 실행 화면

①gson의 fromJson() 메서드를 이용해 파일을 읽어오고 반환값은