티스토리 뷰

발단
사용자 사용 이력을 분석 중 일부 데이터에 특정 값이 누락되어 저장되는 현상을 확인하였음.

해당 이력이 저장되는 로직을 분석한 결과 A 메소드를 진행 시 객체에 저장된 값을 세션에 저장하여
B화면으로 이동 후 화면내 작업 완료 시
B 메소드로 가지고 가서 이력을 남기는 로직으로 확인하였음.

public String A(HttpServletRequest request){
    TestVo testVo = new TestVo();
    testVo.setOne("1");
    testVo.setTwo("2");
    testVo.setThree("3");

    HttpSession session = request.getSession();
    session.setAttribute("TestSession", vo);

    //현시점 TestSession 값 확인 시 누락없이 정상적으로 저장되어 있음

    return "B()메소드 호출하기 위한 화면";
}
public void B(HttpServletRequest request){
    HttpSession session = request.getSession();

    TestVo testVo = (TestVo)session.getAttribute("TestSession");
    //현시점 TestSession 값 확인 시 누락발생되어 있음 확인 (Three 변수 값 null 확인)
    historySave(testVo); //이력 저장 메소드

}


원인파악
멀티서버 및 이기종 WAS 사용 중이기 때문에 현재 시스템 세션 관련 설정 확인

- application 기준 확인(jboss)
WAS standalone.xml 파일 내  org.jboss.as.clustering.web.infinispan 모듈은 존재하나 관련 설정은 없음.
jboss-web.xml 파일 내 세션 공유 관련 설정 존재하지 않음.
web.xml 내 세션 공유 관련 설정인 <distributable/> 태그가 존재하지 않음.
다만 상용 세션클러스터링 솔루션 관련 filter와 servlet 선언이 존재.

상용 세션클러스터링 솔루션 관련 jar를 decompile 하여 확인 시 TestVo class가 확인되었고
현재 TestVo가 현행화되지 않고 초기 상태임을 확인하였음.

프로젝트 내 TestVo.java 파일

public class TestVo implements Serializable{

    private String one;

    private String two;

    private String three;

}


솔루션 내 TestVo.java 파일

public class TestVo implements Serializable{

    private String one;

    private String two;

    //변수 three 추가 현행화 되어있지 않음

}



해당 부분 소스는 솔루션업체에 요청이 필요하고 객체를 세션에 바로 저장하는 경우는 이상 없이 사용 가능하고
확인된 로직처럼 사용시 값 누락이 발생하기 때문에 직접 조치하는 방안으로 결정하였음.

해결방법
세션으로 TestVo 객체를 전달하는 방법을 다른 방법으로 전달하고자 함.
json으로 전달시 해당 값을 다시 파싱 해야 하는 추가 작업 필요.
메서드 A()에서 TestVo 객체를 직렬화하여 세션에 String 형으로 저장 후
메서드 B()에서 역직렬화를 통하여 객체를 활용하는 방법

public String A(HttpServletRequest request){
    TestVo testVo = new TestVo();
    testVo.setOne("1");
    testVo.setTwo("2");
    testVo.setThree("3");

    HttpSession session = request.getSession();

    byte[] encodeByteTestVo = null;
	String serializedTestVo = null;
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(testVo);
            encodeByteTestVo = Base64.encodeBase64(baos.toByteArray());
            serializedAgreeTestVo = new String(encodeByteTestVo);
        }
    }

    session.setAttribute("TestSession", serializedAgreeTestVo);

    return "B()메소드 호출하기 위한 화면";
}



public String B(HttpServletRequest request){

   HttpSession session = request.getSession(false);
        
        //직렬화된 데이터
        String serializedTestSession = (String)session.getAttribute("TestSession");
        
        TestVo testVo = new TestVo();
        byte[] decodeByteTestVo = Base64.decodeBase64(serializedTestSession.getBytes());
        try(ByteArrayInputStream bais = new ByteArrayInputStream(decodeByteTestVo)) {
        	try (ObjectInputStream ois = new ObjectInputStream(bais)) {
                Object objectTestVo = ois.readObject();
                testVo = (TestVo)objectTestVo;
                historySave(testVo); //이력 저장 메소드
        	}
        }
}



결과
메서드 A()에서 저장한 세션정보가
중간 화면을 거쳐
메소드 B() 호출까지 누락 및 유실 없이 정상적으로 사용됨을 확인하였음.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함