PostCommentProject_1
PostCommentProject_1
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 lombok.Data;
@Data
public class PostDto {
private long id;
private String title;
private String description;
private String content;
}
import java.util.List;
@Service
public class PostServiceImpl implements PostService {
@Override
public PostDto createPost(PostDto postDto) {
@RestController
@RequestMapping("/api/posts")
public class PostController {
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 {
@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();
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 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));
}
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());
}
@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) {
Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ?
Sort.by(sortBy).ascending()
: Sort.by(sortBy).descending();
//or we can do this also
// Sort sort=null;
// if(sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()){
// Sort=Sort.by(sortBy).ascending();
// }else{
// sort=Sort.by(sortBy).descending(); }
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;
@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){
@GetMapping("/posts/{postId}/comments")
public List<CommentDto> getCommentsByPostId(@PathVariable(value = "postId")
Long postId){
return commentService.getCommentsByPostId(postId);
}
}
import java.util.List;
import org.springframework.http.HttpStatus;
@Override
public String getMessage() {
return message;
}
}
@Service
public class CommentServiceImpl implements CommentService {
private CommentRepository commentRepository;
private PostRepository postRepository;
private ModelMapper mapper;
public CommentServiceImpl(CommentRepository commentRepository,
PostRepository postRepository, ModelMapper mapper) {
this.commentRepository = commentRepository;
this.postRepository = postRepository;
this.mapper = mapper;
}
@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);
// 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");
}
//or
// if(!Objects.equals(comment.getPost().getId(),post.getId())){
// throw new BlogAPIException(HttpStatus.BAD_REQUEST,"comment does not
//belong to post");
// }
return mapToDTO(comment);
}
@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);
}
import java.util.List;
}
Step 3: Update CommentServiceImpl class:
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
comment.setName(commentRequest.getName());
comment.setEmail(commentRequest.getEmail());
comment.setBody(commentRequest.getBody());
URL: http://localhost:8080/api/posts/{postId}/comments/{id}
@DeleteMapping("/posts/{postId}/comments/{id}")
commentService.deleteComment(postId, commentId);
import java.util.List;
@Override
// retrieve comment by id
if(!comment.getPost().getId().equals(post.getId())){
commentRepository.delete(comment);
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.9</version>
</dependency>
@SpringBootApplication
public class MbyblogApplication {
@Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}
@Service
this.postRepository = postRepository;
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
Comment newComment = commentRepository.save(comment);
return mapToDTO(newComment);
@Override
@Override
// retrieve comment by id
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);
}
private CommentDto mapToDTO(Comment 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;
this.timestamp = timestamp;
this.message = message;
this.details = details;
return timestamp;
return message;
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
<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
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")
if(result.hasErrors()){
return new ResponseEntity<>(result.getFieldError().getDefaultMessage(),
HttpStatus.INTERNAL_SERVER_ERROR);
}
@GetMapping("/api/v1/posts")
){
// get post by id
@GetMapping(value = "/api/v1/posts/{id}")
return ResponseEntity.ok(postService.getPostById(id));
@DeleteMapping("/api/v1/posts/{id}")
postService.deletePostById(id);
Spring Security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Step 2: All Links of rest api are now secured
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
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import
org.springframework.security.config.annotation.method.configuration.EnableGlob
alMethodSecurity;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecu
rity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityCo
nfigurerAdapter;
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 {
@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);
}
@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.Authent
icationManagerBuilder;
import
org.springframework.security.config.annotation.method.configuration.EnableGlob
alMethodSecurity;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecu
rity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityCo
nfigurerAdapter;
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.Authent
icationManagerBuilder;
import
org.springframework.security.config.annotation.method.configuration.EnableGlob
alMethodSecurity;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecu
rity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityCo
nfigurerAdapter;
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.UsernamePasswordAuthenticationToke
n;
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.Role;
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")
public class AuthController {
@Autowired
@Autowired
@Autowired
@Autowired
@Autowired
@PostMapping("/signin")
loginDto.getUsernameOrEmail(), loginDto.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
// get token form tokenProvider
@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 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 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:
1.http status code in API development
HTTP status codes are a crucial part of API development as they provide information about
the status of a request made to a server.
They help communicate the outcome of the request to the client or the calling application.
Here are some commonly used HTTP status codes in API development:
1. 200 OK: This status code indicates that the request was successful, and the server has
returned the requested resource or completed the requested action.
2. 201 Created: This code is used when a new resource is successfully created as a result of a
POST request.
The server should include the location of the newly created resource in the response
headers.
3. 204 No Content: It indicates that the server has successfully processed the request but
does not need to return any content.
4. 400 Bad Request: This status code indicates that the server could not understand the
request due to malformed syntax,
5. 401 Unauthorized: It signifies that the request requires authentication. The client must
provide valid credentials
but the client does not have sufficient permissions to access the requested resource.
7. 404 Not Found: It indicates that the requested resource could not be found on the server.
8. 500 Internal Server Error: This status code indicates that an unexpected error occurred on
the server while processing the request.It is a generic error message used when no more
specific code is suitable.
These are just a few examples of HTTP status codes used in API development.There are many
more status codes available, each serving a specific purpose. API developers should choose
the appropriate status codes to provide meaningful information to clients about the outcome
of their requests.-
import lombok.*;
import javax.persistence.*;
@Data
@Entity
@Table(name = "students")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
private String course;
private double fee;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id_proof_id",referencedColumnName = "id")
private IdProof idProof;
}
3. create idproof entity class
package com.info.entites;
import lombok.Data;
import javax.persistence.*;
@Entity
@Data
@Table(name = "idproofs")
public class IdProof {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String pancardNumber;
@OneToOne(mappedBy = "idProof")
private Student student;
}
4.in application.properties give this
spring.datasource.url=jdbc:mysql://localhost:3306/studentinfo?
useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=9861369983
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=create
# Hibernate Configuration
spring.jpa.show-sql=true
import com.info.entites.IdProof;
import org.springframework.data.jpa.repository.JpaRepository;
import com.info.entites.IdProof;
import org.springframework.data.jpa.repository.JpaRepository;
import lombok.Data;
@Data
public class StudentDto {
private long id;
private String name;
private String course;
private double fee;
private IdProofDto idProofDto;
}
package com.info.payload;
import lombok.Data;
@Data
public class IdProofDto {
private long id;
private String pancardNumber;
}
7. create service layer
package com.info.service;
import com.info.payload.StudentDto;
}
package com.info.payload;
import lombok.Data;
@Data
public class IdProofDto {
private long id;
private String pancardNumber;
}
8. create serviceImpl class
package com.info.service.impl;
import com.info.entites.IdProof;
import com.info.entites.Student;
import com.info.payload.IdProofDto;
import com.info.payload.StudentDto;
import com.info.repository.IdProofRepository;
import com.info.repository.StudentRepository;
import com.info.service.StudentService;
import org.springframework.stereotype.Service;
@Service
public class StudentServiceImpl implements StudentService {
private StudentRepository studentRepo;
private IdProofRepository idProofRepo;
@Override
public StudentDto saveStudent(StudentDto studentDto) {
IdProof idProof =new IdProof();
idProof=idProofRepo.save(idProof);
Student student =new Student();
student.setName(studentDto.getName());
student.setCourse(studentDto.getCourse());
student.setFee(studentDto.getFee());
student.setIdProof(idProof);
student= studentRepo.save(student);
StudentDto dto =new StudentDto();
dto.setId(student.getId());
dto.setName(student.getName());
dto.setCourse(student.getCourse());
dto.setFee(student.getFee());
dto.setIdProofDto(idDto);
return dto;
}
}
package com.info.service.impl;
import com.info.entites.IdProof;
import com.info.exception.IdProofNotFoundException;
import com.info.payload.IdProofDto;
import com.info.repository.IdProofRepository;
import com.info.service.IdProofService;
import org.springframework.stereotype.Service;
@Service
public class IdProofServiceImpl implements IdProofService {
private IdProofRepository idProofRepo;
@Override
public IdProofDto updateIdProof(long id, String pancardNumber) {
IdProof proof = idProofRepo.findById(id).orElseThrow(() -> new
IdProofNotFoundException("student not there"));
proof.setPancardNumber(pancardNumber);
IdProof save = idProofRepo.save(proof);
IdProofDto dto=new IdProofDto();
dto.setId(save.getId());
dto.setPancardNumber(save.getPancardNumber());
return dto;
}
}
9. create exception class
package com.info.exception;
import com.info.payload.StudentDto;
import com.info.service.StudentService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/students")
public class StudentController {
private StudentService studentService;
package com.info.controller;
import com.info.payload.IdProofDto;
import com.info.service.IdProofService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/students")
public class IdProofController {
private IdProofService idProofService;