3/22 TIL - 점프투스프링부트 따라하기 3

큰모래·2023년 3월 22일
0
post-custom-banner

점프투스프링부트 따라하기


redirect

서버가 클라이언트에게 “너 이 주소로 다시 요청해” 라고 응답 결과로 알려주는 것을 의미한다.

클라이언트에게 응답 후 클라이언트 측에서 응답한 내용으로 재요청을 보내기 때문에 두 번의 HTTP 트랜잭션이 발생한다. 또한 서버측에서는 최초의 요청에서 받은 내용을 리다이렉트된 요청과 공유할 수 없는 문제가 있다.

redirect 동작 과정

  • 클라이언트가 서버에게 url 요청을 한다.
  • 서버에서는 클라이언트에게 HTTP 상태 코드 302Location 헤더에 redirect url을 넣어 보낸다.
    • HTTP 상태 코드 302는 리다이렉션을 나타내는 상태 코드이다.
    • LocationHTTP 통신 헤더 항목 중 하나로 리다이렉트 됐을때의 주소를 나타낸다.
  • 클라이언트는 HTTP 상태 코드 302를 확인하고 Location 헤더의 url로 서버에 다시 응답한다.

forward

클라이언트가 url 요청을 했을 때 서버내에서 다른 url 요청으로 이동하여 그에 맞는 결과를 응답하는 것

클라이언트는 forwardurl의 정보를 알 수 없고, 응답은 두번째 url에 대한 응답 한 번만 동작한다.

클라이언트는 다른 urlforward된 것을 모르므로, 주소창의 url 또한 변경되지 않는다.

forward 동작 과정

  • 클라이언트가 서버에 url 요청을 한다.
  • 서버 내부에서 다른 urlforward처리 한다.
  • 두번째 url에 대한 호출이 되고 서버에서 클라이언트에게 해당 url에 대한 응답을 한다.

Validation

폼 입력 시 입력한 데이터가 유효한 값인지 확인해줘야 한다.

종류역할
@Size문자 길이를 제한한다.
@NotNullNull을 허용하지 않는다.
@NotEmptyNull 또는 빈 문자열("")을 허용하지 않는다.
@Past과거 날짜만 가능
@Future미래 날짜만 가능
@FutureOrPresent미래 또는 오늘날짜만 가능
@Max최대값
@Min최소값
@Pattern정규식으로 검증

QuestionForm

  • 예제는 간단하지만, 만약 어떠한 서비스에서 회원가입 폼의 데이터를 컨트롤러까지 보내줘야 한다고 생각해보면 기존의 엔티티에 필요한 데이터말고도 부가적인 요소들이 있을 것이다.
  • 이러한 데이터들을 담아 뷰에서 컨트롤러까지 전송하는 Form 객체를 새로 만들었다.
  • Form 객체의 인자들에 대해 Validation 어노테이션을 붙여서 적용한다.

@Getter
@Setter
public class QuestionForm {
    @NotEmpty(message = "제목은 필수사항입니다.")
    @Size(max = 200)
    private String subject;

    @NotEmpty(message = "내용은 필수사항입니다.")
    private String content;

}

QuestionController

  • @Valid 를 통해 해당 객체에 대한 유효성 검사가 진행된다.
    • 객체에 붙인 @NotEmpty, @Size 등으로 설정한 검증 기능이 동작한다.
  • 그리고 BindingResult 객체에 해당 검증을 통한 결과(에러)가 담기게 된다.
		@PostMapping("/create")
    public String questionCreate(@Valid QuestionForm questionForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "question_form";
        }

        questionService.create(questionForm.getSubject(), questionForm.getContent());
        return "redirect:/question/list";
    }

페이징

목록을 조회하면 현재 페이지에 모든 게시글이 다 출력되므로 페이징 처리를 통해 이 문제를 해결할 필요가 있다.

QuestionRepository

  • findAll
    • Pageable 객체를 입력받아 Page<Question> 객체를 리턴한다.

public interface QuestionRepository extends JpaRepository<Question, Long> {
    Question findBySubject(String subject);

    Question findBySubjectAndContent(String subject, String content);

    List<Question> findBySubjectLike(String subject);

    Page<Question> findAll(Pageable pageable);

}

QuestionService

  • PageRequest.of
    • page는 조회할 페이지의 번호이고, 10은 한페이지에 보여줄 게시물의 개수이다.
    • 이렇게 하면 데이터를 전체 조회하지 않고, 해당 페이지의 데이터만 조회하도록 쿼리가 생성된다.
		public Page<Question> getList(int page) {
	      Pageable pageable = PageRequest.of(page, 10);
        return questionRepository.findAll(pageable);
    }

QuestionController

  • 쿼리스트링으로 페이지 번호를 전달한다. 이때 번호가 전달되지 않았으면 기본값 0
  • 쿼리스트링을 통해 받은 페이지 번호로 Page<Question> 객체를 반환받는다.
  • 해당 객체를 viewmodel로 전달
		@GetMapping("/list")
    public String list(Model model, @RequestParam(value = "page", defaultValue = "0") int page) {
        Page<Question> paging = questionService.getList(page);
        model.addAttribute("paging", paging);
        return "/question/question_list";
    }
profile
큰모래
post-custom-banner

0개의 댓글