SpringBoot by Pankaj Sir
SpringBoot by Pankaj Sir
SpringBoot by Pankaj Sir
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
(
name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames = {"title"})}
)
public class Post {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY) )
private Long id;
spring.datasource.url =
jdbc:mysql://localhost:3306/myblog?useSSL=false&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = root
# hibernate properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
@Service
public class PostServiceImpl implements PostService {
@RestController
@RequestMapping("/api/posts")
public class PostController {
private PostService postService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException{
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
import com.springboot.blog.payload.PostDto;
import java.util.List;
List<PostDto> getAllPosts();
import com.springboot.blog.entity.Post;
import com.springboot.blog.exception.ResourceNotFoundException;
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.repository.PostRepository;
import com.springboot.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PostServiceImpl implements PostService {
@Override
public PostDto createPost(PostDto postDto) {
@Override
public List<PostDto> getAllPosts() {
List<Post> posts = postRepository.findAll();
return posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());
}
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.service.PostService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
import com.springboot.blog.payload.PostDto;
import java.util.List;
List<PostDto> getAllPosts();
import com.springboot.blog.entity.Post;
import com.springboot.blog.exception.ResourceNotFoundException;
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.repository.PostRepository;
import com.springboot.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PostServiceImpl implements PostService {
private PostRepository postRepository;
@Override
public PostDto createPost(PostDto postDto) {
@Override
public List<PostDto> getAllPosts() {
List<Post> posts = postRepository.findAll();
return posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());
}
@Override
public PostDto getPostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
return mapToDTO(post);
}
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.service.PostService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
}
Step 17: Update PostService Interface:
import com.springboot.blog.payload.PostDto;
import java.util.List;
List<PostDto> getAllPosts();
PostDto getPostById(long id);
import com.springboot.blog.entity.Post;
import com.springboot.blog.exception.ResourceNotFoundException;
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.repository.PostRepository;
import com.springboot.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PostServiceImpl implements PostService {
@Override
public PostDto createPost(PostDto postDto) {
@Override
public List<PostDto> getAllPosts() {
List<Post> posts = postRepository.findAll();
return posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());
}
@Override
public PostDto getPostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
return mapToDTO(post);
}
@Override
public PostDto updatePost(PostDto postDto, long id) {
// get post by id from the database
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.service.PostService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
postService.deletePostById(id);
import com.springboot.blog.payload.PostDto;
import java.util.List;
List<PostDto> getAllPosts();
import com.springboot.blog.entity.Post;
import com.springboot.blog.exception.ResourceNotFoundException;
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.repository.PostRepository;
import com.springboot.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PostServiceImpl implements PostService {
@Override
public PostDto createPost(PostDto postDto) {
// convert DTO to entity
Post post = mapToEntity(postDto);
Post newPost = postRepository.save(post);
@Override
public List<PostDto> getAllPosts() {
List<Post> posts = postRepository.findAll();
return posts.stream().map(post -> mapToDTO(post)).collect(Collectors.toList());
}
@Override
public PostDto getPostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
return mapToDTO(post);
}
@Override
public PostDto updatePost(PostDto postDto, long id) {
// get post by id from the database
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
@Override
public void deletePostById(long id) {
// get post by id from the database
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
postRepository.delete(post);
}
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.payload.PostResponse;
import com.springboot.blog.service.PostService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id") long id){
return ResponseEntity.ok(postService.getPostById(id));
}
postService.deletePostById(id);
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.payload.PostResponse;
import java.util.List;
import com.springboot.blog.entity.Post;
import com.springboot.blog.exception.ResourceNotFoundException;
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.payload.PostResponse;
import com.springboot.blog.repository.PostRepository;
import com.springboot.blog.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PostServiceImpl implements PostService {
@Override
public PostDto createPost(PostDto postDto) {
@Override
public PostResponse getAllPosts(int pageNo, int pageSize, String sortBy, String
sortDir) {
return postResponse;
}
@Override
public PostDto getPostById(long id) {
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
return mapToDTO(post);
}
@Override
public PostDto updatePost(PostDto postDto, long id) {
// get post by id from the database
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
@Override
public void deletePostById(long id) {
// get post by id from the database
Post post = postRepository.findById(id).orElseThrow(() -> new
ResourceNotFoundException("Post", "id", id));
postRepository.delete(post);
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "comments")
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;
}
import lombok.*;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(
name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames =
{"title"})}
)
public class Post {
@Id
@GeneratedValue(
strategy = GenerationType.IDENTITY
)
private Long id;
@Data
public class CommentDto {
private long id;
private String name;
private String email;
private String body;
}
import java.util.List;
public interface CommentService {
CommentDto createComment(long postId, CommentDto commentDto);
}
@Service
public class CommentServiceImpl implements CommentService {
@Override
public CommentDto createComment(long postId, CommentDto commentDto) {
// comment entity to DB
Comment newComment = commentRepository.save(comment);
return mapToDTO(newComment);
}
@RestController
@RequestMapping("/api/")
public class CommentController {
@PostMapping("/posts/{postId}/comments")
public ResponseEntity<CommentDto> createComment(@PathVariable(value =
"postId") long postId,
@RequestBody CommentDto commentDto){
return new ResponseEntity<>(commentService.createComment(postId,
commentDto), HttpStatus.CREATED);
}
}
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.List;
@Service
public class CommentServiceImpl implements CommentService {
@Override
public CommentDto createComment(long postId, CommentDto commentDto) {
// comment entity to DB
Comment newComment = commentRepository.save(comment);
return mapToDTO(newComment);
}
@Override
public List<CommentDto> getCommentsByPostId(long postId) {
// retrieve comments by postId
List<Comment> comments = commentRepository.findByPostId(postId);
@RestController
@RequestMapping("/api/")
public class CommentController {
@PostMapping("/posts/{postId}/comments")
public ResponseEntity<CommentDto> createComment(@PathVariable(value =
"postId") long postId, @RequestBody CommentDto commentDto){
import java.util.List;
import org.springframework.http.HttpStatus;
@Override
public String getMessage() {
return message;
}
}
@Service
public class CommentServiceImpl implements CommentService {
@Override
public CommentDto createComment(long postId, CommentDto commentDto) {
// comment entity to DB
Comment newComment = commentRepository.save(comment);
return mapToDTO(newComment);
}
@Override
public List<CommentDto> getCommentsByPostId(long postId) {
// retrieve comments by postId
List<Comment> comments = commentRepository.findByPostId(postId);
@Override
public CommentDto getCommentById(Long postId, Long commentId) {
// retrieve post entity by id
Post post = postRepository.findById(postId).orElseThrow(
() -> new ResourceNotFoundException("Post", "id", postId));
// retrieve comment by id
Comment comment = commentRepository.findById(commentId).orElseThrow(() -
>
new ResourceNotFoundException("Comment", "id", commentId));
if(!comment.getPost().getId().equals(post.getId())){
throw new BlogAPIException(HttpStatus.BAD_REQUEST, "Comment does not
belong to post");
}
return mapToDTO(comment);
}
private CommentDto mapToDTO(Comment comment){
CommentDto commentDto = mapper.map(comment, CommentDto.class);
@RestController
@RequestMapping("/api/")
public class CommentController {
@PostMapping("/posts/{postId}/comments")
public ResponseEntity<CommentDto> createComment(@PathVariable(value =
"postId") long postId,
@RequestBody CommentDto commentDto){
return new ResponseEntity<>(commentService.createComment(postId,
commentDto), HttpStatus.CREATED);
}
@GetMapping("/posts/{postId}/comments")
public List<CommentDto> getCommentsByPostId(@PathVariable(value = "postId")
Long postId){
return commentService.getCommentsByPostId(postId);
}
@GetMapping("/posts/{postId}/comments/{id}")
public ResponseEntity<CommentDto> getCommentById(@PathVariable(value =
"postId") Long postId,
@PathVariable(value = "id") Long commentId){
CommentDto commentDto = commentService.getCommentById(postId,
commentId);
return new ResponseEntity<>(commentDto, HttpStatus.OK);
}
}
@PutMapping("/posts/{postId}/comments/{id}")
public ResponseEntity<CommentDto> updateComment(@PathVariable(value =
"postId") Long postId,
@PathVariable(value = "id") Long commentId,
@RequestBody CommentDto commentDto){
CommentDto updatedComment = commentService.updateComment(postId,
commentId, commentDto);
return new ResponseEntity<>(updatedComment, HttpStatus.OK);
}
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
comment.setName(commentRequest.getName());
comment.setEmail(commentRequest.getEmail());
comment.setBody(commentRequest.getBody());
return mapToDTO(updatedComment);
URL: http://localhost:8080/api/posts/{postId}/comments/{id}
@DeleteMapping("/posts/{postId}/comments/{id}")
commentService.deleteComment(postId, commentId);
@Override
// retrieve comment by id
commentRepository.delete(comment);
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.9</version>
</dependency>
@Service
this.mapper = mapper;
@Override
return postResponse;
@Override
public PostResponse getAllPosts(int pageNo, int pageSize, String sortBy, String sortDir) {
: Sort.by(sortBy).descending();
postResponse.setContent(content);
postResponse.setPageNo(posts.getNumber());
postResponse.setPageSize(posts.getSize());
postResponse.setTotalElements(posts.getTotalElements());
postResponse.setTotalPages(posts.getTotalPages());
postResponse.setLast(posts.isLast());
return postResponse;
@Override
@Override
post.setTitle(postDto.getTitle());
post.setDescription(postDto.getDescription());
post.setContent(postDto.getContent());
return mapToDTO(updatedPost);
@Override
postRepository.delete(post);
}
// convert Entity into DTO
// postDto.setId(post.getId());
// postDto.setTitle(post.getTitle());
// postDto.setDescription(post.getDescription());
// postDto.setContent(post.getContent());
return postDto;
// post.setTitle(postDto.getTitle());
// post.setDescription(postDto.getDescription());
// post.setContent(postDto.getContent());
return post;
@Service
public class CommentServiceImpl implements CommentService {
this.commentRepository = commentRepository;
this.postRepository = postRepository;
this.mapper = mapper;
@Override
comment.setPost(post);
// comment entity to DB
return mapToDTO(newComment);
@Override
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
return mapToDTO(comment);
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
}
comment.setName(commentRequest.getName());
comment.setEmail(commentRequest.getEmail());
comment.setBody(commentRequest.getBody());
return mapToDTO(updatedComment);
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
}
commentRepository.delete(comment);
// commentDto.setId(comment.getId());
// commentDto.setName(comment.getName());
// commentDto.setEmail(comment.getEmail());
// commentDto.setBody(comment.getBody());
return commentDto;
// comment.setId(commentDto.getId());
// comment.setName(commentDto.getName());
// comment.setEmail(commentDto.getEmail());
// comment.setBody(commentDto.getBody());
return comment;
}
Exception Handling – Specific Exception & Global Exception
import java.util.Date;
this.timestamp = timestamp;
this.message = message;
this.details = details;
return timestamp;
return message;
}
public String getDetails() {
return details;
import com.springboot.blog.payload.ErrorDetails;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import
org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorDetails>
handleResourceNotFoundException(ResourceNotFoundException exception,
WebRequest webRequest){
webRequest.getDescription(false));
@ExceptionHandler(BlogAPIException.class)
WebRequest webRequest){
webRequest.getDescription(false));
// global exceptions
@ExceptionHandler(Exception.class)
WebRequest webRequest){
webRequest.getDescription(false));
Spring Validations
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-
validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
package com.springboot.blog.payload;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.Set;
@Data
@NotEmpty
@NotEmpty
@NotEmpty
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.payload.PostResponse;
import com.springboot.blog.service.PostService;
import com.springboot.blog.utils.AppConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping()
this.postService = postService;
@PostMapping("/api/v1/posts")
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto postDto){
@GetMapping("/api/v1/posts")
){
// get post by id
@GetMapping(value = "/api/v1/posts/{id}")
return ResponseEntity.ok(postService.getPostById(id));
@PutMapping("/api/v1/posts/{id}")
public ResponseEntity<PostDto> updatePost(@Valid @RequestBody PostDto postDto,
@PathVariable(name = "id") long id){
@DeleteMapping("/api/v1/posts/{id}")
postService.deletePostById(id);
Spring Security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Spring.security.user.name=pankaj
Spring.security.user.password=password
Spring.security.user.roles=ADMIN
@Configuration
@EnableWebSecurity
@Override
http
.csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
In memory Authentication
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
@Override
@Bean
protected UserDetailsService userDetailsService() {
UserDetails ramesh =
User.builder().username("pankaj").password(passwordEncoder()
.encode("password")).roles("USER").build();
UserDetails admin =
User.builder().username("admin").password(passwordEncoder()
.encode("admin")).roles("ADMIN").build();
return new InMemoryUserDetailsManager(ramesh, admin);
}
}
import com.springboot.blog.payload.PostDto;
import com.springboot.blog.payload.PostResponse;
import com.springboot.blog.service.PostService;
import com.springboot.blog.utils.AppConstants;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
@PreAuthorize("hasRole('ADMIN')")
// create blog post rest api
@PostMapping
public ResponseEntity<PostDto> createPost(@Valid @RequestBody PostDto
postDto){
return new ResponseEntity<>(postService.createPost(postDto),
HttpStatus.CREATED);
}
// get post by id
@GetMapping("/{id}")
public ResponseEntity<PostDto> getPostById(@PathVariable(name = "id")
long id){
return ResponseEntity.ok(postService.getPostById(id));
}
@PreAuthorize("hasRole('ADMIN')")
// update post by id rest api
@PutMapping("/{id}")
public ResponseEntity<PostDto> updatePost(@Valid @RequestBody PostDto
postDto, @PathVariable(name = "id") long id){
@PreAuthorize("hasRole('ADMIN')")
// delete post rest api
@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable(name = "id") long
id){
postService.deletePostById(id);
import lombok.Data;
import javax.persistence.*;
import java.util.Set;
@Data
@Entity
@Table(name = "users", uniqueConstraints = {
@UniqueConstraint(columnNames = {"username"}),
@UniqueConstraint(columnNames = {"email"})
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
private String username;
private String email;
private String password;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Setter
@Getter
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 60)
private String name;
}
import java.util.Optional;
import com.springboot.blog.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
UserDetailsService Implementation
import com.springboot.blog.entity.Role;
import com.springboot.blog.entity.User;
import com.springboot.blog.repository.UserRepository;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import
org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String usernameOrEmail) throws
UsernameNotFoundException {
User user = userRepository.findByUsernameOrEmail(usernameOrEmail,
usernameOrEmail)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with
username or email:" + usernameOrEmail));
return new
org.springframework.security.core.userdetails.User(user.getEmail(),
user.getPassword(), mapRolesToAuthorities(user.getRoles()));
}
import com.springboot.blog.security.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import
org.springframework.security.config.annotation.authentication.builders.Authen
ticationManagerBuilder;
import
org.springframework.security.config.annotation.method.configuration.EnableGlo
balMethodSecurity;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSec
urity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityC
onfigurerAdapter;
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;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
// @Override
// @Bean
// protected UserDetailsService userDetailsService() {
// UserDetails ramesh =
User.builder().username("ramesh").password(passwordEncoder()
// .encode("password")).roles("USER").build();
// UserDetails admin =
User.builder().username("admin").password(passwordEncoder()
// .encode("admin")).roles("ADMIN").build();
// return new InMemoryUserDetailsManager(ramesh, admin);
// }
}
@Data
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@PostMapping("/signin")
public ResponseEntity<String> authenticateUser(@RequestBody LoginDto
loginDto){
Authentication authentication = authenticationManager.authenticate(
new
UsernamePasswordAuthenticationToken(loginDto.getUsernameOrEmail(),
loginDto.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(authentication);
return new ResponseEntity<>("User signed-in successfully!.",
HttpStatus.OK);
}
}
Step 3: Update SecurityConfig File:
import com.springboot.blog.security.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.config.annotation.authentication.builders.Authen
ticationManagerBuilder;
import
org.springframework.security.config.annotation.method.configuration.EnableGlo
balMethodSecurity;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSec
urity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityC
onfigurerAdapter;
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;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").permitAll()
.antMatchers("/api/auth/**").permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
// @Override
// @Bean
// protected UserDetailsService userDetailsService() {
// UserDetails ramesh =
User.builder().username("ramesh").password(passwordEncoder()
// .encode("password")).roles("USER").build();
// UserDetails admin =
User.builder().username("admin").password(passwordEncoder()
// .encode("admin")).roles("ADMIN").build();
// return new InMemoryUserDetailsManager(ramesh, admin);
// }
}
package com.springboot.blog.controller;
import com.springboot.blog.entity.Role;
import com.springboot.blog.entity.User;
import com.springboot.blog.payload.LoginDto;
import com.springboot.blog.payload.SignUpDto;
import com.springboot.blog.repository.RoleRepository;
import com.springboot.blog.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationTok
en;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@PostMapping("/signin")
public ResponseEntity<String> authenticateUser(@RequestBody LoginDto
loginDto){
Authentication authentication =
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
loginDto.getUsernameOrEmail(), loginDto.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
return new ResponseEntity<>("User signed-in successfully!.",
HttpStatus.OK);
}
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@RequestBody SignUpDto signUpDto){
userRepository.save(user);
return new ResponseEntity<>("User registered successfully",
HttpStatus.OK);
}
}
@Data
public class SignUpDto {
private String name;
private String username;
private String email;
private String password;
}
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Override
HttpServletResponse response,
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
authException.getMessage());
## App Properties
app.jwt-secret= JWTSecretKey
app.jwt-expiration-milliseconds = 604800000
package com.springboot.blog.security;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// inject dependencies
@Autowired
@Autowired
@Override
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// validate token
);
authenticationToken.setDetails(new
WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response);
// Bearer <accessToken>
return null;
package com.springboot.blog.security;
import com.springboot.blog.exception.BlogAPIException;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
@Value("${app.jwt-secret}")
// generate token
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
return token;
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
try{
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
return true;
import com.springboot.blog.entity.User;
import com.springboot.blog.payload.JWTAuthResponse;
import com.springboot.blog.payload.LoginDto;
import com.springboot.blog.payload.SignUpDto;
import com.springboot.blog.repository.RoleRepository;
import com.springboot.blog.repository.UserRepository;
import com.springboot.blog.security.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
@RestController
@RequestMapping("/api/auth")
@Autowired
@Autowired
@Autowired
@Autowired
@Autowired
@PostMapping("/signin")
loginDto.getUsernameOrEmail(), loginDto.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
@PostMapping("/signup")
if(userRepository.existsByUsername(signUpDto.getUsername())){
if(userRepository.existsByEmail(signUpDto.getEmail())){
user.setName(signUpDto.getName());
user.setUsername(signUpDto.getUsername());
user.setEmail(signUpDto.getEmail());
user.setPassword(passwordEncoder.encode(signUpDto.getPassword()));
user.setRoles(Collections.singleton(roles));
userRepository.save(user);
this.accessToken = accessToken;
}
this.accessToken = accessToken;
this.tokenType = tokenType;
return accessToken;
return tokenType;
1. AWS
2. Heroku
3. Google Cloud
4. Microsoft Azure
5. Oracle
6. IBM Cloud
Important AWS Services every java developer should be aware of:
1. Amazon EC2 - Amazon Elastic Compute Cloud (EC2) is a web service that provides
resizable computing capacity in the cloud. It allows users to rent virtual machines (VMs),
known as instances, which can be used to run a variety of different operating systems and
applications. With EC2, users can easily scale their computing resources up or down as
needed, paying only for the resources they actually use. This makes it an ideal service for
applications that have varying compute needs, such as web servers, batch processing, and
big data processing. EC2 also provides a variety of different instance types, each
optimized for different types of workloads, such as compute-optimized, memory-
optimized, and storage-optimized instances. Additionally, EC2 also provides features such
as load balancing, auto-scaling, and virtual private cloud (VPC) to give users more control
and security over their instances
2. AWS Elastic Beanstalk -
Amazon Elastic Beanstalk is a fully managed service offered by AWS that makes it easy to
deploy, run, and scale web applications and services. It supports several programming
languages including Java, .NET, PHP, Node.js, Python, Ruby, and Go. Elastic Beanstalk
handles the provisioning of the infrastructure resources, load balancing, and automatic
scaling, allowing developers to focus on writing code for their application. The service also
includes monitoring and logging features, so developers can easily track the performance
and troubleshoot issues.
Elastic Beanstalk provides a simple, unified user interface to deploy and manage web
applications, as well as a command-line interface and APIs for more advanced users. It
integrates with other AWS services such as Amazon RDS, Amazon S3, Amazon SNS, and
AWS Elasticache. Elastic Beanstalk also provides a feature called "platform versions" that
allows developers to choose a specific version of the language runtime, web server, and
other software components to use with their application.
3. AMAZON RDS –
Amazon Relational Database Service (RDS) is a web service that makes it easy to set up,
operate, and scale a relational database in the cloud. RDS supports several popular database
engines including MySQL, PostgreSQL, Oracle, Microsoft SQL Server, and Amazon Aurora.
RDS automates many of the time-consuming tasks typically associated with managing a
relational database, such as provisioning, patching, backup, and recovery. It also provides
features such as automatic failover, read replicas, and a point-in-time restore, which help to
improve the availability and durability of the database. In addition, RDS allows users to easily
scale the resources allocated to a database up or down as needed, and it also offers a variety
of different instance types optimized for different types of workloads.
RDS also provides a feature called "Multi-AZ Deployments" that allows the user to create a
primary DB instance and synchronously replicate the data to a standby instance in a different
availability zone (AZ) for failover capabilities. This provides an automatic failover to the
standby instance in the event of a planned or unplanned outage of the primary instance.
Amazon Route 53 is a highly available and scalable Domain Name System (DNS) web service
offered by AWS. It translates human-friendly domain names, such as www.example.com, into
the IP addresses, such as 192.0.2.1, that computers use to identify each other on the internet.
Route 53 is designed to give developers and businesses a reliable and cost-effective way to
route end users to internet applications.
Route 53 provides a variety of different routing types, such as simple routing, which routes
traffic to a single resource, such as a web server, and complex routing, which allows you to
route traffic based on factors such as the geographic location of your users, the health of
your resources, and the routing policies that you specify.
Route 53 also provides a feature called "Health Check", that allows the user to monitor the
health of their resources, such as web servers, and route traffic to healthy resources. It also
integrates with other AWS services such as Amazon CloudFront, Elastic Load Balancing, and
AWS Elastic Beanstalk.
It also provides a feature called "Traffic Flow" that allows the user to create a visual
representation of their routing policies and test how the traffic will be routed before it's
updated.
# hibernate properties
#spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
# App Properties
app.jwt-secret= JWTSecretKey
app.jwt-expiration-milliseconds = 604800000
spring.profiles.active=prod
application-dev.properties content:
spring.datasource.url = jdbc:mysql://localhost:3306/myblog
spring.datasource.username = root
spring.datasource.password = test
# hibernate properties
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
application-qa.properties content:
spring.datasource.url = jdbc:mysql://localhost:3306/myblog
spring.datasource.username = root
spring.datasource.password = test
# hibernate properties
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
application-prod.properties content:
spring.datasource.url = jdbc:mysql://localhost:3306/myblog
spring.datasource.username = root
spring.datasource.password = test
# hibernate properties
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
Manually Enter Data into Roles Table Using Command Line Runner
package com.springboot.blog;
import com.springboot.blog.entity.Role;
import com.springboot.blog.repository.RoleRepository;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringbootBlogRestApiApplication implements CommandLineRunner {
@Autowired
private RoleRepository roleRepository;
@Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}
@Override
public void run(String... args) throws Exception {
Role adminRole = new Role();
adminRole.setName("ROLE_ADMIN");
roleRepository.save(adminRole);
Step 1:
Step 2: Go to AWS:
Step 3: Update Localhostname
Step 6: Click on ok
Step 7: Create Database in aws throughmysql workbench
Step 4:
Step 5:
Step 6:
Step 7:
Step 8:
Step 11:
Step 12: