Post

[코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문] 7장. 게시글 수정하기: Update

[코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문] 7장. 게시글 수정하기: Update

“코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문” 도서 바로가기

7장. 게시글 수정하기: Update

웹 애플리케이션에서 이미 저장된 데이터를 수정하려면, 수정할 대상 데이터를 데이터베이스에서 다시 불러와 입력 가능한 상태의 화면으로 제공해야 한다. 그 후 사용자가 수정한 데이터를 서버로 전송하면 데이터베이스의 기존 데이터를 갱신하게 된다.

게시글 수정 프로세스는 크게 다음의 2단계로 나뉜다.

  1. 수정 페이지 구현 및 기존 데이터 조회
  2. 수정된 데이터를 데이터베이스에 반영 후 상세 페이지로 리다이렉트

7.1 데이터 수정과정

1단계: 수정 페이지 호출 및 기존 데이터 로드

  • 사용자가 상세 페이지(show)에서 [Edit] 버튼을 클릭하여 수정 요청을 보낸다.
  • 요청을 수신한 컨트롤러는 전달받은 고유 식별자(id)를 기준으로 리파지터리를 통해 데이터베이스에서 데이터를 조회한다.
  • 컨트롤러는 조회된 데이터를 뷰 템플릿 엔진이 렌더링할 수 있도록 모델(Model)에 등록합니다.
  • 모델에 등록된 데이터를 수정 페이지(edit)의 각 입력 필드에 매핑하여 출력함으로써 사용자가 데이터를 수정할 수 있는 상태를 제공합니다.

2단계: 데이터 수정 요청 및 데이터베이스 갱신

  • 수정 페이지의 입력 폼 데이터를 DTO 객체에 담아 컨트롤러로 전송합니다.
  • 컨트롤러는 전달받은 DTO를 도메인 엔티티(Entity) 객체로 변환합니다.
  • 변환된 엔티티 데이터를 리파지터리를 통해 데이터베이스의 기존 레코드 정보와 비교한 후 최신 데이터로 갱신합니다.
  • 데이터베이스 반영이 완료되면 갱신된 데이터를 보여주는 상세 페이지로 화면을 리다이렉트(재요청) 처리합니다.

7.2 <수정 페이지=""> 만들기

7.2.1 <상세 페이지="">에 Edit 버튼 만들기

7.2.1 <상세 페이지="">에 Edit 버튼 만들기

  1. 상세 페이지 뷰 수정: 상세 페이지를 나타내는 show.mustache 파일을 연다. 데이터 테이블을 종결하는 </table> 태그 하단에 수정 화면으로 요청을 보낼 하이퍼링크 <a> 태그를 추가한다. 이동할 URL은 개별 게시글의 고유 id 속성에 유기적으로 대응하도록 /articles/{article.id}/edit 경로로 지정하고, 링크 텍스트는 Edit로 설정합니다.
  2. 작동 상태 검증: 로컬 서버를 가동한 뒤 localhost:8080/articles/new경로에 진입하여 ‘가가가가/1111’ 데이터를 제출한다. 이후 상세 페이지 화면으로 진입하여 표 하단에 작성한 Edit링크가 정상적으로 노출되는지 확인한다.
  3. 부트스트랩 스타일 적용: 하이퍼링크 텍스트 형태를 버튼 스타일로 전환하기 위해 부트스트랩 클래스 속성(class="btn btn-primary")을 링크 태그에 부여한다.
  4. 갱신 화면 확인: 브라우저의 화면을 새로고침하여 링크 텍스트가 파란색의 Edit 버튼 형태로 스타일이 정상 변경되었음을 확인한다.

사진1

7.2.2 Edit 요청을 받아 데이터 가져오기

[Edit] 버튼을 클릭하면 서버 내부에서 요청을 수신할 컨트롤러 메서드가 존재하지 않기 때문에 404 에러(Not Found) 페이지가 발생한다. 요청을 정상적으로 처리하는 제어 메서드를 구현한다.

  • edit() 메서드 기본 틀 구성: ArticleController.java 소스 파일을 열고, 기존 index() 메서드 아래에 수정 화면 요청을 수신할 edit() 메서드를 추가한다. 수정 페이지 요청 경로인 /articles/{id}/edit를 @GetMapping 어노테이션의 주소 값으로 정의한다. 이때 뷰 페이지에서 사용하는 이중 중괄호 문법과 달리, 스프링 컨트롤러에서 변수를 경로 상에서 획득할 때는 단일 중괄호({ }) 변수 표기법을 준수해야 한다.
1
2
3
4
5
@GetMapping("/articles/{id}/edit")
public String edit() {
    // 수정 페이지를 렌더링할 뷰 템플릿 파일 경로를 지정합니다.
    return "articles/edit";
}
  • 수정 대상 데이터 로드: 데이터베이스에 저장되어 있는 기존 데이터를 획득하기 위해 주입된 리파지터리 객체의 findById(id)메서드를 사용한다. 경로 변수(id)를 메서드의 매개변수로 안전하게 획득하기 위해 Long id타입 정의 앞에 @PathVariable어노테이션을 지정한다. 조회한 데이터를 찾지 못하는 예외 상황을 고려하여 뒤에 .orElse(null)구문을 체이닝 처리하며, 반환된 데이터를 Article타입의 articleEntity변수에 최종 할당한다.
1
2
3
4
5
6
7
@GetMapping("/articles/{id}/edit")
public String edit(@PathVariable Long id) {
    // 1. 데이터베이스에서 수정 대상 데이터 조회
    Article articleEntity = articleRepository.findById(id).orElse(null);

    return "articles/edit";
}
  • 모델에 데이터 등록: 획득한 엔티티를 뷰 엔진 렌더링 파이프라인으로 전달하기 위해 메서드 파라미터 구조에 Model model객체를 부여하여 인스턴스를 주입받는다. 그 후 model.addAttribute("article", articleEntity)코드를 통해 데이터베이스 조회 엔티티를 모델 컨텍스트에 등록한다.
1
2
3
4
5
6
7
8
9
10
11
@GetMapping("/articles/{id}/edit")
public String edit(@PathVariable Long id, Model model) {
    // 1. 데이터베이스에서 수정 대상 데이터 조회
    Article articleEntity = articleRepository.findById(id).orElse(null);

    // 2. 모델 영역에 엔티티 데이터 등록
    model.addAttribute("article", articleEntity);

    // 3. 뷰 템플릿 파일 경로 설정
    return "articles/edit";
}

사진2

7.2.3 수정 폼 만들기

  1. 수정 뷰 파일 생성 및 공통 레이아웃 설정: resources > templates > articles 디렉터리에 edit.mustache 파일을 만든다. 파일 내부 최상단에 헤더 템플릿을 바인딩하고 최하단에 푸터 템플릿을 삽입하여 공통적인 레이아웃 프레임을 잡는다.
  2. 입력 폼 컴포넌트 재사용: 수정하는 양식 인터페이스는 신규 데이터를 입력하는 구성과 유사하므로, 기존 작성된 new.mustache 소스 내의 <form class="container" ...>...</form> 태그 영역을 전체 복사한다.
  3. 수정 뷰 코드 수정 반영: 복사한 내용을 edit.mustache 파일의 헤더와 푸터 태그 레이아웃 사이에 붙여넣은 뒤 다음의 두 가지 항목을 순차적으로 수정한다.
    • <form> 태그의 action 속성값 공백화: 데이터 전송에 관련된 목적지 주소 속성을 우선 제거(공백)하여 후속 수정 데이터 처리 부분에서 개발할 수 있도록 대기시킨다.
    • Back 링크 대상 타겟 주소 변경: 수정 작업을 중단하고 상세 화면으로 돌아가기 위해, 기존 /articles 메인 주소에서 사용 범위 데이터를 반영하여 고유 id 경로인 /articles/{article.id} 주소값으로 수정한다.
  4. 화면 갱신 테스트: 서버를 구동한 후 localhost:8080/articles 목록 화면에서 임의의 데이터(예: 홍팍자바/1111)를 신규 생성하여 등록한다. 상세 조회 결과 화면에서 [Edit] 버튼을 선택했을 때 오류 없이 수정 입력창들이 로출되는지 확인한다.
  5. 결함 사항 분석: 이동된 수정 화면을 확인하면 기존에 입력되어 있어야 할 ‘홍팍자바/1111’ 텍스트 데이터들이 입력란에 채워지지 않은 상태로 깨끗하게 비어있는 것을 볼 수 있다. 이는 서버 내부 데이터 정보를 뷰 템플릿 파일 컴포넌트에 올바르게 바인딩하지 않았기 때문이다.
  6. 기존 데이터 표시 설정: 수정 화면 진입 시 기존 데이터의 값이 입력창 내부 필드에 자동으로 매핑되도록 edit.mustache 코드 내의 태그 속성들을 아래와 같이 각각 수정한다.
    • 단일 행 입력 요소인 <input> 태그에는 value="{article.title}" 속성을 부착하여 제목 데이터를 기입한다.
    • 여러 줄 입력 요소인 <textarea> 태그에는 별도의 value 속성 대신 시작 태그와 종료 태그 사이의 콘텐트 텍스트 바인딩 영역 안에 {article.content} 속성을 작성하여 본문 데이터를 인출한다.
  7. 머스테치 중복 코드 개선 (사용 범위 설정): 반복적으로 기입된 article. 명칭을 제거하여 코드를 가독성 있게 최적화한다. <form>의 시작 부분 위에 데이터 모델 영역 지시 기호를 씌우고 </form> 하단 끝단에 {/article}로 닫는 설정을 추가하여 데이터의 범위를 규정한다. 범위 내에서는 단일 필드 명칭만으로 참조할 수 있도록 간소화된다.
  8. 최종 렌더링 동작 확인: 서버 인스턴스를 재가동한 뒤 ‘홍팍 자바/1111’ 데이터를 새로 발급해 등록을 친니다. 1번 데이터 상세 페이지의 하단 [Edit] 단추를 누르고 전환된 화면에서 ‘홍팍 자바’와 ‘1111’ 텍스트 정보가 가용 영역 내에 누수 없이 성공적으로 연동되어 로드되었음을 실증한다.

사진3


7.3 수정 데이터를 DB에 갱신하기

클라이언트 레이어와 서버 간의 일련의 처리 흐름을 지원하기 위해 상호 연결되는 4대 핵심 기술군은 아래와 같다.

  • MVC (Model-View-Controller): 서버 프로그램 내부에서 처리 영역을 독립적으로 구조화하여 분할 관리하는 아키텍처 패턴 기법이다.
  • JPA (Java Persistence API): 자바 프로그램 영역과 물리 관계형 데이터베이스 시스템 간의 데이터를 매핑하고 조작할 때 소통을 전담 제어하는 영속성 프레임워크 기술이다.
  • SQL (Structured Query Language): 데이터베이스 시스템 상에 적재되어 있는 원시 레코드를 조작하고 관리하기 위해 사용하는 구조화 질의어 표준 명세다.
  • HTTP (HyperText Transfer Protocol): 네트워크 통신 인프라를 통과하여 서로 다른 기기 간에 물리적 텍스트 데이터를 안정적으로 교환하기 위해 정의된 통신 규약 프로토콜 표준이다.

7.3.1 HTTP 메서드

클라이언트 브라우저와 원격지 서버 시스템이 패킷 정보를 전송할 때는 다양한 목적별 원활한 연결망 관리를 목표로 프로토콜 통신 표준 규격을 이용한다.

  • 프로토콜 (Protocol): 이종 시스템 컴퓨터 기기 간에 지연 에러 없이 안전하게 신호와 암호, 인증 방식을 공유하여 네트워크 통신을 완수할 수 있도록 상호 제정해 둔 전 세계 공동 전송 약속 규약이다. 목적과 용도에 상응하도록 파일 교환(FTP), 이메일 교송(SMTP) 등으로 규격화되어 사용되며, 웹 브라우저 서비스를 매개할 때는 HTTP 프로토콜이 표준 기저로 채택된다.

HTTP 프로토콜은 데이터 전달에 특화된 대표적인 고유의 처리 메서드 규격들을 정의하여 사용한다.

  • GET: 서버 시스템이 관리하는 특정 자원을 브라우저로 가져와 읽어들이는 조회 요청을 전담한다.
  • POST: 데이터베이스 테이블에 새로운 데이터를 주입하고 생성하기 위한 생성 요청을 전담한다.
  • PATCH (혹은 PUT): 기존에 이미 물리적으로 디스크 상에 기록되어 존재하고 있는 대상 데이터를 새로운 속성 데이터 값으로 대체하는 수정 요청을 전담한다.
  • DELETE: 데이터베이스 시스템 영역에 적재된 특정 자원 정보를 파기하고 소거하는 삭제 요청을 전담한다.

가장 대표적인 자원 관리의 4대 핵심 가동 체계인 CRUD(Create, Read, Update, Delete) 동작과 이를 지원하기 위한 관계형 SQL 쿼리문 및 HTTP 통신 프로토콜 메서드 간의 대응 관계는 다음과 같이 명세 구조가 정교하게 매칭된다.

데이터 관리 분류대응 SQL 명령문연계 HTTP 표준 메서드
데이터 생성 (Create)INSERTPOST
데이터 조회 (Read)SELECTGET
데이터 수정 (Update)UPDATEPATCH (혹은 PUT)
데이터 삭제 (Delete)DELETEDELETE

실행 시 예외 원인 규명: 이전 단계까지 완성된 수정 페이지 양식 화면에서 제목과 본문 값을 일부 임의로 변경하고 전송 버튼([Submit])을 선택하여 처리 연산을 실행하면, 수정 대상 목적 처리를 전담하는 백엔드 매핑 제어 영역이 부재하기 때문에 브라우저 화면 상에 405 Method Not Allowed 차단 예외 코드가 강제로 방출되는 결함이 나타난다.

7.3.2 더미 데이터 설정하기

매번 개발자가 코드를 수정할 때마다 메모리 데이터베이스가 초기화되어 매번 신규 데이터를 재입력해야 하는 번잡한 절차적 낭비를 해소하기 위해, 부트스트랩 인프라와 결합하여 가동 시점에 데이터를 자동 입력해 주는 더미(Dummy) 적재 구조를 프로젝트에 설치한다.

  1. 초기 로드용 SQL 파일 구성: src > main > resources 경로 하위에 마우스 오른쪽 클릭을 적용해 새 텍스트 파일명 data.sql을 만들어 소스 창을 연다. (시스템이 데이터베이스 플러그인 경고창을 표출할 경우 설정 무시(ignore extension) 명령을 주어 진행합니다.)
  2. 데이터 생성 쿼리 추가: 파일 내부에 시스템 부팅 과정 시 가상 데이터를 자동 배치할 수 있도록 데이터베이스 테이블 삽입 제어 명령어인 INSERT INTO 구문을 적용해 총 3건의 쿼리 코드를 기입한다.

    1
    2
    3
    
     INSERT INTO article(id, title, content) VALUES (1, '가가가가', '1111');
     INSERT INTO article(id, title, content) VALUES (2, '나나나나', '2222');
     INSERT INTO article(id, title, content) VALUES (3, '다다다다', '3333');
    
  3. 초기화 적재 에러 대응: 이대로 서버를 재시작하면 콘솔 콘솔창 내에 ScriptStatementFailedException 에러 경보가 나타나며 정상 실행에 실패하게 된다. 스프링 부트 2.5 버전 프레임워크부터는 구동 즉시의 data.sql 자동 처리를 기본값 정책상 제한하기 때문이다. 이를 영속적으로 가동하고 허가하기 위해 src > main > resources 디렉토리 하위의 프로젝트 설정 지표 관리 파일인 application.properties 소스 내부를 열어 지연 데이터 소스 활성화 속성을 다음과 같이 수동 기입하여 시스템을 조정한다.

    1
    
     spring.jpa.defer-datasource-initialization=true
    
  4. 적재 여부 뷰 검증: 수정 구성을 완료하고 서버 인스턴스를 정상 재시작한 뒤, 목록 정보 주소인 localhost:8080/articles 페이지로 바로 이동한다. 새 글 작성 행위를 건너뛴 상태임에도 테이블 영역 상에 우리가 설정한 3개의 데이터(id 1, 2, 3번)가 기본 적재 완료되어 부팅 시점부터 즉시 나타남을 볼 수 있다. 사진4

7.3.3 <수정 페이지=""> 변경하기

  1. 데이터 전송 경로 및 방식 변경: 수정 페이지 템플릿인 edit.mustache 소스를 연다. <form> 태그의 전달 타겟 속성을 /articles/update 가변 목적지 주소로 새로 수정 기입하고, 통신 전달 프로토콜 방식을 포스트 타입인 method="post" 구조로 설정해 준다.

    1
    
     <form class="container" action="/articles/update" method="post">
    

    💡 수정 행위에 POST 메서드를 대입하여 사용하는 내부 설계 원인 데이터 수정을 요청하는 작업이므로 HTTP 프로토콜 규격상 원래 PATCH나 PUT 메서드를 지정하는 것이 아키텍처 규칙에 부합한다. 그러나 전통적인 HTML 마크업 표준의 <form> 태그 명세 구조는 오직 GET과 POST 단 두 개의 전송 프로토콜 방식만을 제한적으로 허가하는 한계가 존재한다. 따라서 본 기능에서는 폼 양식의 표준 규격을 온전히 준수하기 위해 POST 방식을 유지한 상태로 수정 데이터를 전송한다.

  2. 식별자 ID 전달 폼 설계: 수정 작업을 영속 데이터 레이어에 적용하려면, 수정할 대상이 데이터베이스 내에서 몇 번째 인덱스로 등록된 레코드 행인지 명확히 전달해 주어야 한다. 따라서 수정 폼 영역 내에 식별 코드 변수를 저장하기 위한 목적의 전용 컴포넌트인 <input> 태그를 삽입하고 값을 value="~"로 지정한다. 사용자가 이 id 값을 화면에서 인지할 필요는 없으므로 시각적인 출력을 원천 차단하기 위해 화면 은폐 타입 제어 속성인 type="hidden"을 추가한다.

7.3.4 수정 데이터 받아 오기

update() 메서드 기본 구조 구축

ArticleController.java 컨트롤러 소스 코드로 진입한다. edit() 메서드 바로 하위 경로 부분에 전송 폼 데이터를 전용으로 가로채 처리할 @PostMapping("/articles/update") 주입 메서드를 추가로 작성하고 빈 문자를 반환하도록 임시 틀을 정의한다.

1
2
3
4
@PostMapping("/articles/update")
public String update(){
    return "";
}

수정 데이터를 DTO에 담기

  1. 클라이언트 전송 데이터를 받아 가공 수용하기 위한 목적의 저장 매개 파라미터로 데이터 전송 DTO 클래스인 ArticleForm form 구조를 주입 설정한다.

    1
    2
    3
    4
    
     @PostMapping("/articles/update")
     public String update(ArticleForm form){
         return "";
     }
    

    사진5

  2. 수정 데이터를 서버 측에 보낼 때 고유의 가변 id 변수 정보가 새로 동반되므로, 기존 데이터 필드 정의체 파일인 dto > ArticleForm.java 소스 파일을 편집기에 띄운다. 내부 인자 필드 데이터 유형 선언 목록 맨 윗부분에 식별자 변수 private Long id; 필드를 새롭게 명시한다. 그 뒤 하단 데이터 객체 치환용 변환 도구 메서드인 toEntity() 정의 구역을 확인한다. 기존에는 식별자 고유 정보가 연동되지 않아 가짜 초기 세팅값인 null로 지정해 인스턴스 빌더 생성자를 호출했지만, 이제는 주입 필드가 확보되었으므로 인자 내 값을 생성자에 안전하게 전달할 수 있도록 파라미터 호출 코드를 id로 최종 변경한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     public class ArticleForm{
         private Long id; // 식별자 데이터를 획득하기 위한 멤버 필드 정의 확장
         private String title;
         private String content;
        
         public Article toEntity(){
             // 기존의 null 지정 호출부에서 id 변수 전달 인자로 수정 개선
             return new Article(id, title, content);
         }
     }
    
  3. 수정 가공을 거친 데이터가 컨트롤러 레이어에 제대로 안착하여 전달되는지 점검하기 위해 컨트롤러 내부 코드 내에 수신 로그 디버깅용 확인 코드 log.info(form.toString()); 구문을 배치한다.

    1
    2
    3
    4
    5
    
     @PostMapping("/articles/update")
     public String update(ArticleForm form){
         log.info(form.toString()); // 수집된 수신 수정정보 출력 로그 등록
         return "";
     }
    
  4. 서버 프로세스를 재가동한 뒤 localhost:8080/articles/1 상세 페이지에 접근한다. 우측 하단의 [Edit] 버튼을 누르고 제목 속성과 내용을 ‘가가가가나나나나/11112222’로 연쇄 변경한 뒤 [Submit] 전송 명령을 입력한다. 백엔드 연동이 온전하지 않아 화면상에는 여전히 에러 페이지가 노출되지만, 개발 도구 실행 콘솔창 하단에 ArticleForm(id=1, title=가가가가나나나나, content=11112222) 포맷의 최종 수집 바인딩 로그가 정상적으로 도출됨을 검증한다.

7.3.5 DB에 저장하고 결과 페이지로 리다이렉트하기

DTO를 거쳐 서버 가공 계층에 무사히 획득된 데이터 집합은 영구적인 저장 공간인 데이터베이스에 확실히 반영 및 영속화되어야 한다. 이는 아래의 정형화된 3단계 프로세스를 차례대로 밟아 코딩하게 되며, 처리 이정표 역할을 할 주석 문장을 update() 메서드 블록 내부에 기입하여 구획을 짓는다.

1
2
3
4
5
6
7
8
9
10
@PostMapping("/articles/update")
public String update(ArticleForm form){
    log.info(form.toString());

    // 1. DTO를 엔티티로 변환하기
    // 2. 엔티티를 DB에 저장하기
    // 3. 수정 결과 페이지로 리다이렉트하기

    return "";
}

1단계: DTO를 엔티티로 변환하기

  • DTO 클래스인 ArticleForm에 선언된 객체 치환 전송 도구 메서드인 toEntity()를 다이렉트로 호출하여, 정립 완료된 도메인 모델 엔티티 구조인 Article 형태의 articleEntity 변수에 데이터를 받는다. 그 후 엔티티 형태로 적합하게 상속되어 가공되었는지 변환 점검용 디버그 로그(log.info())를 연속 출력한다.

    1
    2
    3
    
      // 1. DTO를 엔티티로 변환하기
      Article articleEntity = form.toEntity();
      log.info(articleEntity.toString()); // 변환된 엔티티 데이터 무결성 검사 로그 작성
    

사진6

2단계: 엔티티를 DB에 저장하기

수정 행위는 순수한 신규 정보 작성과 완전히 결별되어 작동되어야 한다. 이미 DB 내에 존재하고 적재되어 관리되던 특정 레코드 항목의 내용 부분만을 교체하는 논리적 작업이다. 따라서 다음과 같이 세부 2단계를 연속 연동하여 적용한다.

2-1. 기존 영속 데이터 수색 확보:

넘겨받은 변형 엔티티 객체의 내부 접근 게터 메서드인 getId()를 매개로 하여, 리파지터리가 제공하는 고유의 조회용 findById(id)를 발동시킨다. 수집 대상 id가 일례로 1번 값이라면 findById(1)과 같은 쿼리 동작이 정밀하게 일치 작동하도록 인자 매핑을 완성하며, 결과 획득 자바 변수는 Article target으로 정의해 받는다. (동작 안정성을 위해 탐색 실패 상황에는 null을 반환하도록 예외 지정을 뒤에 선언한다.)

1
2
// 2-1. DB에서 기존 데이터 가져오기
Article target = articleRepository.findById(articleEntity.getId()).orElse(null);

2-2. 검증 절차 기반의 데이터 가공 갱신 처리:

인출하여 넘겨받은 target 변수 정보가 존재 유무에 대해 결함이 전혀 검출되지 않음을 보증하는 검사 조건문 if (target != null)을 구현한다. 조건 만족 통과가 확정된 최종 제어 흐름 내부 구역에 진입하여 비로소 기존 엔티티 갱신 저장을 영구 수행하는 articleRepository.save(articleEntity); 코드를 최종적으로 실행시킨다.

1
2
3
4
// 2-2. 기존 데이터 값을 갱신하기 (대상 존재 여부 정합성 확인)
if (target != null) {
    articleRepository.save(articleEntity); // 갱신 대상이 데이터베이스 내에 확인되면 엔티티 갱신 수행
}

사진7

3단계: 결과 페이지로 리다이렉트하기

데이터 변경이 성공적으로 가용 공간에 영속 기입된 것을 최종 완수하였으므로, 사용자의 시각 화면에 결과 갱신이 완료된 최신의 대상 페이지 화면이 실시간으로 제공될 수 있도록 최종 제어권을 넘겨주어야 합니다. 따라서 수동으로 에러를 피하기 위해 뒤로가기를 지정하는 것이 아니라, 방금 데이터 갱신을 끝낸 해당 고유 정수 ID 번호 기반 상세 페이지 뷰의 주소 규칙인 /articles/{id} 경로로 재접속할 것을 클라이언트 브라우저로 재유도 및 지시해야 한다. 문자열 결합 처리 패턴 규칙에 상응하도록 최종 엔티티 반환 주소식을 return "redirect:/articles/" + articleEntity.getId(); 구문으로 입력하여 컨트롤러 조작을 끝맺는다.

1
2
// 3. 수정 결과 페이지로 리다이렉트하기
return "redirect:/articles/" + articleEntity.getId();

코드가 모두 완성되면 서버를 안전하게 리스타트하여 초기 더미 데이터 3종이 적재된 메인 화면에서 1번 행을 선택하여 Edit 버튼으로 진입한다. 제목 필드를 ‘AAAA’로 바꾸고 세부 본문 내용을 ‘12345678’로 타정한 다음 전송을 누른다. 주소 경로가 /articles/1 페이지로 즉시 리다이렉트 연쇄 반응을 보이며 수정한 ‘AAAA/12345678’ 데이터가 표출 화면상에 에러 없이 렌더링됨을 검증한다.

사진8

This post is licensed under CC BY 4.0 by the author.