Question 속성 추가
Question
@ManyToOne
private SiteUser author; //질문자
질문자 (유저) 한명에 많은 질문
Answer
@ManyToOne
private SiteUser author; //질문자
DB확인하기
ANSWER과 QUESTION 에 둘 다 AUTHOR_ID 추가 확인
AnswerController 에서 작성자를 추가한다
이미 세션에 정보를 저장하고 있는데, 그 정보를 가지고 오면 됨
@PostMapping("/create/{id}")
public String createAnswer(Model model, @PathVariable("id") Integer id,
@Valid AnswerForm answerForm, BindingResult bindingResult, Principal principal) {
}
Principal principal > 현재 로그인 한 유저 정보
UserService
//유저 조회
public SiteUser getUser(String username) {
Optional<SiteUser> siteUser = userRepo.findByusername(username);
if(siteUser.isPresent()){
return siteUser.get();
}
else {
throw new DataNotFoundException("siteuser not found");
}
}
AnswerService - 작성자 추가
//답변 저장 시 질문 객체와 답변 내용을 입력받아서 답변을 등록
public void create(Question question,String content,SiteUser author ) {
Answer answer = new Answer(); //답변 객체 만드릭
answer.setContent(content);
answer.setCreateDate(LocalDateTime.now());//오늘날짜
answer.setQuestion(question);
answer.setAuthor(author);
this.aRepo.save(answer);//새 답변 입력
}
AnswerController
@Autowired
private UserService uService;
//답변 저장
@PostMapping("/create/{id}") //주소에 있는 변수 { }안에 넣기
public String createAnswer(Model model, @PathVariable("id") Integer id,
@Valid AnswerForm answerForm, BindingResult result,
Principal principal) {
Question question = this.qService.getQuestion(id);
SiteUser siteUser = this.uService.getUser(principal.getName()); //추가
if(result.hasErrors()) {
model.addAttribute("question", question);
return "question_detail";
}
//답변 저장
aService.create(question, answerForm.getContent(),siteUser);
return String.format("redirect:/question/detail/%s", id);//질문 상세보기 페이지로 리다이렉트
}
QuestionService에도 동일하게 작성자 추가함
//질문 등록 처리
public void create(String subject , String content,SiteUser user) { //파라미터 subject와 content가 들어감
Question q = new Question(); //객체를 생성해서 파라미터로 가져온 값을 넣는다.
q.setSubject(subject);
q.setContent(content);
q.setCreateDate(LocalDateTime.now());
q.setAuthor(user);
this.qRepo.save(q); // 저장한다.
}
QuestionController - 작성자 추가
@Autowired
private UserService uService;
//질문 등록 처리하기
@PostMapping("/create")
public String questionCreate(@Valid QuestionForm questionForm, BindingResult result,Principal principal) {
if(result.hasErrors()) {
return"question_form"; //유효성 검사 에러
}
SiteUser siteUser = uService.getUser(principal.getName());
qService.create(questionForm.getSubject(), questionForm.getContent(), siteUser);
return "redirect:/question/list"; //질문 저장 후 질문목록으로 이동
}
이렇게 바꾸면 test에서 오류남
작성자가 안들어가서그럼 null로 임시적으로 바꿔주면 오류 풀림
테스트하기
하지만 로그인을 안했을 경우에는 오류가 남
QuestionController
@PreAuthorize : 인증이 되어야 함
//질문 등록하기
@PreAuthorize("isAuthenticated()")
@GetMapping("/create")
public String questionCreate(QuestionForm questionForm) {
return "question_form";
}
//질문 등록 처리하기
@PreAuthorize("isAuthenticated()")
@PostMapping("/create")
public String questionCreate(@Valid QuestionForm questionForm, BindingResult result,Principal principal) {
if(result.hasErrors()) {
return"question_form"; //유효성 검사 에러
}
SiteUser siteUser = uService.getUser(principal.getName());
qService.create(questionForm.getSubject(), questionForm.getContent(), siteUser);
return "redirect:/question/list"; //질문 저장 후 질문목록으로 이동
}
AnswerController도 추가
//답변 저장
@PreAuthorize("isAuthenticated()")
@PostMapping("/create/{id}") //주소에 있는 변수 { }안에 넣기
public String createAnswer(Model model, @PathVariable("id") Integer id,
@Valid AnswerForm answerForm, BindingResult result,
Principal principal) {
Question question = this.qService.getQuestion(id);
SiteUser siteUser = this.uService.getUser(principal.getName()); //추가
if(result.hasErrors()) {
model.addAttribute("question", question);
return "question_detail";
}
//답변 저장
aService.create(question, answerForm.getContent(),siteUser);
return String.format("redirect:/question/detail/%s", id);//질문 상세보기 페이지로 리다이렉트
}
SecurityConfig
@EnableGlobalMethodSecurity(prePostEnabled = true) 추가
SecurityConfig에 적용한@EnableGlobalMethodSecurity 애너테이션의 prePostEnabled = true 설정은 QuestionController와 AnswerController에서 로그인 여부를 판별하기 위해 사용했던 @PreAuthorize 애너테이션을 사용하기 위해 반드시 필요하다.
테스트하기
1. 로그인 안 된 상태에서 질문 등록하기
2.로그인 페이지로 이동함
3. 정상적으로 로그인하면 원래 이동하려고 했었던 질문 등록 페이지로 바로 이동함
답변창도 로그인 여부에 따라 사용가능 하게끔 만듬
<!-- 비회원 시 -->
<textarea
sec:authorize="isAnonymous()"
disabled
th:field="*{content}"
rows="10"
class="form-control"
></textarea>
<!-- 로그인 시 -->
<textarea
sec:authorize="isAuthenticated()"
th:field="*{content}"
rows="10"
class="form-control"
></textarea>
테스트
1. 로그인 안됐을 때 - 답변 창 비활성화
2. 로그인 시 - 답변 창 활성화
글 목록에도 글쓴이 추가
question_list.html
<tbody>
<tr th:each="question, loop : ${paging}">
<td
th:text="${paging.getTotalElements - (paging.number * paging.size) - loop.index}"
></td>
<td>
<a
th:href="@{/question/detail/__${question.id}__}"
th:text="${question.subject}"
></a>
<span
class="text-danger small ms-2"
th:if="${#lists.size(question.answerList)>0}"
th:text="${#lists.size(question.answerList)}"
>
</span>
</td>
<td>
<span
th:if="${question.author != null}"
th:text="${question.author.username}"
></span>
</td>
<td
th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"
></td>
</tr>
</tbody>
테스트하기
질문 상세보기에도 작성자 이름을 추가한다.
question_detail.html
<!-- 질문 -->
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
<div
class="card-text"
style="white-space: pre-line"
th:text="${question.content}"
></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<div class="mb-2">
<span
th:if="${question.author != null}"
th:text="
${question.author.username}"
></span>
</div>
<div
th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"
></div>
</div>
</div>
</div>
</div>
<!-- 답변 반복 시작 -->
<div class="card my-3" th:each="answer : ${question.answerList}">
<div class="card-body">
<div
class="card-text"
style="white-space: pre-line"
th:text="${answer.content}"
></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<div class="mb-2">
<span
th:if="${answer.author != null} th:text="
${question.author.username}
></span>
</div>
<div
th:text="${#temporals.format(answer.createDate, 'yyyy-MM-dd HH:mm')}"
></div>
</div>
</div>
</div>
</div>
테스트하기
'BACKEND > SpringBoot' 카테고리의 다른 글
질문 삭제 처리 (0) | 2023.11.10 |
---|---|
질문 수정 처리 (0) | 2023.11.10 |
로그아웃 처리 (0) | 2023.11.10 |
로그인 구현 (0) | 2023.11.10 |
회원가입 처리(유효성검사, 비밀번호 암호화, 중복회원가입처리) (0) | 2023.11.10 |