if (authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) { redirectStrategy.sendRedirect(request, response, "/admin"); } 예를 들어 위와 같이 authorization이 성공한 상황에서 Authentication 객체에서 권한을 가지고 있는지 여부를 알고싶으면 위와 같이 작성한다. 여기서 핵심은 "ROLE_ADMIN"을 contains 하고 있는지 확인하는 것이 아닌 new SimpleGrantedAuthority("ROLE_ADMIN")을 확인하는 것이다. SimpleGrantedAuthority는 GrantedAuthority의 이미 만들어져 있는 구현..
코드 출처: https://velog.io/@peppermint100/Spring-Boot-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC 스프링부트의 예외 처리에 있어서 가장 핵심은 값에 대한 validation을 계속 순차적으로 진행하면서 생기는 exception을 단 하나의 객체에서만 처리하고 그 객체를 위로 던지는 것이다. @PostMapping("/login") //모든 exception을 담아줄 response객체를 return. public ResponseEntity login(@RequestBody LoginRequest loginRequest) throws Exception { //service layer에서 login 처리 후 token을 리턴 String token..
값의 변화점을 예측하기 힘들어지기에 무지성 Setter는 지양해야 한다. 지금 당장에는 문제가 생기지 않을지라도 이후에 Setter에 의한 문제가 발생할 여지를 남겨두는 것은 좋지 않다. 그러면 Setter없이 어떻게 Entity를 update 할 수 있을까? 핵심은 한가지다. update가 필요한 값만을 받는 메서드를 따로 생성해서 그것을 명시적으로 사용하는 것. 코드로 보면 간단하다. @RestController ... @PostMapping("/update/{id}") public void updateCategory(@PathVariable("id") Long id, @RequestBody CategoryDto categoryDto) { categoryService.updateById(id, cat..
빈 배열만 출력된다는 것은 [ {}, {}... {} ]으로 보이지만 실제 값은 [ { "id" : null, "username" : null} ]처럼 보여 빈 배열로 출력되는 것처럼 보이는 것이다. 이 문제는 객체에 접근해야하는 Hibernate와 HttpMessageConverter가 Entity의 property에 접근하지 못하여 null값을 반환하게 되는 것이다. @Getter(AccessLevel.PUBLIC) 해결 방법은 Getter를 생성해주고 접근 레벨을 public으로 해주는 것이다.
@PreAuthorize()는 메서드를 실행하기 전에 하는 권한 검사 @PostAuthorize()는 메서드를 실행하고 클라이언트에게 응답을 하기 직전에 하는 권한 검사 라는 차이점을 가지고 있다. hasRole([role]) : 현재 사용자의 권한이 파라미터의 권한과 동일한 경우 true hasAnyRole([role1,role2]) : 현재 사용자의 권한디 파라미터의 권한 중 일치하는 것이 있는 경우 true principal : 사용자를 증명하는 주요객체(User)를 직접 접근할 수 있다. authentication : SecurityContext에 있는 authentication 객체에 접근 할 수 있다. permitAll : 모든 접근 허용 denyAll : 모든 접근 비허용 isAnonymou..
JPA에서는 @Embeddable 애너테이션을 이용하여 해당 클래스가 다른 Entity에 의해 프로퍼티 값으로 들어갈 수 있음(embedded)을 의미한다. public class Company { private Integer id; private String name; private String address; private String phone; private String contactFirstName; private String contactLastName; private String contactPhone; // standard getters, setters } 회사라는 클래스에 있는 평범한 프로퍼티들이지만 연락할 수 있는 인원에 대한 정보는 따로 빼는 것이 좋아 보일때 @Embeddable p..
@SQLDelete(sql = "UPDATE USER SET deleted=true where id=?") soft deletion은 유저의 입장에서는 삭제되어 보이지 않는 값이지만 DB에는 삭제하지 않고 남겨두는 방식이다. 해당 Entity 테이블에 deleted라는 컬럼에 flag와 같이 true, false로 나타내어 구현한다. JPA에서는 해당 어노테이션이 있으면 delete를 수행하는 대신 update를 통해 flag를 true로 하여 외부로는 보이지 않게 해주어 간단하게 구현할 수 있다. @SQLDelete(sql = "UPDATE user SET deleted=true WHERE id=?") @Where(clause = "deleted=false") 매번 deleted=false인 데이터만 ..
IoC를 통한 DI를 받는 방법은 @Autowired를 통한 방법과 생성자를 기반으로 받을 수 있다. @RequiredConstructor를 통해(혹은 그냥 생성자를 통해) private final Repository repository와 같이 주입을 받게 되면 불변성을 얻게 되어 실행 중 객체가 변하는 것을 막을 수 있고 이로 인해 오류를 방지할 수 있다. 코드의 품질도 높아지며 순환 참조를 방지하는 등의 부가적인 이득도 있다. Autowired를 지양하고 private final을 생성자로 생성하도록 하자
@AllArgsConstructor는 필드에 존재하는 모든 변수들을 받는 생성자를 생성하는데 필드 변수의 순서에도 영향을 받아 순서에 의해 에러가 발생할 수도 있다. 그리고 접근할 필요가 없는 필드값에 대해서 접근할 수 있게되어 접근가능성을 오히려 최대화하는 문제가 생긴다. 꼭 받고 나가야 되는 필드값만 넣는 생성자를 따로 만들어서 쓰도록 하자 @Setter는 데이터값이 변경되도록 의도된 DTO와 같은 곳에서는 자유롭게 사용하지만 @Entity와 같이 외부에서의 접근가능성을 최소화하여 안정성을 최대화해야 할 때에는 @Setter를 지양해야 한다. 이때 @Setter를 대체하는 방법으로는 어떤 특별한 의미가 있는(update, pointUp 등)과 같이 메서드를 만들어 그 메서드를 통해 꼭 필요한 파라미터..
JPA에서는 프록시 생성을 위해 @NoArgsConstructor를 강제하게 되는데 이때 ACCESSLEVEL을 따로 걸지 않으면 외부에서 생성자에 쉽게 접근할 수 있게 된다. 유지보수성을 최대화하고 접근가능성을 최소화하기 위해 ACCESSLEVEL을 PROTECTED 이하로 거는 것이 좋다. //@NoArgsConstructor(access = AccessLevel.PROTECTED) ... User user = new User(); //컴파일 에러 발생
- Total
- Today
- Yesterday
- lunarvim
- ModelAttribute
- neovim
- JavaScript
- vim
- RequestBody
- 도커
- 루나빔
- RequestParam
- RequestPart
- 레디스
- 배포
- 아키텍처
- Dap
- IDE
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |