이번에는 질문 상세 페이지를 구현하려고합니다.
QuestionService클래스로 이동하여 id값으로 질문 엔터티를 찾아오는 함수를 작성합니다.
public Question getQuestion(Integer id) {
Optional<Question> oq=questionRepository.findById(id);
if (oq.isPresent()){
return oq.get();
}else{
throw new DataNotFoundException("data not found");
}
}
일단 question객체를 받기위해 Optional객체로 만들었습니다.
Optional클래스는 '존재할 수도 있지만 존재하지않을 수도 있는 객체'를 담을 수 있는 wrapper 클래스입니다.
그래서 Optional클래스를 사용하게 되면 nullPointerException을 방지할 수 있습니다.
Question객체를 담을 수있는 Optional객체 oq를 선언하고,questionRepository에서 해당 id값을 갖는 객체를 찾아 객체가 존재한다면(null이 아니라면) oq객체를 반환해줍니다.
하지만 Optional객체의 값이 null이라면 예외객체(DataNotFoundException)를 던져줍니다.
이제 questionController로 이동해서 questionService에서 구현한 함수를 사용하여 사용자에게 페이지를 반환해주는 메소드를 생성해보겠습니다.
@GetMapping(value = "/details/{id}")
public String detail(Model model, @PathVariable("id") Integer id, AnswerForm answerForm) {
Question question = this.questionService.getQuestion(id);
model.addAttribute("question", question);
return "question_details";
}
questionService에서 id값을 가지고 질문을 받아와 question변수에 넣어주고,해당 question객체를 model에 더해줍니다.
model의 addAttribute를 통해 qustion객체를 담아 question_details화면에 전송해줍니다.그러면 question_details에서 question이라는 변수를 통해 qustion객체의 사용이 가능합니다.
이제 답변 기능을 구현할 차례입니다.
답변테이블에 접근이 가능하게끔 AnswerRepository를 작성해보겠습니다.
@Repository
public interface AnswerRepository extends JpaRepository<Answer,Integer> {
List<Answer> findByQuestion(Question question);
}
question객체를 통해 Answer객체를 담은 리스트를 반환하는 메서드 이름을 정의합니다.
이 인터페이스에서 정의한 findByQuestion을 service에서 실행하면 jpa가 메서드 이름을 분석하여 jpql을 생성하고 실행합니다.
AnswerService를 통해 답변을 저장하는 메서드를 작성해보겠습니다.
@Service
@RequiredArgsConstructor
public class AnswerService {
private final AnswerRepository answerRepository;
public void createAnswer(Question question, String content, Member author){
Answer answer1=new Answer();
answer1.setQuestion(question);
answer1.setCreateDate(LocalDateTime.now());
answer1.setContent(content);
answer1.setAuthor((author));
answerRepository.save(answer1);
}
}
answer1이라는 answer객체를 생성하여 question,CreateData,Content,Ahthor값을 설정해주고 answereRepository에 저장해주는 함수입니다.
입력받은 폼의 검증을 위해 Form클래스도 활용할것입니다.
build.gradle파일의 dependancies안에 implementation 'org.springframework.boot:spring-boot-starter-validation'를 추가해줍니다.그리고 AnswerForm클래스를 작성해줍니다.
@Getter
@Setter
public class AnswerForm {
@NotEmpty(message = "내용은 필수항목입니다.")
private String content;
}
그리고 AnswerController를 작성해줍니다.
@Controller
@RequiredArgsConstructor
@RequestMapping("/answer")
public class AnswerController {
private final QuestionService questionService;
private final AnswerService answerService;
private final MemberService memberService;
@PreAuthorize("isAuthenticated()")
@PostMapping("/create/{id}")
public String CreateAnswer(Model model, @PathVariable("id") Integer id, @Valid AnswerForm answerForm,BindingResult bindingResult, Principal principal){
Question question=questionService.getQuestion(id);
Member member=this.memberService.getMember(principal.getName());
if (bindingResult.hasErrors()){
model.addAttribute("question",question);
return "question_details";
}
answerService.createAnswer(question,answerForm.getContent(),member);
return String.format("redirect:/question/details/%s", id);
}
}
위와 같이 list페이지에서 detail페이지로의 이동이 가능해졌습니다.
'웹개발' 카테고리의 다른 글
quenswer(프로젝트)-spring security(로그인,로그아웃) (0) | 2024.02.04 |
---|---|
quenswer(프로젝트)-spring security(회원가입) (0) | 2024.02.04 |
quenswer(프로젝트)-QuestionList (0) | 2024.01.08 |
quenswer(프로젝트)-Junit Test(Answer) (0) | 2023.12.29 |
quenswer(프로젝트)-Junit Test(Question) (0) | 2023.12.29 |