[Tetris] ObjectMapper
기존에는 Tetris 게임의 scoreboard 처리를 txt 파일 I/O로 처리했었다.
하지만 이 방식이 project를 jar 파일로 만들고 나면 잘 작동하지 않는다는 것을 알게된 후 JSON 파일로 바꾸기로 결심했다.
바뀌는 점을 최소화하기 위해 기존 클래스의 함수 이름을 그대로 사용했다.
JSON(Javascript Object Notation)
"키:값" 쌍으로 이루어진 데이터 객체를 전달하기 위해 사람이 읽을 수 있는 텍스트를 사용하는 포맷
직렬화(Serialize): 객체들을 문자열로 바꾸어주는것, Object -> String
역직렬화(Deserialize): 데이터가 모두 전송된 이후 문자열을 기존의 객체로 회복시켜주는 것 String -> Object
ObjectMapper: JSON 컨텐츠를 Java 객체로 deserialization 하거나 Java 객체를 JSON으로 serialization 할 때 사용하는 Jackson 라이브러리 클래스
1. 우선 Score class를 만들어서 object로 score을 처리할 수 있도록 했다.
이때 getter와 default 생성자가 있어야한다.
public class Score {
protected String name;
protected Integer score;
protected String level;
protected String mode;
public Score() { //Default
this.name = "DF";
this.score = 0;
this.level = "normal";
this.mode = "regul";
}
public String getName(){
return name;
}
public Integer getScore(){
return score;
}
public String getLevel(){
return level;
}
public String getMode(){
return mode;
}
public Score(String name, Integer score, String level,String mode) {
this.name = name;
this.score = score;
this.level = level;
this.mode = mode;
}
public String toWritableString(){
return "| " + String.format("%-4s", this.name) + " "
+ String.format("%05d", this.score) + " " + String.format("%-7s", this.level)
+ String.format("%7s", this.mode) + "\n";
}
}
class ScoreComparator implements Comparator<Score> {
public int compare(Score arg0, Score arg1) {
return arg1.score.compareTo(arg0.score);
}
}
2. Java 객체를 JSON으로 직렬화 하기 위해 ObjectMapper의 writeValue() 함수를 사용한다.
scoreBoard를 처리하기 위한 Java 클래스를 하나 만들었다.
private List<Score> list;
private ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
여러개의 값을 가져오기 위해 List를 사용했고 새로운 값을 추가할 때 List에는 add가 되지 않아 ArrayList를 사용했다.
또한 Scoreboard 처리를 위해 sort 하고 현재 추가된 값의 list에서의 위치를 반환했다.
사실 쓸데 없이 리스트를 두 개 쓴거 같아서 이 부분은 수정이 필요할 것 같다.
public int writeScoreBoard(String name, int score, String level, String mode) throws IOException {
Score p = new Score(name,score,level,mode);
ArrayList<Score> List = new ArrayList<Score>(list);
List.add(p);
try {
mapper.writeValue(new File("scoreBoardFile.json"), List);
} catch (IOException e) {
e.printStackTrace();
}
list = Arrays.asList(mapper.readValue(new File("scoreBoardFile.json"), Score[].class));
Collections.sort(List, new ScoreComparator());
Collections.sort(list, new ScoreComparator());
int index = List.indexOf(p);
return index;
}
3. JSON -> java Object
readValue 함수를 사용해서 JSON 파일의 값을 Java 객체로 가져온다.
public void getScoreBoard() throws IOException {
list = Arrays.asList(mapper.readValue(new File("scoreBoardFile.json"), Score[].class));
Collections.sort(list, new ScoreComparator());
}
잘 작동한다.
참고
https://escapefromcoding.tistory.com/341
https://velog.io/@zooneon/Java-ObjectMapper를-이용하여-JSON-파싱하기