2026. 4. 1. 19:23ㆍ대우개발원 수업 내용/spring boot, framework
1. 검색 파라미터 추출 및 URL 자동 조립 기능 구현 (PageRequestDTO.java)
사용자가 설정한 5가지 검색 조건이 이동 시마다 유실되지 않도록 getLink() 메서드 내부에 조건부 결합 로직을 구축함.
- 완료 여부(finished) 유지: 체크박스가 선택된 상태(true)라면 URL 뒤에 &finished=on을 강제로 붙여 필터링 상태 유지.
- 다중 검색 조건(types) 반복 결합: 제목(t), 작성자(w) 등 배열로 들어오는 검색 타입을 반복문을 통해 &types=t&types=w 형태로 빠짐없이 이어 붙임.
- 검색어(keyword) 인코딩 처리: 한글 검색어가 URL에서 깨지지 않도록 URLEncoder를 사용해 UTF-8 형식으로 안전하게 변환하여 결합.
- 날짜 구간(from, to) 데이터 보존: 시작 날짜와 종료 날짜가 존재할 경우 문자열로 변환하여 URL 파라미터에 포함시켜 구간 검색 결과 유지.
2. 자바스크립트 폼 제출 방식을 통한 페이징 개선 (list.jsp)
단순한 링크 이동 방식에서 기존 검색 조건을 포함하여 전송하는 방식으로 로직을 변경함.
- 히든 필드를 활용한 데이터 전송: 페이지 번호 클릭 시 기존 form 태그 안에 input type='hidden'으로 페이지 번호를 동적으로 삽입.
- 상태 유지 제출(Submit): formObj.submit()을 호출하여 사용자가 입력한 모든 검색 조건과 클릭한 페이지 번호를 서버로 한꺼번에 전송.
3. 삭제 작업 후 검색 상태 유지 로직 적용 (modify.jsp & TodoController.java)
게시글 삭제 시 모든 검색 조건이 초기화되는 현상을 방지하기 위해 경로 제어 코드를 수정함.
- 삭제 폼 액션 수정: formObj.action 경로 뒤에 ${pageRequestDTO.link}를 결합하여 삭제 요청 시에도 현재의 검색/페이징 상태를 서버로 전달.
- 컨트롤러 리다이렉트 최적화: remove 메서드에서 작업 완료 후 redirect:/todo/list? 뒤에 pageRequestDTO.getLink()를 붙여 리턴함으로써, 삭제 직전의 검색 결과 화면으로 정확히 복귀하도록 구현.
4. 수정 작업 후 경로 제어 및 파라미터 최적화 (TodoController.java)
수정(Modify) 작업 완료 후의 흐름을 사용자 경험에 맞춰 재설계함.
- 상세 페이지(Read) 복귀 설정: 수정 완료 후 단순 목록 이동이 아닌, 방금 수정한 글을 확인할 수 있도록 redirect:/todo/read 경로에 tno와 기존 link 정보를 실어서 보냄.
- 불필요한 중복 코드 제거: page와 size를 별도로 addAttribute하던 방식을 지우고, 모든 정보가 포함된 getLink() 메서드 하나로 파라미터 전달 과정을 간소화함.
아래 사진 부분에

완료 여부(finished) 체크박스가 선택(true)된 상태라면 URL 주소 뒤에 '&finished=on' 파라미터를 덧붙여주는 조건부 결합 코드. 목록 페이지를 넘기거나 상세 글을 읽고 돌아와도 '완료된 항목만 보기' 검색 필터가 풀리지 않고 그대로 유지되게 만드는 필수 수정.
if(finished){
builder.append("&finished=on");
}
이 구문을 추가

제목이나 작성자 같은 검색 조건(types)이 선택되어 배열에 값이 존재하면,
URL 주소 뒤에 '&types=t'나 '&types=w' 처럼 선택한 개수만큼 파라미터를 계속 이어 붙여주는 반복문 코드.
여러 개의 체크박스를 동시에 선택하고 페이지를 넘기더라도,
내가 체크했던 다중 검색 조건들이 중간에 유실되지 않고 끝까지 유지되도록 만들어주는 필수 수정.
if(types != null && types.length > 0){
for (int i = 0; i < types.length ; i++) {
builder.append("&types=" + types[i]);
}
}
추가
검색어(keyword)가 입력되었을 때, 한글이나 띄어쓰기 같은 문자가 URL 주소창에서 깨지지 않도록
UTF-8 형식으로 안전하게 변환(인코딩)하여 파라미터에 붙여주는 필수 코드.
검색창에 한글을 치고 다음 페이지로 넘어갔을 때, 글자가 외계어로 변질되어
애써 찾은 검색 결과가 날아가는 현상을 완벽하게 막아주는 꼼꼼한 수정.
if(keyword != null){
try {
builder.append("&keyword=" + URLEncoder.encode(keyword,"UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
추가
시작 날짜(from)가 선택되어 값이 존재할 경우, URL 주소 뒤에 '&from=2026-05-01' 같은 형식으로
날짜 데이터를 문자열로 변환해 덧붙여주는 코드. 날짜 구간으로 검색을 하고 페이지를 넘기거나
상세 글을 보고 돌아와도, 처음에 설정했던 시작 날짜 필터가 초기화되지 않도록 꽉 잡아주는 필수 수정.
if(from != null){
builder.append("&from=" + from.toString());
}
추가
종료 날짜(to)가 선택되어 값이 존재할 경우, URL 주소 뒤에 '&to=2026-05-31' 같은 형식으로
날짜 데이터를 문자열로 변환해 덧붙여주는 코드. 날짜 구간으로 검색을 하고 페이지를 넘기거나
상세 글을 보고 돌아와도, 처음에 설정했던 종료 날짜 필터가 초기화되지 않도록 끝까지 유지시켜주는 필수 수정.
if(to != null){
builder.append("&to=" + to.toString());
}
요약
사용자가 입력한 5가지 검색 조건들을 모두 모아 하나의 URL 파라미터로 길게 이어 붙여주는 코드.
페이지를 이동하거나 상세 글을 보고 돌아와도 내가 설정한 검색 필터가 절대 초기화되지 않도록 하는 코드들 이다.
총 코드
package com.example.springex_web.dto;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Arrays;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PageRequestDTO {
@Builder.Default //기본값 세팅
@Min(value = 1)
@Positive // 무조건 양수값을 가져야함 ,음수 x
private int page = 1;
@Builder.Default
@Min(value = 10)
@Max(value = 100)
@Positive
private int size = 10;
private String link;
private String[] types;
private String keyword;
private boolean finished;
private LocalDate from;
private LocalDate to;
public int getSkip(){
return (page -1) * 10;
}
public String getLink(){
if(link == null){
StringBuilder builder = new StringBuilder();
builder.append("page=" +this.page);
builder.append("&size=" + this.size);
if(finished){
builder.append("&finished=on");
}
if(types != null && types.length > 0){
for (int i = 0; i < types.length ; i++) {
builder.append("&types=" + types[i]);
}
}
if(keyword != null){
try {
builder.append("&keyword=" + URLEncoder.encode(keyword,"UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if(from != null){
builder.append("&from=" + from.toString());
}
if(to != null){
builder.append("&to=" + to.toString());
}
link = builder.toString();
}
return link;
}
public boolean checkType(String type){
if(types == null || types.length == 0){
return false;
}
return Arrays.stream(types).allMatch(type::equals); //타입 equals와 일치하는게 하나라도 있으면 true를 반환
}
}
list.jsp에서
// self.location = `/todo/list?page=\${num}` //백틱(` `)을 이용해서 템플릿 처리
이부분을 주석처리 후
코드는 브라우저에서 현재 화면의 데이터를 서버로 보낼 때, 눈에 보이지 않는 데이터를 추가해서 제출(Submit)하는 코드
페이징 처리(Pagination)**를 할 때 사용하며, 사용자가 특정 페이지 번호를 클릭했을 때 그 번호를 서버에 전달하기 위한 용도
const formObj = document.querySelector("form")
formObj.innerHTML += `<input type='hidden' name='page' value='\${num}'>`
formObj.submit();
구문 추가

실행하게 되면



그대로 유지된다
list는 링크가 그대로 유지 되는 코드가 있지만

링크가 그대로 유지되는 코드가 remove에는 없어서 유지가 되지 않기 때문에 추가
formObj.action=`/todo/remove?${pageRequestDTO.link}`

TodoController.java에도 remove메서드 구간에 링크를 포함한 이동을 할 수 있게 해줘야함
// redirectAttributes.addAttribute("page",1);
// redirectAttributes.addAttribute("size",pageRequestDTO.getSize());
// return "redirect:/todo/list";
이부분을 주석처리 후
return "recirect:/todo/list?" + pageRequestDTO.getLink();
을 추가

링크가 그대로 유지되는 코드가 modify에도 없어서 유지가 되지 않기 때문에 추가
modify에서는 검색 필터링에 대한 내용을 없애고 list로 돌아오도록 한다
(이전에 검색했던 내용을 수정했을 때 그대로 나오면 꼬이기 때문)
우선 link메서드에 page와 size정보가 다 담겨 있고
modify에서는 쓰지 않아서 주석처리를 한다



이걸로 자바 프레임워크는 끝나고 이제 spring boot를 한다
'대우개발원 수업 내용 > spring boot, framework' 카테고리의 다른 글
| 자바 스프링 부트 2일차 b01 (0) | 2026.04.02 |
|---|---|
| 자바 스프링 부트 1일차 b01 (0) | 2026.04.01 |
| 자바 프레임 워크 10일차 springex_web 페이징처리, 검색처리 (1) | 2026.04.01 |
| 자바프레임워크 9일차 springex_web 페이징 처리 (0) | 2026.03.30 |
| 자바 프레임워크 8일차 springex_web(Read, Delete, Update) (0) | 2026.03.27 |