Java

[Tetris] ObjectMapper

kk_eezz 2022. 4. 30. 19:34

 

기존에는 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-파싱하기