질문 상세

prana·2023년 5월 22일

SpringBoot

목록 보기
10/22
post-thumbnail
// QuestionService.java
package com.mysite.sbb.question;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.mysite.sbb.DataNotFoundException;


import java.util.List;

@RequiredArgsConstructor
@Service
public class QuestionService {
    private final QuestionRepository questionRepository;
    public List<Question> getList(){
        return this.questionRepository.findAll();
    }

    public Question getQuestion(Integer id){
        Optional<Question> question = this.questionRepository.findById(id);
            if(question.isPresent()){
                return question.get();
            }else{
                throw new DataNotFoundException("question not found");
            }

    }
}
  • id 값으로 Question 데이터를 조회하는 getQuestion 메서드를 추가했다.

  • 리포지터리로 얻은 Question 객체는 Optional 객체이기 때문에 위와 같이 isPresent 메서드로 해당 데이터가 존재하는지 검사하는 로직이 필요하다.

  • 만약 id 값에 해당하는 Question 데이터가 없을 경우에는 DataNotFoundException을 발생시키도록 했다.


//DataNotFoundException.java
package com.mysite.sbb;

import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.http.HttpStatus;
import 

@ResponseStatus(value=HttpStatus.NOT_FOUND, reason = "entity not found")
public class DataNotFoundException extends RuntimeException{
    private static final long serialVersionUID = 1L;
    public DataNotFoundException(String message){
        super(message);
    }
}
  • RuntimeException을 상속하여 만들었다.
    만약 DataNotFoundException이 발생하면, @ResponseStatus 애너테이션에 의해 404 오류(HttpStatus.NOT_FOUND)가 나타날 것이다.


에서 id가 1, 2인데 3을 url에 넣어 확인해본다면?

id가 1인 게시글의 상세보기는 잘 나왔다.

Controller 에 내용 추가하기

   @GetMapping(value="question/detail/{id}")
    public String detail(Model model, @PathVariable("id") Integer id){
        Question question = this.questionService.getQuestion(id);
        model.addAttribute("question", question);
        return "question_detail";
  } 

URL 프리픽스(prefix)

1. @GetMapping("/question/list")

↑ 나는 슬래시가 빠진 ("question/list")로 했다. 그대신 application.properties에서 / 하나를 template 뒤에 붙여준다.

  • value 매개변수는 생략할 수 있다.

2. @GetMapping(value="/question/detail/{id}")


/question으로 시작한다는 것을 확인할 수 있었는데, 이런 경우 클래스명 위에

package com.mysite.sbb.question;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

✅ @RequestMapping("question")
@RequiredArgsConstructor
@Controller
public class QuestionController {

    //private final QuestionRepository questionRepository;
    private final QuestionService questionService;

    @GetMapping("/list")
    public String list(Model model) {
        List<Question> questionList = this.questionService.getList();
        model.addAttribute("questionList", questionList);
        return "question_list";
    }

    @GetMapping(value="/detail/{id}")
    public String detail(Model model, @PathVariable("id") Integer id){
        Question question = this.questionService.getQuestion(id);
        model.addAttribute("question", question);
        return "question_detail";
    }

}

list 메서드의 url 매핑은 /list이지만,
/question + /list 가 되어 최종적인 URL 매핑은
/question/list가 된다.

  • 위와 같이 수정하면 기존과 완전히 동일한 기준으로 URL 매핑이 이루어진다.

  • 앞으로 QuestionController에서 사용하는 URL 매핑은 항상 /question으로 시작해야하는 규칙이 생긴 것이다.

0개의 댓글