IT 프로젝트/블로그 만들기

[Spring Boot] 스프링 부트 프로젝트/블로그 만들기 - 관리자(admin) 사용자(users) 페이지 만들기

happygram 2019. 2. 2. 00:43

관리자 페이지 기능 중 '사용자' 관리하는 페이지를 작성합니다.


기능 목록

  • 사용자 추가/조회


소스

users.html
<th:block th:include="admin/users-js"></th:block>
<h3>사용자 <small>사용자를 관리합니다.</small></h3>
<div class="box box-primary">
    <div class="box-header with-border">
        <h3 class="box-title">입력</h3>
    </div>
    <!-- /.box-header -->
    <!-- form start -->
    <form role="form" th:action="@{/users}" method="post">
        <div class="box-body">
            <div class="form-group">
                <label for="username">아이디</label>
                 <input type="text" class="form-control" id="username" name="username" placeholder="아이디를 입력하세요." required>
            </div>
            <div class="form-group">
                <label for="password">비밀번호</label>
                <input type="password" class="form-control" id="password" name="password" placeholder="패스워드를 입력하세요." required>
            </div>
            <input type="submit" class="btn btn-primary" value="저장"/>
        </div>
        <!-- /.box-body -->
    </form>
</div>
 
<div class="box box-primary">
    <div class="box-header with-border">
        <h3 class="box-title">목록</h3>
    </div>
    <div class="content">
        <table id="user_table" class="table table-striped table-bordered" style="width: 100%">
            <thead>
                <tr>
                    <th>UserName</th>
                    <th>Enabled</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                </tr>
            </tbody>
        </table>
    </div>
</div>
cs


아이디, 비밀번호를 입력한 후 저장할 수 있습니다.

저장한 사용자는 테이블의 형태로 조회할 수 있습니다.


users-js.html
<script th:inline="javascript">
$(function(){
    // Ajax call for category
    $.ajax({
        method : 'GET',
        url: BASE_CONTEXT_PATH + 'users',
    }).done(function(result){
        console.log(result);
        // Category tables
        $('#user_table').DataTable({
            data : result,
            columns: [
                { data: 'username' },
                { data: 'enabled' },
            ]
        });
    }).fail(function(xhr, ajaxOptions, thrownError){
        alert(xhr);
    });
});
</script>
cs


'DataTable' 을 이용하여 사용자를 조회를 합니다.

사용자 이름과 사용 여부를 조회합니다.

'DataTable' 은 Javascript 라이브러리로 테이블에 유용한 기능을 제공합니다.

(페이징 처리, 검색, 컬럼 정렬 등)


DataTable 참조 사이트



UsersController.java
package project.blog.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.RedirectView;

import project.blog.dto.UsersDto;
import project.blog.service.UsersService;

@Controller
@RequestMapping("/users")
public class UsersController {

	@Autowired
	private UsersService usersService;

	@GetMapping
	public @ResponseBody List<UsersDto> getUsers() {
		return usersService.getUsers();
	}
	
	@PostMapping
	public RedirectView newUsers(@ModelAttribute UsersDto userDto) {
		usersService.newUsers(userDto);
		return new RedirectView("/admin/users");
	}
}

사용자 서비스를 호출하여, 사용자를 추가하거나, 사용자를 조회합니다.


소스 설명

	@GetMapping
	public @ResponseBody List<UsersDto> getUsers() {
		return usersService.getUsers();
	}

사용자의 목록을 가져옵니다.


	@PostMapping
	public RedirectView newUsers(@ModelAttribute UsersDto userDto) {
		usersService.newUsers(userDto);
		return new RedirectView("/admin/users");
	}

사용자의 정보를 받아서 사용자를 등록합니다.

등록 후 사용자 관리 페이지로 이동합니다.


UsersService.java
package project.blog.service;

import java.util.List;
import java.util.stream.Collectors;

import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import project.blog.domain.Authorities;
import project.blog.dto.UsersDto;
import project.blog.repository.AuthoritiesRepository;
import project.blog.repository.UsersRepository;

@Service
public class UsersService {
	
	@Autowired
	private UsersRepository usersRepository;
	
	@Autowired
	private AuthoritiesRepository authoritiesRepository;
	
	@Autowired
	private ModelMapper modelMapper;
	
	public List<UsersDto> getUsers(){
		return usersRepository.findAll().stream().map(users -> modelMapper.map(users, UsersDto.class)).collect(Collectors.toList());
	}
	
	@Transactional
	public UsersDto newUsers(UsersDto usersDto) {
		// 사용자 저장
		// 암호화
		usersDto.setPassword(new BCryptPasswordEncoder().encode(usersDto.getPassword()));
		UsersDto resultDto = modelMapper.map(usersRepository.save(usersDto.toEntity()), UsersDto.class);
		// 권한 저장
		authoritiesRepository.save(Authorities.builder()
											.username(usersDto.getUsername())
											.authority("ROLE_ADMIN")
											.build());
		return resultDto;
	}
}

사용자 서비스에서 필요한 처리를 Repository 를 통해서 처리하고 있습니다.

실제 데이터 접근은 Repository 에서 합니다.


소스 설명

	public List<UsersDto> getUsers(){
		return usersRepository.findAll().stream().map(users -> modelMapper.map(users, UsersDto.class)).collect(Collectors.toList());
	}

사용자 전체 목록을 가져옵니다.


	@Transactional
	public UsersDto newUsers(UsersDto usersDto) {
		// 사용자 저장
		// 암호화
		usersDto.setPassword(new BCryptPasswordEncoder().encode(usersDto.getPassword()));
		UsersDto resultDto = modelMapper.map(usersRepository.save(usersDto.toEntity()), UsersDto.class);
		// 권한 저장
		authoritiesRepository.save(Authorities.builder()
											.username(usersDto.getUsername())
											.authority("ROLE_ADMIN")
											.build());
		return resultDto;
	}

입력받은 사용자 정보를 저장합니다.

비밀번호는 'BCryptPasswordEncoder 클래스를 이용하여 암호화합니다.

현재 소스 예제에서는 권한을 'ROLE_ADMIN' 으로 고정 하였지만, 권한을 세분화 하여 'ROLE_' prefix 를 붙여서 저장하여 관리할 수 있습니다.


UsersRepository.java
package project.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import project.blog.domain.Users;

public interface UsersRepository extends JpaRepository<Users, String> {
	
}

JpaRepository 기본 제공하는 메소드를 사용하므로, 추가로 구현한 메소드는 존재하지 않습니다.


UsersDto.java
package project.blog.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import project.blog.domain.Users;

@Getter
@Setter
@NoArgsConstructor
public class UsersDto {
	private String username;
	private String password;
	private boolean enabled;
	
	public Users toEntity(){
        return Users.builder()
        		.username(username)
        		.password(password)
        		.enabled(enabled)
                .build();
    }
}

서비스에서 DTO 를 사용하여 Controller 와 통신합니다.


Users.java
package project.blog.domain;

import javax.persistence.Entity;
import javax.persistence.Id;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class Users {
	@Id
    private String username;
	private String password;
    private boolean enabled;
    
    @Builder
    public Users(String username, String password, boolean enabled) {
    	this.username = username;
    	this.password = password;
    	this.enabled = enabled;
    }
}

테이블과 직접 매핑하는 domain 클래스를 생성 합니다


결과


참조 라이브러리 사이트 목록 - 도움에 감사를 드립니다.

https://jquery.com/

https://getbootstrap.com/

https://startbootstrap.com/template-overviews/clean-blog/