创建一个简单的Sping Boot项目
初始化项目
首先,让我们使用Spring Initializr为我们的生成项目。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
应用配置
接下来,我们将为我们的应用程序编写一个简单的主启动类
package com.example.learnspringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LearnSpringBoot {
public static void main(String[] args) {
SpringApplication.run(LearnSpringBoot.class, args);
}
}
最后,我们将定义一个简单的application.properties文件
server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/learn?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=xxxx
创建MVC
现在让我们使用Thymeleaf添加一个简单的前端。我们需要将spring-boot-starter-thymeleaf依赖添加到pom. xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
默认启用Thymeleaf无需额外配置。我们现在可以在application.properties中配置它:
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.application.name=Bootstrap Spring Boot
接下来,我们将定义一个简单的控制器和一个带有欢迎语的基本主页
@Controller
public class SimpleController {
@Value("${spring.application.name}")
String appName;
@GetMapping("/")
public String homePage(Model model) {
model.addAttribute("appName", appName);
return "home";
}
}
最后,这是我们的home. html:
<html>
<head><title>Home Page</title></head>
<body>
<h1>Hello !</h1>
<p>Welcome to <span th:text="${appName}">Our App</span></p>
</body>
</html>
安全
接下来,让我们通过添加Spring Security来为我们的应用程序添加安全性
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
一旦添加了spring-boot-starter-security依赖,默认情况下所有端点都受到保护。在我们的例子中中,我们允许不受限制地访问所有端点。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(expressionInterceptUrlRegistry ->
expressionInterceptUrlRegistry
.anyRequest()
.permitAll())
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
}
持久化
首先我们需要引入spring-boot-starter-data-jpa和创建Book entity
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
package com.example.learnspringboot.Entity;
import javax.persistence.*;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false, unique = true)
private String title;
@Column(nullable = false)
private String author;
// getters and setters
}
然后创建Repository
package com.example.learnspringboot.repository;
import com.example.learnspringboot.Entity.Book;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface BookRepository extends CrudRepository<Book, Long> {
List<Book> findByTitle(String title);
}
最后在主启动类上添加注解开启Jpa Repository
@EnableJpaRepositories("com.baeldung.persistence.repo")
@EntityScan("com.baeldung.persistence.model")
设置Hibernate DDL策略
spring.jpa.hibernate.ddl-auto=update
创建BookController
让我们创建一个BookController可以对Book资源进行CRUD操作
package com.example.learnspringboot.controller;
import com.example.learnspringboot.Entity.Book;
import com.example.learnspringboot.exception.BookIdMismatchException;
import com.example.learnspringboot.exception.BookNotFoundException;
import com.example.learnspringboot.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/books")
public class BookController {
@Autowired
private BookRepository bookRepository;
@GetMapping
public Iterable findAll() {
return bookRepository.findAll();
}
@GetMapping("/title/{bookTitle}")
public List findByTitle(@PathVariable String bookTitle) {
return bookRepository.findByTitle(bookTitle);
}
@GetMapping("/{id}")
public Book findOne(@PathVariable Long id) {
return bookRepository.findById(id)
.orElseThrow(BookNotFoundException::new);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Book create(@RequestBody Book book) {
return bookRepository.save(book);
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
bookRepository.findById(id)
.orElseThrow(BookNotFoundException::new);
bookRepository.deleteById(id);
}
@PutMapping("/{id}")
public Book updateBook(@RequestBody Book book, @PathVariable Long id) {
if (book.getId() != id) {
throw new BookIdMismatchException();
}
bookRepository.findById(id)
.orElseThrow(BookNotFoundException::new);
return bookRepository.save(book);
}
}
错误处理
使用@ControllerAdvice注解进行集中式的错误处理
package com.example.learnspringboot.exception;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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;
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ BookNotFoundException.class })
protected ResponseEntity<Object> handleNotFound(
Exception ex, WebRequest request) {
return handleExceptionInternal(ex, "Book not found",
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
@ExceptionHandler({ BookIdMismatchException.class,
ConstraintViolationException.class,
DataIntegrityViolationException.class })
public ResponseEntity<Object> handleBadRequest(
Exception ex, WebRequest request) {
return handleExceptionInternal(ex, ex.getLocalizedMessage(),
new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
}
自定义异常
package com.example.learnspringboot.exception;
public class BookIdMismatchException extends RuntimeException {
public BookIdMismatchException(String message, Throwable cause) {
super(message, cause);
}
public BookIdMismatchException() {
super();
}
}
package com.example.learnspringboot.exception;
public class BookNotFoundException extends RuntimeException {
public BookNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public BookNotFoundException() {
super();
}
}
创建一个简单的error. html来自定义错误的视图,配置视图路径
<html lang="en">
<head><title>Error Occurred</title></head>
<body>
<h1>Error Occurred!</h1>
<b>[<span th:text="${status}">status</span>]
<span th:text="${error}">error</span>
</b>
<p th:text="${message}">message</p>
</body>
</html>
server.error.path=/error
本文由博客一文多发平台 OpenWrite 发布!
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦