반응형
학습 목표
-객체 간의 관계 설정(@OneToMany, @ManyToOne 등)
학습 목차
4-1. 회원과 질문 간의 관계 매핑 및 리팩토링
4-2. 질문 상세보기 기능 구현
4-3. 질문 수정/삭제 기능 구현
4-4. 수정/삭제 기능에 대한 보안 처리 및 LocalDateTime 설정
4-5. 답변 추가 및 답변 목록 기능 구현
4-6. QuestionController 중복 제거 리팩토링
4-7. 원격 서버에 소스 코드 배포
//QuestionController.java
@Controller
@RequestMapping("/questions")
public class QuestionController {
@Autowired
private QuestionRepository questionRepository;
@GetMapping("/form")
public String form(HttpSession session) {
if(HttpSessionUtils.isLoginUser(session)) {
return "/users/loginForm";
}
return "/qna/form";
}
@PostMapping("")
public String create(String title, String contents, HttpSession session) {
if(!HttpSessionUtils.isLoginUser(session)) {
return "/users/loginForm";
}
User sessionUser=HttpSessoinUtils.getUserFromSession(session);
Question newQuestion=new Question(sessionUser, title, contents);
questionRepository.save(newQuestion);
return "redirect:/";
}
@GetMapping("/{id}")
public String show(@PathVariable Long id, Model model) {
model.addAttribute("question", questionRepository.findById(id).get());
return "/qna/show";
}
@GetMapping("/{id}/form")
public String updateForm(@PathVariable Long id, Model model, HttpSession session) {
try { //2.
Question question=questionRepository.findById(id).get();
hasPermission(session, question);
model.addAttribute("question", question);
return "/qna/updateForm";
} catch(IllegalStateException e) {
model.addAttribute("errorMessage", e.getMessage());
return "/user/login"; //3.
}
}
private boolean hasPermission(HttpSession session, Question question) { //1.
if(!HttpSessionUtils.isLoginUser(session) {
throw new IllegalStateException("로그인이 필요합니다.");
}
User loginUser=HttpSessionUtils.getUserFromSession(session);
if(question.isSameWriter(loginUser)) {
throw new IllegalStateException("자신이 쓴 글만 수정, 삭제가 가능합니다.");
}
return true;
}
@PutMapping("/{id}")
public String update(@PathVariable Long id, String title, String contents, Model model, HttpSession session) {
try { //2.
Question question=questionRepository.findById(id).get();
hasPermission(session, question);
question.update(title, contents);
questionRepository.save(question);
return String.format("redirect:/questions/%d", id);
} catch(IllegalStateException e) {
model.addAttribute("errorMessage", e.getMessage());
return "/user/login"; //3.
}
}
@DeleteMapping("/{id}")
public String delete(@PathVariable Long id, Model model, HttpSession session) {
try { //2.
Question question=questionRepository.findById(id).get();
hasPermission(session, question);
questionRepository.delete(id);
return "redirect:/";
} catch(IllegalStateException e) {
model.addAttribute("errorMessage", e.getMessage());
return "/user/login"; //3.
}
}
}
1. 중복 코드를 없애주기 위해 hasPermission 메소드를 만들어줍니다.
2. try catch문과 hasPermission 메소드를 이용해서 코드를 리팩토링 해줍니다.
3. return 주소를 잘못 설정해줌(/user/login으로 변경하기)
<!--login.html-->
<div class="container" id="main">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default content-main">
{{#errorMessage}} <!--1.-->
<div class="alert alert-danger" role="alert">{{this}}</div> <!--1.-->
{{/errorMessage}} <!--1.-->
<form name="question" method="post" action="/users/login">
<div class="form-group">
<label for="userId">사용자 아이디</label>
<input class="form-control" id="userId" name="userId" placeholder="User ID">
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-success clearfix pull-right">로그인</button>
<div class="clearfix" />
</form>
</div>
</div>
</div>
1. 에러 메시지를 연결해줍니다.
{{this}}: 자기 자신을 불러줌
//Result.java
public class Result {
private boolean valid;
private String errorMessage;
private Result(boolean valid, String errorMessage) {
this.valid=valid;
this.errorMessage=errorMessage;
}
public boolean isValid() {
return valid;
}
public String getErrorMessage() {
return errorMessage;
}
public static Result ok() {
return new Result(true, null);
}
public static Result fail(String errorMessage) {
return new Result(false, errorMessage);
}
}
Result.java는 hasPermission 메소드 대신 사용해줄 수 있는 클래스입니다.
//QuestionController.java
@Controller
@RequestMapping("/questions")
public class QuestionController {
@Autowired
private QuestionRepository questionRepository;
@GetMapping("/form")
public String form(HttpSession session) {
if(HttpSessionUtils.isLoginUser(session)) {
return "/users/loginForm";
}
return "/qna/form";
}
@PostMapping("")
public String create(String title, String contents, HttpSession session) {
if(!HttpSessionUtils.isLoginUser(session)) {
return "/users/loginForm";
}
User sessionUser=HttpSessoinUtils.getUserFromSession(session);
Question newQuestion=new Question(sessionUser, title, contents);
questionRepository.save(newQuestion);
return "redirect:/";
}
@GetMapping("/{id}")
public String show(@PathVariable Long id, Model model) {
model.addAttribute("question", questionRepository.findById(id).get());
return "/qna/show";
}
@GetMapping("/{id}/form")
public String updateForm(@PathVariable Long id, Model model, HttpSession session) {
Question question=questionRepository.findById(id).get(); //2.
Result result=valid(session, question); //2.
if(!result.isValid) { //3.
model.addAttribute("errorMessage", result.getErrorMessage());
return "/user/login";
}
model.addAttribute("question", question);
return "/qna/updateForm";
}
private Result valid(HttpSession session, Question question) { //1.
if(!HttpSessionUtils.isLoginUser(session) {
return Result.fail("로그인이 필요합니다.");
}
User loginUser=HttpSessionUtils.getUserFromSession(session);
if(question.isSameWriter(loginUser)) {
return Result.fail("자신이 쓴 글만 수정, 삭제가 가능합니다.");
}
return Result.ok();
}
private boolean hasPermission(HttpSession session, Question question) {
if(!HttpSessionUtils.isLoginUser(session) {
throw new IllegalStateException("로그인이 필요합니다.");
}
User loginUser=HttpSessionUtils.getUserFromSession(session);
if(question.isSameWriter(loginUser)) {
throw new IllegalStateException("자신이 쓴 글만 수정, 삭제가 가능합니다.");
}
return true;
}
@PutMapping("/{id}")
public String update(@PathVariable Long id, String title, String contents, Model model, HttpSession session) {
Question question=questionRepository.findById(id).get(); //2.
Result result=valid(session, question); //2.
if(!result.isValid) { //3.
model.addAttribute("errorMessage", result.getErrorMessage());
return "/user/login";
}
question.update(title, contents);
questionRepository.save(question);
return String.format("redirect:/questions/%d", id);
}
@DeleteMapping("/{id}")
public String delete(@PathVariable Long id, Model model, HttpSession session) {
Question question=questionRepository.findById(id).get(); //2.
Result result=valid(session, question); //2.
if(!result.isValid) { //3.
model.addAttribute("errorMessage", result.getErrorMessage());
return "/user/login";
}
questionRepository.delete(id);
return "redirect:/";
}
}
1. Result의 메소드를 만들어줍니다.
2. valid의 인자로 question이 필요하기 때문에 먼저 선언해줍니다.
Result 클래스를 이용해서 로그인 정보가 유효한지 확인합니다.
3. hasPermission을 대신해서 Result를 이용하여 리팩토링 합니다.
반응형
'Spring > 게시판 만들기 프로젝트' 카테고리의 다른 글
[Spring Boot] #5_1 게시판 만들기 (0) | 2020.12.23 |
---|---|
[Spring Boot] #4_2 게시판 만들기 (0) | 2020.12.22 |
[Spring Boot] #4_1 게시판 만들기 (0) | 2020.12.22 |
[Spring Boot] #3_2 게시판 만들기 (0) | 2020.12.21 |
[Spring Boot] #3_1 게시판 만들기 (0) | 2020.12.21 |