Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/codesquad/WebMvcConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public void addFormatters(FormatterRegistry registry) {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
//classpath 있으면 안되나?
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(30);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/codesquad/domain/Issue.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
import support.domain.AbstractEntity;

import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Issue extends AbstractEntity {

@NotEmpty
@Size(min = 3, max = 50)
@Column(nullable = false, length = 50)
private String subject;

@NotEmpty
@Size(min = 3, max = 500)
@Column(nullable = false, length = 500)
private String comment;
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/codesquad/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,32 @@
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.Objects;

@Entity
public class User extends AbstractEntity {
public static final GuestUser GUEST_USER = new GuestUser();

@Size(min = 3, max = 20)
@NotEmpty
@Size(min = 2, max = 20)
@Column(unique = true, nullable = false, length = 20)
private String userId;

@Size(min = 6, max = 20)
@NotEmpty
@Size(min = 4, max = 20)
@Column(nullable = false, length = 20)
@JsonIgnore
private String password;

@Size(min = 3, max = 20)
@NotEmpty
@Size(min = 2, max = 20)
@Column(nullable = false, length = 20)
private String name;



public User() {
}

Expand Down
21 changes: 21 additions & 0 deletions src/main/java/codesquad/validate/RestResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package codesquad.validate;

import java.util.HashMap;
import java.util.Map;

public class RestResponse extends RestStatus {
private Map<String, Object> result;

public RestResponse() {
super(true);
result = new HashMap<>();
}

public void addAttribute(String key, Object value) {
result.put(key, value);
}

public Map<String, Object> getResult() {
return result;
}
}
18 changes: 18 additions & 0 deletions src/main/java/codesquad/validate/RestStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package codesquad.validate;

public class RestStatus {
private boolean status;

public RestStatus(boolean status) {
this.status = status;
}

public boolean isStatus() {
return status;
}

@Override
public String toString() {
return "RestResponse [status=" + status + "]";
}
}
25 changes: 25 additions & 0 deletions src/main/java/codesquad/validate/ValidationError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package codesquad.validate;

public class ValidationError {
private String fieldName;

private String errorMessage;

public ValidationError(String fieldName, String errorMessage) {
this.fieldName = fieldName;
this.errorMessage = errorMessage;
}

public String getFieldName() {
return fieldName;
}

public String getErrorMessage() {
return errorMessage;
}

@Override
public String toString() {
return "ValidationError [fieldName=" + fieldName + ", errorMessage=" + errorMessage + "]";
}
}
21 changes: 21 additions & 0 deletions src/main/java/codesquad/validate/ValidationErrorsResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package codesquad.validate;

import java.util.ArrayList;
import java.util.List;

public class ValidationErrorsResponse extends RestStatus {
private List<ValidationError> errors;

public ValidationErrorsResponse() {
super(false);
errors = new ArrayList<>();
}

public void addValidationError(ValidationError error) {
errors.add(error);
}

public List<ValidationError> getErrors() {
return errors;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package codesquad.validate;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

@RestControllerAdvice
public class ValidationExceptionControllerAdvice {
private static final Logger log = LoggerFactory.getLogger(ValidationExceptionControllerAdvice.class);

@Resource(name = "messageSourceAccessor")
private MessageSourceAccessor msa;

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ValidationErrorsResponse handleValidationException(MethodArgumentNotValidException exception) {
List<ObjectError> errors = exception.getBindingResult().getAllErrors();
ValidationErrorsResponse response = new ValidationErrorsResponse();
for (ObjectError objectError : errors) {
log.debug("object error : {}", objectError);
FieldError fieldError = (FieldError) objectError;
response.addValidationError(new ValidationError(fieldError.getField(), getErrorMessage(fieldError)));
}
return response;
}

private String getErrorMessage(FieldError fieldError) {
Optional<String> code = getFirstCode(fieldError);
if (!code.isPresent()) {
return null;
}

String errorMessage = msa.getMessage(code.get(), fieldError.getArguments(), fieldError.getDefaultMessage());
log.info("error message: {}", errorMessage);
return errorMessage;
}

private Optional<String> getFirstCode(FieldError fieldError) {
String[] codes = fieldError.getCodes();
if (codes == null || codes.length == 0) {
return Optional.empty();
}
return Optional.of(codes[0]);
}
}
5 changes: 4 additions & 1 deletion src/main/java/codesquad/web/AttatchmentController.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import javax.naming.CannotProceedException;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;

Expand Down Expand Up @@ -53,7 +54,9 @@ public ResponseEntity<FileSystemResource> download(@PathVariable long id) throws

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_XML);
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + saveName);
String encoredFilename = URLEncoder.encode(saveName, "UTF-8").replace("+", "%20");
headers.set(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=" + encoredFilename + ";filename*= UTF-8''" + encoredFilename);
headers.setContentLength(resource.contentLength());
log.debug("!!!@#!@# {}", headers);
return new ResponseEntity<FileSystemResource>(resource, headers, HttpStatus.OK);
Expand Down
22 changes: 20 additions & 2 deletions src/main/java/codesquad/web/IssueController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

import java.util.List;

import static org.slf4j.LoggerFactory.getLogger;

@Controller
Expand Down Expand Up @@ -44,7 +48,14 @@ public String createIssue(@LoginUser User user) {
}

@PostMapping("")
public String create(@LoginUser User user , @Valid IssueDto issueDto) {
public String create(@LoginUser User user , @Valid IssueDto issueDto, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
for (ObjectError error : errors) {
log.debug("issue create error : {}", error.getDefaultMessage());
}
return "redirect:/issues";
}
log.debug("IssueDto : {}", issueDto.toString());
issueService.add(user ,issueDto);
return "redirect:/";
Expand All @@ -68,7 +79,14 @@ public String update(@LoginUser User loginUser, @PathVariable long id, Model mod
}

@PutMapping("/{id}")
public String updated(@LoginUser User loginUser, @PathVariable long id, IssueDto target) {
public String updated(@LoginUser User loginUser, @PathVariable long id, IssueDto target, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
for (ObjectError error : errors) {
log.debug("update error : {}",error.getDefaultMessage());
}
return "redirect:/users/{id}/update";
}
issueService.update(loginUser, id, target);
return "redirect:/";
}
Expand Down
24 changes: 21 additions & 3 deletions src/main/java/codesquad/web/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

@Controller
@RequestMapping("/users")
Expand All @@ -26,7 +30,14 @@ public String form() {
}

@PostMapping("")
public String create(UserDto userDto) {
public String create(@Valid UserDto userDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
for (ObjectError error : errors) {
log.debug("error~~~ : {}", error.getDefaultMessage());
}
return "redirect:/users/form";
}
userService.add(userDto);
return "redirect:/login";
}
Expand All @@ -35,14 +46,21 @@ public String create(UserDto userDto) {
public String updateForm(@LoginUser User loginUser, @PathVariable long id, Model model) {
log.debug("LoginUser : {}", loginUser);
log.debug("login id : {}", id);
log.debug("user test :",userService.findById(id));
log.debug("user test :", userService.findById(id));

model.addAttribute("user", userService.findById(id));
return "/user/updateForm";
}

@PutMapping("/{id}")
public String update(@LoginUser User loginUser, @PathVariable long id, UserDto target) {
public String update(@LoginUser User loginUser, @PathVariable long id, UserDto target, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
for (ObjectError error : errors) {
log.debug("user update error : {}", error.getDefaultMessage());
}
return "redirect:/users/{id}/form";
}
userService.update(loginUser, id, target);
return "redirect:/";
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/messages.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Size.userDto.userId=User {0} must be between {2} and {1}.
NotEmpty.userDto.userId= User {0} is required.
Size.userDto.password=User {0} must be between {2} and {1}.
Size.userDto.name=User {0} must be between {2} and {1}.
size.issueDto.subject=Issue {0} must be between {2} and {1}.
size.issueDto.comment=Issue {0} must be between {2} and {1}.
size.answer.comment=Answer {0} must be between {2} and {1}.
2 changes: 1 addition & 1 deletion src/test/java/codesquad/domain/UserValidationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void setup() {
public void userIdWhenIsEmpty() throws Exception {
User user = new User("", "password", "name");
Set<ConstraintViolation<User>> constraintViolcations = validator.validate(user);
assertThat(constraintViolcations.size(), is(1));
assertThat(constraintViolcations.size(), is(2));

for (ConstraintViolation<User> constraintViolation : constraintViolcations) {
log.debug("violation error message : {}", constraintViolation.getMessage());
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/codesquad/web/ApiIssueAcceptanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public void create() {
softly.assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
}

@Test
public void create_valdiation() {
Issue issue = new Issue("1", "2", UserTest.USER, false);
ResponseEntity<String> response = basicAuthTemplate(UserTest.USER).postForEntity("/api/issues", issue, String.class);
softly.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}

@Test
public void create_without_login() {
ResponseEntity<Issue> response = template().postForEntity("/api/issues", issue, Issue.class);
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/codesquad/web/ApiUserAcceptanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public void create() throws Exception {

}

@Test
public void create_invalid() throws Exception {
UserDto newUser = new UserDto("1", "1", "1");
ResponseEntity<String> response = template().postForEntity("/api/users", newUser, String.class);
softly.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}

@Test
public void show_다른_사람() throws Exception {
UserDto newUser = createUserDto("testuser2");
Expand Down