# SpringBoot 3/26 上課內容 ###### tags: `SpringBoot` [老師雲端](https://onedrive.live.com/?authkey=%21AOSC5VqK5wFJeuk&id=AF483E7E8FEC387B%218460&cid=AF483E7E8FEC387B) ![](https://i.imgur.com/61mkp3X.png) # 58 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/pjk9x8B.png) # 59 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/SgQfmpt.png) [Spring Data JPA](https://docs.spring.io/spring-data/jpa/docs/2.4.6/reference/html/#repositories.namespace-reference) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/YTZqZEu.png) # 60 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/yvudpv2.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/DOOnBXG.png) # 61 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/EKT9aim.png) # 62 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/C5Z43mI.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/V0AynM2.png) # 63 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/0Kkb9lC.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/OEe9aMU.png) # 64 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/RVfqTnj.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/uGgRceU.png) # 65 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/mVanbqn.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/KdSljEU.png) * 要寫在最上面 .authorizeRequests() * .authenticated()要驗證 # 66 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/uliA0pS.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/ek578Jz.png) # 67 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/iHoUPXk.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/TP3Wye1.png) # 68 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/2RdjPrH.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/qcAz0IQ.png) # 69 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/uigVhjH.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/kXqPpm8.png) # 70 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/WKgR3AD.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/AgebHnP.png) * 加密後的密碼(2000) # 71 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/X2N58P2.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/6a6aCmi.png) # 72 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/PueQ99s.png) * UserNotFoundException = 自訂Exception ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/Y4bQCG9.png) # 73 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/gBJ9CSM.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/HHuaeZD.png) # 74 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/5VgomSR.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/gvy5iVa.png) # 75 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/VNS4INx.png) # 76 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/QNz56Eu.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/FFHJ3Jn.png) # 77 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/ly8mKnu.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/eWIi6NZ.png) # 78 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/mp92sR0.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/X4h3kDc.png) # 79 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/bD1knN7.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/wohRpZp.png) * 新增 查詢 # 80 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/zH7NDhi.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/z8FTzWA.png) # 81 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/V4aKZl5.png) ![](https://i.imgur.com/0X3OxxJ.png) # 82 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/0M81GgR.png) * 呼叫 ![](https://i.imgur.com/UvvUI6J.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/IHiJKJU.png) # 83 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/FCei3qY.png) ## Spring Boot 動態網站開發實務 ![](https://i.imgur.com/atsUtpP.png) # (重要) 88 Spring Boot 動態網站開發實務 ![](https://i.imgur.com/PHs0unh.png) # <font color="green">------------實作部份------------</font> #### sql table ```clike= USE LeonPower create table Users( id int not null primary key identity(1,1), name nvarchar(50) not null ); insert into Users(name) Values('mary'); insert into Users(name) Values('john'); insert into Users(name) Values('judy'); insert into Users(name) Values('louis'); insert into Users(name) Values('karen'); select*from Users ``` #### Users.java ```clike= package tw.leonchen.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.springframework.stereotype.Component; @Entity @Table(name = "users") @Component public class Users { @Id @Column(name = "ID") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "NAME") private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` #### UsersRepository.java (interface) ```clike= package tw.leonchen.model; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; public interface UsersRepository extends JpaRepository<Users, Integer> { @Query(value = "from Users Where name like concat('%', ?1, '%')",nativeQuery = false) public List<Users> findUsers(String name); public List<Users> findByNameLike(String name); @Query(value = "Select * From Users",nativeQuery = true) public List<Users> findAll(); } ``` #### UsersService.java ```clike= package tw.leonchen.model; import java.util.List; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service @Transactional public class UsersService { @Autowired private UsersRepository usersRepository; public List<Users> findUsers(String name){ return usersRepository.findUsers(name); } public List<Users> findUsersLike(String name){ return usersRepository.findByNameLike(name); } public List<Users> findAll(){ return usersRepository.findAll(); } } ``` #### UsersController.java ```clike= package tw.leonchen.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import tw.leonchen.model.Users; import tw.leonchen.model.UsersRepository; import tw.leonchen.model.UsersService; @RestController public class UsersController { @Autowired private UsersRepository usersRepository; @Autowired private UsersService uService; @GetMapping("/findusersbyname,controller") public List<Users> processFindUsersByName(){ return usersRepository.findUsers("ma"); } @GetMapping("/findusersbynamelike.controller") public List<Users> processFindUsersByNameLike(@RequestParam(name = "name")String name){ return usersRepository.findByNameLike("%" + name + "%"); } @GetMapping("/findallusers.controller") public List<Users> processFindAllUsers(){ return uService.findAll(); } } ``` #### Postman ![](https://i.imgur.com/D3HoOrk.png) #### pom.xml ![](https://i.imgur.com/TQNpo2L.png) ```clike= <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` #### WebSecurityConfig.java ![](https://i.imgur.com/45HsIGD.png) ```clike= package tw.leonchen.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; //import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import tw.leonchen.model.AuthUserDetailsService; @EnableWebSecurity //忽略管控 public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AuthUserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService) .passwordEncoder(new BCryptPasswordEncoder()); } @Override public void configure(WebSecurity web) throws Exception { } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() //路徑都要驗證 可多個路徑 payment底下都要驗證 .antMatchers(HttpMethod.GET,"/users/**","/payment/**").authenticated() .antMatchers(HttpMethod.GET).permitAll() .antMatchers(HttpMethod.POST,"/users/**","/payment/**").authenticated() .antMatchers(HttpMethod.POST).permitAll() //除了上面 任何請求都要驗證 .anyRequest().authenticated() .and() .rememberMe().tokenValiditySeconds(86400).key("remember-me") .and() //不要管我 .csrf().disable() .formLogin().loginPage("/login/page") .defaultSuccessUrl("/login/welcome"); } } ``` #### application.properties ```clike= #spring security default username and password spring.security.user.name=user spring.security.user.password=test123 ``` #### login.jsp ```clike= <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <form action="/login/page" method="post"> <table> <tr> <td>UserName:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password"></td> </tr> <tr> <td colspan="2"> <input type="checkbox" name="remember-me">RememberMe </td> </tr> <tr> <td colspan="2"> <button type="submit" value="login">Login</button> </td> </tr> </table> </form> </body> </html> ``` #### welcome.jsp ```clike= <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Welcome</title> </head> <body> Welcome </body> </html> ``` #### WebAppConfig.java ![](https://i.imgur.com/hugdcoK.png) ![](https://i.imgur.com/A9qmxVZ.png) ```clike= package tw.leonchen.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebAppConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login/page").setViewName("login"); registry.addViewController("/login/welcome").setViewName("welcome"); registry.addViewController("/logout/page").setViewName("logout"); registry.addViewController("/logout").setViewName("logoutResult"); } } ``` #### logout.jsp ```clike= <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Logout</title> </head> <body> <form action="/logout" method="post"> <table> <tr> <td>Logout</td> <td><button type="submit" value="logout">Logout</button></td> </tr> </table> </form> </body> </html> ``` #### logoutResult.jsp ```clike= <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>LogoutResult</title> </head> <body> You've already logout<br/> </body> </html> ``` #### sql table UserProfiles ```clike= create table UserProfiles( id int not null primary key identity(1000,1), name nvarchar(50)not null, emailAddress nvarchar(50) not null, password nvarchar(2000)not null ) 加密後的密碼(2000) 編碼 不能解碼 nvarchar最多4000字 varchar最多8000字 select * from UserProfiles ``` #### UserProfiles.java ```clike= package tw.leonchen.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import org.springframework.stereotype.Component; @Entity @Table(name = "userprofiles") @Component public class UserProfiles { @Id @Column(name = "ID") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "NAME") private String name; @Column(name = "EMAILADDRESS") private String emailAddress; @Column(name = "PASSWORD") private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ``` #### UserProfilesRepository.java(interface) ```clike= package tw.leonchen.model; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface UserProfilesRepository extends JpaRepository<UserProfiles, String> { public Optional<UserProfiles> findByName(String name); } ``` #### UserNotFoundException.java ![](https://i.imgur.com/tAx8yOH.png) ![](https://i.imgur.com/6pRvnEA.png) ```clike= package tw.leonchen.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(HttpStatus.NOT_FOUND) public class UserNotFoundException extends RuntimeException { private static final long serialVersionUID = 1L; public UserNotFoundException() { } public UserNotFoundException(String message) { super(message); } } ``` #### UserProfilesService.java ```clike= package tw.leonchen.model; import java.util.Optional; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import tw.leonchen.exception.UserNotFoundException; @Service @Transactional public class UserProfilesService { @Autowired private UserProfilesRepository userProfilesRepository; public UserProfiles getByName(String name) { Optional<UserProfiles> uRep = userProfilesRepository.findByName(name); //重要 if(uRep.isEmpty()) { throw new UserNotFoundException("Can't find User"); } return uRep.get(); } public UserProfiles createUserProfiles(UserProfiles userProfiles) { return userProfilesRepository.save(userProfiles); } } ``` #### UserProfilesController.java ```clike= package tw.leonchen.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import tw.leonchen.model.UserProfiles; import tw.leonchen.model.UserProfilesService; @RestController public class UserProfilesController { @Autowired private UserProfilesService userProfilesService; @PostMapping("/userProfilesCreate.controller") public UserProfiles processCreateUser(@RequestBody UserProfiles uProfiles) { String bcEncode1 = new BCryptPasswordEncoder().encode(uProfiles.getPassword()); uProfiles.setPassword(bcEncode1); return userProfilesService.createUserProfiles(uProfiles); } } ``` #### AuthUserDetailsService.java ```clike= package tw.leonchen.model; import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; 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.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; @Service public class AuthUserDetailsService implements UserDetailsService { @Autowired private UserProfilesService userProfilesService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserProfiles uProfiles = userProfilesService.getByName(username); return new User(uProfiles.getName(), uProfiles.getPassword(), Collections.emptyList()); } } ``` #### sql table Product ![](https://i.imgur.com/UZznbC6.png) * 查詢200筆會有以下的圖 ![](https://i.imgur.com/9EJgK37.png) ```clike= create table Product( id int not null primary key identity(10000,1), pname nvarchar(50)not null, price int not null, pdate date not null, note nvarchar(200)not null ); select * from Product insert into Product(pname,price,pdate,note) values('NB',25000,'2021-03-26','Good to use'); insert into Product(pname,price,pdate,note) values('MobilePhone',18000,'2021-03-27','contact'); insert into Product(pname,price,pdate,note) values('Banana',10,'2021-03-26','yummy'); insert into Product(pname,price,pdate,note) values('Drink',80,'2021-04-16','sweet'); insert into Product(pname,price,pdate,note) values('Apple',50,'2021-05-08','Health'); insert into Product(pname,price,pdate,note) values('客家資策會',1,'2020-01-01','bad'); ``` #### Product.Java ```clike= package tw.leonchen.product.model; import java.sql.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonFormat; @Entity @Table(name = "product") public class Product { @Id @Column(name = "ID") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "PNAME") private String pname; @Column(name = "PRICE") private int price; @Column(name = "QUANTITY") private int quantity; @Column(name = "PDATE") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date pdate; @Column(name = "NOTE") private String note; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public Date getPdate() { return pdate; } public void setPdate(Date pdate) { this.pdate = pdate; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } } ``` #### ProductRepository.java(interface) ```clike= package tw.leonchen.product.model; import org.springframework.data.jpa.repository.JpaRepository; public interface ProductRepository extends JpaRepository<Product, Integer> { } ``` #### ProductService.java ```clike= package tw.leonchen.product.model; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @Service public class ProductService { @Autowired private ProductRepository productRepository; public Product findById(Integer id) { Optional<Product> pRep = productRepository.findById(id); if(pRep.isPresent()) { return pRep.get(); } return null; } public List<Product> findAll(){ return productRepository.findAll(); } public Page<Product> findAllByPage(Pageable pageable){ return productRepository.findAll(pageable); } } ``` #### ProductController.java ```clike= package tw.leonchen.product.controller; import java.util.List; 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.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.SessionAttributes; import tw.leonchen.product.model.Product; import tw.leonchen.product.model.ProductService; @Controller @RequestMapping(path = "/product") @SessionAttributes(names = { "totalPages", "totalElements" }) public class ProductController { @Autowired private ProductService pService; //顯示分頁 @GetMapping("/productqueryMainPage.controller") public String processQueryMainPage() { return "product/productQueryAll"; } //直接顯示全部 @PostMapping("/queryallproduct.controller") @ResponseBody public List<Product> queryAllProduct() { return pService.findAll(); } //分頁 @PostMapping("/queryallproductByPage.controller/{pageNo}") @ResponseBody public List<Product> queryAllProductByPage(@PathVariable(name = "pageNo") int pageNo, Model m) { int pageSize = 2; Pageable pageable = PageRequest.of(pageNo-1, pageSize); Page<Product> page = pService.findAllByPage(pageable); int totalPages = page.getTotalPages(); long totalElements = page.getTotalElements(); m.addAttribute("totalPages", totalPages); m.addAttribute("totalElements", totalElements); return page.getContent(); } } ``` #### productQuery.jsp ```clike= <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Product Query</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script type="text/javascript"> var indexPage = 1; $(document).ready(function(){ load(indexPage); }); function change(page){ indexPage = page; load(indexPage); } function load(indexPage){ $.ajax({ type:'post', url:'/product/queryallproductByPage.controller/' + indexPage, dataType:'JSON', contentType:'application/json', success: function(data) { var json = JSON.stringify(data, null, 4); console.log("SUCCESS : ", json); var parsedObjinArray = JSON.parse(json); $('#showproduct').empty(""); //清空table內的資料 if(json=null){ $('table').prepend("<tr><td colspan='2'>暫無資料</td></tr>"); }else{ var table = $('#showproduct'); table.append("<tr id='ptitle'><th>ID</th><th>Product Name</th><th>ProductPrice</th><th>Date</th><th>Note</th></tr>"); $.each(parsedObjinArray,function(i,n){ var tr = "<tr align='center'>" + "<td>" + n.id + "</td>" + "<td>" + n.pname + "</td>" + "<td>" + n.price + "</td>" + "<td>" + n.pdate + "</td>" + "<td>" + n.note + "</td>" + "</tr>"; table.append(tr); }); } }, error: function() { console.log("error"); } }); } </script> <style type="text/css"> table { margin: auto; width: 70% } #ptitle { background-color: orange; } #productListTitle { margin: auto; font-size: 25px; font-weight: bold; text-align: center; } </style> </head> <body> <div id="productListTitle">ProductQuery</div> <table id="showproduct" border="1"> </table> <table id="showpage"> <tr> <td>Total Pages:${totalPages} Total Records:${totalElements}</td> <td colspan="3" align="right">Previous <c:forEach var="i" begin="1" end="${totalPages}" step="1"> <button id="myPage" value="${i}" onclick="change(${i})">${i}</button> </c:forEach>Next </td> </tr> </table> </body> </html> ```