日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

使用Spring Boot搭建你的第一个应用程序

發(fā)布時(shí)間:2024/2/28 javascript 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用Spring Boot搭建你的第一个应用程序 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 依賴配置
  • main程序配置
  • MVC配置
  • 安全配置
  • 存儲(chǔ)
  • Web 頁(yè)面和Controller
  • 異常處理
  • 測(cè)試
  • 結(jié)論

Spring Boot是Spring平臺(tái)的約定式的應(yīng)用框架,使用Spring Boot可以更加方便簡(jiǎn)潔的開(kāi)發(fā)基于Spring的應(yīng)用程序,本篇文章通過(guò)一個(gè)實(shí)際的例子,來(lái)一步一步的演示如何創(chuàng)建一個(gè)基本的Spring Boot程序。

依賴配置

本例子使用Maven來(lái)做包的依賴管理,在pom.xml文件中我們需要添加Spring boot依賴:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent>

同時(shí)我們要構(gòu)建一個(gè)web應(yīng)用程序,所以需要添加web依賴:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

OOM框架,我們使用spring自帶的jpa,數(shù)據(jù)庫(kù)使用內(nèi)存數(shù)據(jù)庫(kù)H2:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>

main程序配置

接下來(lái)我們需要?jiǎng)?chuàng)建一個(gè)應(yīng)用程序的主類:

@SpringBootApplication public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}

這里我們使用了注解: @SpringBootApplication。 它等同于三個(gè)注解:@Configuration, @EnableAutoConfiguration, 和 @ComponentScan同時(shí)使用。

最后,我們需要在resources目錄中添加屬性文件:application.properties。 在其中我們定義程序啟動(dòng)的端口:

server.port=8081

MVC配置

spring MVC可以配合很多模板語(yǔ)言使用,這里我們使用Thymeleaf。

首先需要添加依賴:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

然后在application.properties中添加如下配置:

spring.thymeleaf.cache=false spring.thymeleaf.enabled=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.htmlspring.application.name=Bootstrap Spring Boot

然后創(chuàng)建一個(gè)home頁(yè)面:

<html> <head><title>Home Page</title></head> <body> <h1>Hello !</h1> <p>Welcome to <span th:text="${appName}">Our App</span></p> </body> </html>

最后創(chuàng)建一個(gè)Controller指向這個(gè)頁(yè)面:

@Controller public class SimpleController {@Value("${spring.application.name}")String appName;@GetMapping("/")public String homePage(Model model) {model.addAttribute("appName", appName);return "home";} }

安全配置

本例主要是搭一個(gè)基本完整的框架,所以必須的安全訪問(wèn)控制也是需要的。我們使用Spring Security來(lái)做安全控制,加入依賴如下:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>

當(dāng)spring-boot-starter-security加入依賴之后,應(yīng)用程序所有的入庫(kù)會(huì)被默認(rèn)加入權(quán)限控制,在本例中,我們還用不到這些權(quán)限控制,所以需要自定義SecurityConfig,放行所有的請(qǐng)求:

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().permitAll().and().csrf().disable();} }

上例中,我們permit all請(qǐng)求。

后面我又會(huì)詳細(xì)的關(guān)于Spring Security的教程。這里先不做深入討論。

存儲(chǔ)

本例中,我們定義一個(gè)Book類,那么需要定義相應(yīng)的Entity類:

@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; }

和相應(yīng)的Repository類:

public interface BookRepository extends CrudRepository<Book, Long> {List<Book> findByTitle(String title); }

最后,我們需要讓應(yīng)用程序發(fā)現(xiàn)我們配置的存儲(chǔ)類,如下:

@EnableJpaRepositories("com.flydean.learn.repository") @EntityScan("com.flydean.learn.entity") @SpringBootApplication public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}

這里,我們使用@EnableJpaRepositories 來(lái)掃描repository類。

使用@EntityScan來(lái)掃描JPA entity類。

為了方便起見(jiàn),我們使用內(nèi)存數(shù)據(jù)庫(kù)H2. 一旦H2在依賴包里面,Spring boot會(huì)自動(dòng)檢測(cè)到,并使用它。 我們需要配置一些H2的屬性:

spring.datasource.driver-class-name=org.h2.Driver spring.datasource.url=jdbc:h2:mem:bootapp;DB_CLOSE_DELAY=-1 spring.datasource.username=sa spring.datasource.password=

和安全一樣,存儲(chǔ)也是一個(gè)非常重要和復(fù)雜的課題,我們也會(huì)在后面的文章中討論。

Web 頁(yè)面和Controller

有了Book entity, 我們需要為Book寫一個(gè)Controller,主要做增刪改查的操作,如下所示:

@RestController @RequestMapping("/api/books") public class BookController {@Autowiredprivate BookRepository bookRepository;@GetMappingpublic 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("ID mismatch!");}bookRepository.findById(id).orElseThrow(BookNotFoundException::new);return bookRepository.save(book);} }

這里我們使用@RestController 注解,表示這個(gè)Controller是一個(gè)API,不涉及到頁(yè)面的跳轉(zhuǎn)。

@RestController是@Controller 和 @ResponseBody 的集合。

異常處理

基本上我們的程序已經(jīng)完成了,但是在Controller中,我們定義了一些自定義的異常:

public class BookNotFoundException extends RuntimeException {public BookNotFoundException(String message, Throwable cause) {super(message, cause);}// ... }

那么怎么處理這些異常呢?我們可以使用@ControllerAdvice來(lái)攔截這些異常:

@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);} }

這種異常捕獲也叫做全局異常捕獲。

測(cè)試

我們的Book API已經(jīng)寫好了,接下來(lái)我們需要寫一個(gè)測(cè)試程序來(lái)測(cè)試一下。

這里我們使用@SpringBootTest :

@Slf4j @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SpringContextTest {@Testpublic void contextLoads() {log.info("contextLoads");} }

webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT的作用是表示測(cè)試時(shí)候使用的Spring boot應(yīng)用程序端口使用自定義在application.properties中的端口。

接下來(lái)我們使用RestAssured來(lái)測(cè)試BookController:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SpringBootBootstrapTest {private static final String API_ROOT= "http://localhost:8081/api/books";private Book createRandomBook() {Book book = new Book();book.setTitle(randomAlphabetic(10));book.setAuthor(randomAlphabetic(15));return book;}private String createBookAsUri(Book book) {Response response = RestAssured.given().contentType(MediaType.APPLICATION_JSON_VALUE).body(book).post(API_ROOT);return API_ROOT + "/" + response.jsonPath().get("id");}@Testpublic void whenGetAllBooks_thenOK() {Response response = RestAssured.get(API_ROOT);assertEquals(HttpStatus.OK.value(), response.getStatusCode());}@Testpublic void whenGetBooksByTitle_thenOK() {Book book = createRandomBook();createBookAsUri(book);Response response = RestAssured.get(API_ROOT + "/title/" + book.getTitle());assertEquals(HttpStatus.OK.value(), response.getStatusCode());assertTrue(response.as(List.class).size() > 0);}@Testpublic void whenGetCreatedBookById_thenOK() {Book book = createRandomBook();String location = createBookAsUri(book);Response response = RestAssured.get(location);assertEquals(HttpStatus.OK.value(), response.getStatusCode());assertEquals(book.getTitle(), response.jsonPath().get("title"));}@Testpublic void whenGetNotExistBookById_thenNotFound() {Response response = RestAssured.get(API_ROOT + "/" + randomNumeric(4));assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());}@Testpublic void whenCreateNewBook_thenCreated() {Book book = createRandomBook();Response response = RestAssured.given().contentType(MediaType.APPLICATION_JSON_VALUE).body(book).post(API_ROOT);assertEquals(HttpStatus.CREATED.value(), response.getStatusCode());}@Testpublic void whenInvalidBook_thenError() {Book book = createRandomBook();book.setAuthor(null);Response response = RestAssured.given().contentType(MediaType.APPLICATION_JSON_VALUE).body(book).post(API_ROOT);assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode());}@Testpublic void whenUpdateCreatedBook_thenUpdated() {Book book = createRandomBook();String location = createBookAsUri(book);book.setId(Long.parseLong(location.split("api/books/")[1]));book.setAuthor("newAuthor");Response response = RestAssured.given().contentType(MediaType.APPLICATION_JSON_VALUE).body(book).put(location);assertEquals(HttpStatus.OK.value(), response.getStatusCode());response = RestAssured.get(location);assertEquals(HttpStatus.OK.value(), response.getStatusCode());assertEquals("newAuthor", response.jsonPath().get("author"));}@Testpublic void whenDeleteCreatedBook_thenOk() {Book book = createRandomBook();String location = createBookAsUri(book);Response response = RestAssured.delete(location);assertEquals(HttpStatus.OK.value(), response.getStatusCode());response = RestAssured.get(location);assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode());} }

寫好了測(cè)試類,運(yùn)行就行了。

結(jié)論

你的第一個(gè)Spring Boot程序就完成了,后面的文章我們會(huì)繼續(xù)豐富和改善這個(gè)基本框架,歡迎繼續(xù)關(guān)注。

本文章的例子代碼可以參考github: bootstrap-sample-app

更多精彩內(nèi)容且看:

  • 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學(xué),超級(jí)賬本,以太坊,Libra,比特幣等持續(xù)更新
  • Spring Boot 2.X系列教程:七天從無(wú)到有掌握Spring Boot-持續(xù)更新
  • Spring 5.X系列教程:滿足你對(duì)Spring5的一切想象-持續(xù)更新
  • java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細(xì)文章教程

更多教程請(qǐng)參考 flydean的博客

總結(jié)

以上是生活随笔為你收集整理的使用Spring Boot搭建你的第一个应用程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。