반응형

저번에는 홍길동이라는 이름으로 글쓴이로 작성되었다.

이제는 user와 board를 

일대 다로 하여 글을 쓰면 글쓴이로 등록되게 해보자 

 

우선 user_id를 조인한다고 생각하자 

 

그 후 모델 객체에 어노테이션을 추가하자 

 

import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Entity
@Data
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @NotNull
    @Size(min = 2,max = 30 , message = "제목은 2자이상 30자 이하 입니다.")
    private String title;
    @NotNull
    @Size(min = 1, message = "내용을 입력해주세요.")
    private String content;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private  User user;
}

그 후 글을 쓰려면 

인증정보를 가져와야한다. 

 

    @PostMapping("/form")
    public String postForm(@Valid Board board, BindingResult bindingResult , Authentication authentication){
//        vaildator.validate(board,bindingResult);
        if(bindingResult.hasErrors()){
            return "board/form";
        }
        String username = authentication.getName();
        boardService.save(username,board);
//        boardRepository.save(board);
        return "redirect:/board/list";
    }
}
String username = authentication.getName();

로 인증정보를 가져올 수있다. 

 

@Autowired
private BoardRepository boardRepository;

@Autowired
private UserRepository userRepository;
public Board save(String username , Board board){
 User user =  userRepository.findByUsername(username);
 board.setUser(user);

 return boardRepository.save(board);

}

그 후 서비스로 넘어와 save() 메소드를 작성 해준다. 

유저 레포지토리에서 유저를 먼저 찾아 board.setUser에 담아준다. 

그 후 save(board)를 해주면 된다. 

 

홍길동에서 변경된걸 볼 수 있다.

반응형
반응형

저번에는 회원가입 처리를 해보았다.

이제는 로그인 처리를 해보자 

 

로그인을 위해 

 타임리프 엑스트라스 스프링5 디펜던시 추가를 해준다.

 

<dependency>
   <groupId>org.thymeleaf.extras</groupId>
   <artifactId>thymeleaf-extras-springsecurity5</artifactId>
   <version>3.0.4.RELEASE</version>
</dependency>

 

 

를 추가 해준다.

 

그 후 https://www.thymeleaf.org/doc/articles/springsecurity.html 

 

Thymeleaf + Spring Security integration basics - Thymeleaf

Have you switched to Thymeleaf but your login and error pages are still using JSP? In this article we will see how to configure your Spring application to use Thymeleaf for login and error pages. All the code seen here comes from a working application. You

www.thymeleaf.org

를 참고 하여 

 

<div sec:authorize="isAuthenticated()">
  This content is only shown to authenticated users.
</div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
  This content is only shown to administrators.
</div>
<div sec:authorize="hasRole('ROLE_USER')">
  This content is only shown to users.
</div>

를 이용하여 로그인 처리 및 로그아웃 처리를 해준다 !

 

<!DOCTYPE>

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
>
<head th:fragment="head(title)">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
    <link href="starter-template.css" th:href="@{/css/starter-template.css}" rel="stylesheet">

    <title th:text="${title}"></title>
</head>
<body>

<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:fragment="menu(menu)">
    <a class="navbar-brand" href="#">Spring Boot</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarsExampleDefault">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item " th:classappend="${menu} == 'home' ? 'active'">
                <a class="nav-link" href="#"  th:href="@{/}">홈 <span class="sr-only" th:if="${menu} == 'home'">(current)</span></a>
            </li>
            <li class="nav-item" th:classappend="${menu} == 'board' ? 'active'">
                <a class="nav-link" href="#" th:href="@{/board/list}">게 시 판 <span class="sr-only" th:if="${menu} == 'board'">(current)</span> </a>
            </li>
        </ul>
            <a class="btn btn-secondary my-2 my-sm-0"  sec:authorize="!isAuthenticated()"th:href="@{/account/login}">Login</a>
             <a class="btn btn-secondary my-2  mx-2 my-sm-0"  sec:authorize="!isAuthenticated()"th:href="@{/account/register}">Sign Up</a>
        <form class="form-inline my-2 my-lg-0" sec:authorize="isAuthenticated()" th:action="@{/logout}" method="post">
            <span class="text-white" sec:authentication="name" >사용자</span>
            <span class="text-white mx-2" sec:authentication="principal.authorities" >권한</span>
            <button class="btn btn-secondary my-2 my-sm-0" type="submit">Logout</button>
        </form>
    </div>
</nav>

 

반응형
반응형

우선 스프링 시큐리티를 사용하기 위해 

 

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-test</artifactId>
  <scope>test</scope>
</dependency>

 

디펜던시를 추가해 주자 

이렇게 하면 스프링 시큐리티를 쓸 준비는 끝난다 

이제 회원가입을 위해 User Table과 User Model 을 생성해보자

 

이런식으로 추가 해줬다.

그후 

 

package com.seogi.myhome.model;

import lombok.Data;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String username;
    private String password;
    private boolean enabled;

이렇게 모델 객체를 생성해준다. 

 

그 후 config 패키지를 생성을 해주고 

WebSecurityConfig를 만들어준다. 

https://www.baeldung.com/spring-security-jdbc-authentication

 

Spring Security: Exploring JDBC Authentication | Baeldung

Explore the capabilities offered by Spring to perform JDBC Authentication using an existing DataSource configuration.

www.baeldung.com

사이트는 이곳을 참고 하였다. 

 

package com.seogi.myhome.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/" , "/account/register","/css/**" ).permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/account/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .passwordEncoder(passwordEncoder()) // 비밀번호를 암호화 하는 작업
                // 인증처리
                .usersByUsernameQuery("select username,password,enabled "
                        + "from user "
                        + "where username = ?")
                // 권한처리
                .authoritiesByUsernameQuery("select u.username,r.name "
                        + "from user_role ur inner join user u on  ur.user_id = u.id "
                        + "inner join role r on ur.role_id = r.id "
                        + "where u.username = ?");
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

이렇게 추가해준다. 

이렇게 할 경우에 antMatchers 에 인증처리가 없어도 접속할 수있는

페이지를 설정해주고 

loginPage는 login api를 설정해준다.ㅣ 

 

그후 PasswordEndcoder를 설정하여 회원가입을 할때 

비밀번호를 단반향으로 암호화에 필요한 걸 빈등록을해준다. 

 

그 후 configureGlobal을 하나 만들어준다. 

인증 처리에 관한 데이터 소스를 처리해준다.

이곳에 대해서는 나중에 many to many로 다대다 조인을 할 것이다. 

 

그 후 role 테이블을 만들어 이곳에는 인증에 대한 테이블이다

조인에 필요한 테이블을 생성해 준다.

 

테이블을 생성해 주었다면 모델 객체도 만들어주자

 

package com.seogi.myhome.model;

import lombok.Data;

import javax.persistence.*;
import java.util.List;

@Entity
@Data
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String name;

부트스트랩에서 로그인 페이지 샘플을 가져온다.

 

https://getbootstrap.com/docs/4.6/examples/

 

Examples

Quickly get a project started with any of our examples ranging from using parts of the framework to custom components and layouts.

getbootstrap.com

컨트롤러를 만들어 주어 로그인 페이지에 접근할 수 있도록 만들어준다. 

 

@GetMapping("/login")
public String loing(){
    return "account/login";
}

그 후 타임리프 th:if로 

<div th:if="${param.error}" class="alert alert-danger" role="alert">
    Invalid username and password.
</div>

</div>
<div th:if="${param.logout}" class="alert alert-light" role="alert">
    로그아웃 되었습니다.
</div>

에러를 처리해준다. 

 

이렇게 처리 되었다. 

 

그 후 로그인을 위해 회원가입 페이지를 만들어야겠다. 

회원가입 페이지는 간단하게 로그인 페이지를 카피하여 살짝 수정하여 재활용 하자 

 

페이지까지 만들었다면 

@ManyToMany 설정해준다. 

 

@ManyToMany
@JoinTable( name = "user_role", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")) // 조인될 상대 테이블을 적어준다.
private List<Role> roles = new ArrayList<>();
@ManyToMany(mappedBy = "roles")
private List<User> users;

이렇게 모델 객체에 추가하여준다. 

으로 조인해준다.


그 후 UserRepository를 만들어준다. 

 

package com.seogi.myhome.repository;

import com.seogi.myhome.model.Board;
import com.seogi.myhome.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User,Long> {
}

 

JPA를 쓸 준비는 끝낫다. 

 

이제 컨트롤러를 작성해주자 

 

@GetMapping ("/register")
public String register(){
    return "account/register";
}

으로 접속 할 수있게 해주고 

그 후 서비스를 작성해주자

 

package com.seogi.myhome.service;

import com.seogi.myhome.model.Role;
import com.seogi.myhome.model.User;
import com.seogi.myhome.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;

        public User save(User user){
            String encodedPassword = passwordEncoder.encode(user.getPassword());
            user.setPassword(encodedPassword);
            user.setEnabled(true);
            Role role = new Role();
            role.setId(1);
            user.getRoles().add(role);
            return userRepository.save(user);
        }


}

서비스에서는 Repositoy를 사용하기 위해 

AutoWired로 추가해 준뒤 

아까 빈 등록을 해준 비밀번호 단방향 암호화를 해줄

@Autowired
private PasswordEncoder passwordEncoder;

이 두개를 AutoWired로 추가 해준다. 

 

Save()라는 메소드를 작성해준다. 

먼저 파라미터로 비밀번호를 받아와 passwordencoder로 암호화를 해준뒤 

유저 권한인 setEnabled를 true를 바꿔준다. 

그후 Role 객체를 추가 해준다. 

1번으로 설정 해준다. 

 

1번은 Role_user 로 권한을 설정해준다.

 

그후 

private List<Role> roles = new ArrayList<>();

아까 모델객체에서 추가해준 roles 를 ArrayList로 바꿔준다.

 

@PostMapping("/register")
public String register(User user){
    userService.save(user);
    return "redirect:/";
}

이제 컨트롤러를 완성시켜준다. 

 

<form class="form-signin" th:action="@{/account/register}" method="post">

    <a th:href="@{/}"><img  class="mb-4" src="https://getbootstrap.com/docs/4.6/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72"></a>


    <h1 class="h3 mb-3 font-weight-normal">회원가입</h1>
    <label for="username" class="sr-only">UserName</label>
    <input type="text" id="username" class="form-control"  name="username"  required autofocus>
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="inputPassword" class="form-control" name="password" required>
    <div class="checkbox mb-3">
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    <p class="mt-5 mb-3 text-muted">&copy; 2017-2021</p>
</form>

 

이제 회원가입을 하면

 

이렇게 단방향으로 암호화가 되었다! 

 

잘 안된다면 아래의 소스코드를 확인해보자! 

 

 

https://github.com/MoonSeokHyun?tab=repositories 

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 7 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

우선 간단한 게시판을 만들고 있는데

이전에 배운 validation 체크를 해보려고 한다. 

방법은 매우 간단다하다. 

 

우선 부트스트랩 기능을 적극 이용할 예정이다. 

 

벨리데이션체크하는 방법은 

크게 두가지가 있는데 

 
첫번째는 model 객체에 vaild를 사용하여

@Size 등 어노테이션을 이용하는 것이다. 

 

 

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotNull
@Size(min = 2,max = 30 , message = "제목은 2자이상 30자 이하 입니다.")
private String title;
@NotNull
@Size(min = 1, message = "내용을 입력해주세요.")
private String content;

 

한다면 이와 같이 정의 할 수 있다. 

 

 <div class="form-group">
          <label for="title">제목</label>
          <input type="text"  class="form-control"  th:classappend="${#fields.hasErrors('title')} ? 'is-invalid'" id="title" th:field="*{title}" >
          <div class="invalid-feedback" th:if="${#fields.hasErrors('title')}" th:errors="*{title}">
            제목 에러메시지
          </div>
        </div>
        <div class="form-group">
          <label for="content">내용</label>
          <textarea class="form-control"  id="content" rows="3" th:field="*{content}"  th:classappend="${#fields.hasErrors('content')} ? 'is-invalid'"></textarea>
          <div class="invalid-feedback" th:if="${#fields.hasErrors('content')}" th:errors="*{content}">
            내용 에러메시지
          </div>

 

그 후 타임리프 th:if ="fields.haserrors"로에러가 있다면 에러 메시지를 반환한다.

 

보시다시피 #fields.hasErrors(...) 함수는 매개변수(datePlanted)로 필드 표현식을 수신하고 해당 필드에 유효성 검사 오류가 있는지 여부를 알려주는 부울 값을 반환합니다. 또한 해당 필드에 대한 모든 오류를 얻고 반복할 수 있습니다.

타임리프 공식홈페이지 발췌 

 

그 classAppend로 클래스를  추가해 준다. 

 

is-invalid

추가해 주면 된다.

 

두번째 방법을 알아보자 

 

import org.thymeleaf.util.StringUtils;

@Component
public class BoardVaildator implements Validator{

    @Override
    public boolean supports(Class<?> clazz) {
        return Board.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        Board board = new Board();
        if(StringUtils.isEmpty(board.getContent())){
            errors.rejectValue("content", "key" ,"내용을 입력하세요");
        }

    }
}

이 방법은 벨리데이션 메소드를 만들어 서비스와 같이 동작을 하게된다. 

 

    @PostMapping("/form")
    public String greetingSubmit(@Valid Board board, BindingResult bindingResult){
//        vaildator.validate(board,bindingResult);
        if(bindingResult.hasErrors()){
            return "board/form";
        }
        boardRepository.save(board);
        return "redirect:/board/list";
    }
}

form에 전달될때 validator로 검증을 하면 위와 같이 동작한다. 

 

1번의 경우는 간단하지만 세밀한 조정이 어렵다.

2번 같은경우는 세밀한 조정이 가능하지만 클래스를 하나 더 만들어야 한다. 

 

https://github.com/MoonSeokHyun/SpringBoot

반응형
반응형
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

먼저 사용을 위해 디펜던시를 추가 하자 

 

여기서 모든 정보를 보고싶다면

 

yml 파일에 

 

management:
  endpoints:
    web:
      exposure:
        include: "*"

을 추가 하면 

모든 api의 정보를 볼수 있다.

 

 

{
  "_links": {
    "self": {
      "href": "http://localhost:8088/actuator",
      "templated": false
    },
    "auditevents": {
      "href": "http://localhost:8088/actuator/auditevents",
      "templated": false
    },
    "beans": {
      "href": "http://localhost:8088/actuator/beans",
      "templated": false
    },
    "caches-cache": {
      "href": "http://localhost:8088/actuator/caches/{cache}",
      "templated": true
    },
    "caches": {
      "href": "http://localhost:8088/actuator/caches",
      "templated": false
    },
    "health-component-instance": {
      "href": "http://localhost:8088/actuator/health/{component}/{instance}",
      "templated": true
    },

 

완료!

반응형
반응형

Swagger란 개발한 REST API를 편리하게 문서화 해주고, 이를 통해서 편리하게 API를 호출해보고 테스트할 수 있는 프로젝트이다. 기본 swagger2 프로젝트 뿐 아니라 다양한 구성을 가지고 있다

 

API Documentation & Design Tools for Teams | Swagger

 

swagger.io

 

Swagger를 적용 시켜보자 

 

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

우선 이 두가지를 pom.xml에 적용시켜 보자 

 

그렇게 하면 메이븐에서 Swagger를 사용할 수 있게 된다. 

 

일단 config를 하나 생성해주자 

 

@Bean
public Docket api() {
    return new Docket(DocumentationType.SWAGGER_2)

}

이렇게 하면 완료 된다.

 

이렇게 편하게 문서 자동화가 가능하다. 

반응형
반응형

 

 

HATEOAS

(Hypermedia As the Enging Of Application State)

 

현재 리소스와 연관된(호출 가능한) 자원 상태 정보를 제공 -> 결국 하이퍼미디어 mapping !

 

RESTful API를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 하는데,

하나의 리소스에서 파생할 수 있는 여러가지 추가 작업의 정보들을 한번에 얻을 수 있다.

 

 

 

링크를 통해서 다른 페이지로 가는 것을 다른 상태로 전이한다고 보고

이 링크들에 대한 레퍼런스를 서버 측에서 전송한다.
그럼으로서 클라이언트가 명시적으로 링크를 작성하지 않고도 

서버 측에서 받은 링크의 레퍼런스를 통해 어플리케이션의 상태 및 전이를 표현할 수 있다. 
이것이 바로 올바른 REST 아키텍처에서의 HATEOAS 구성법이다.

 

장점
- 요청 URI가 변경되더라도 클라이언트에서 동적으로 생성된 URI를 사용함으로써, 

   클라이언트가 URI 수정에 따른 코드를 변경하지 않아도 되는 편리함을 제공한다.
- URI 정보를 통해 들어오는 요청을 예측할 수 있게 된다.
- Resource가 포함된 URI를 보여주기 때문에, Resource에 대한 확신을 얻을 수 있다

 

HATEOAS란? 

 

Hateoas란 REST Api를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 하는 것을 의미합니다. 이러한 방법은 클라이언트가 서버로부터 어떠한 요청을 할 때, 요청에 필요한 URI를 응답에 포함시켜 반환하는 것으로 가능하게 할 수 있습니다

라고 위키에 정의 되어 있다. 

 

HATEOAS를 사용해보자 

 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>

우선 디펜던스를 폼.xml에 추가 해보자 

 

이렇게 되면 우선 사용이 가능하다. 

 

 

@GetMapping("/users/{id}")
public Resource<User> retrieveUser(@PathVariable int id) {
    User user = service.findOne(id);

    if (user == null) {
        throw new UserNotFoundException(String.format("ID[%s] not found", id));
    }

    // HATEOAS
    Resource<User>  resource = new Resource<>(user);
    ControllerLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
    resource.add(linkTo.withRel("all-users"));

    return resource;
}

우선 User 객체를 반환한다. 

user 객체가 추가적으로 사용할 수 있는 정보(링크)를 하이퍼미디어 타입으로 넣어준다. 

이때 static 메소드를 사용하면 아래의 코드를 길게 쓰지 않아도 된다.

 

//ControllerLinkBuilder linkTo = ControllerLinkBuilder.linkTo(
        //ControllerLinkBuilder.methodOn(this.getClass()).retrieveAllUsers());

retrieveAllUsers() 메소드와 "all-users" 이름으로 링크를 작업한다. 

 

link작업이 완료 되었다.

반응형
반응형

다국어 처리를 위해 프로퍼티스파일에 저장을 해서 

컴퓨터에 저장된 언어코드에 따라서 서버에 지정된 내용으로 보여준다. 

 

일단 yml 파일에 프로퍼티스에 만들어줄 파일을 선언해준다.

 

spring:

  messages:
    basename: messages

우선 나는 messages라는 이름의 프로퍼티 파일을 만들 것이다.

 

 

이런 식으로 선언을 만들어 주면 된다. 

 

그후 메인 로컬에 있는 빈등록 을 해준다. 

 

@Bean
public LocaleResolver localeResolver() {
    SessionLocaleResolver localeResolver = new SessionLocaleResolver();
    localeResolver.setDefaultLocale(Locale.KOREA);
    return localeResolver;
}

그 다음 컨트롤러에서

 

@GetMapping(path = "/hello-world-internationalized")
public String helloWorldInternationalized(
        @RequestHeader(name="Accept-Language", required=false)  Locale locale) {
    return messageSource.getMessage("greeting.message", null, locale);
}

프로퍼티의 이름이 Greeting.message라면 해당 내용을 출력해준다!

 

 

반응형
반응형

@past 나 @Size로 Vaule값을 검증해보자 

 

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>

우선 벨리데이션을 쓰려면 

메이븐 타입이라면 추가해주자 

 

@Data
@AllArgsConstructor
@JsonIgnoreProperties(value = {"password","ssn"})
public class User {
    private Integer id;

    @Size(max=2, message = "Name은 두글자 이상 입력해주세요!")
    private String name;
    @Past
    private Date joinDate;

@Size를 걸어서 서버에서 Name값을 사이즈를 2미만이라면 예외처리를 해보자 

 

@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody User user){
    User savedUser = service.save(user);

    URI location =  ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
            .buildAndExpand(savedUser.getId()).toUri();

    return ResponseEntity.created(location).build();
}

@Vaild라는 어노테이션을 활용하여 구성하면 끝이난다.

반응형
반응형

예를 들면 1~3번 까지 기존 데이터가 있는데 

100번 데이터를 입력 했다고 가정해보자

그러면 오류가 날 것이다. 

 

이때 예외처리를 할 것이다. 

 

이전 DeleteUser에서 

 

if(user ==  null){
    throw new UserNotFoundExeception(String.format(id + " not pound"));
}

이것을 하기위해

UsernotFoundException이라는 클래스를 만들어 보자 

 

package com.example.restfulwebservice.user;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

// 2xx -> ok
// 4xx -> 클라이언트가 잘못
// 5xx -> 서버가 잘못
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundExeception extends RuntimeException {
    public UserNotFoundExeception(String message) {
        super(message);
    }
}
ResponseStatus

을 사용하여 Not Foind를 선택해준다. 

이것은 500에러를 404에러로 변경해주기도 한다. 

그 후 아까 지정한

 

user가 없으면 메시지를 출력해준다. 

 

if(user ==  null){
    throw new UserNotFoundExeception(String.format(id + " not pound"));
}

100을 입력하면 100은 없다고 메시지가 출력된다.

 

반응형

+ Recent posts