SpringBoot實戰(一)之構建RestFul風格
RestFul風格是一種非常流行的架構風格,相關實戰可以參考我的這篇博客:SSM框架之RestFul示例
論文可參考:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
關於論文,我想說的是,程序員不要對英文產生恐懼感,現在的翻譯工具多的多,當然了,多也代表一些雜碎的也不少,所以就需要我們學會如何甄別。
我英語也不好,不過我目前也在學會如何看英文文檔,其實英文並沒有那麽可怕,相反,它還是很有趣的,畢竟我們天天對諸如Eclipse或IDEA這樣的英文軟件,而且還寫著一大堆的英文代碼,日子久了,自然都知道是什麽意思了。
記得唐代有句古詩:熟讀唐詩三百首,不會做詩也會吟。
對於天天敲著英文代碼的我們而言,也是如此。每個人都有一個過程,過程周期有長有短。
在這裏再閑扯一句,外國人的技術創新能力不容小覷,我們現在用的很多技術,都已經是人家用了好多年甚至已經過時了的,隨著經濟全球化越來越廣越來越深,而且目前國內的培訓機構和大學生研究生碩士博士等,如果不想被淘汰,必須要掌握強大學習能力。其中有一項就是英文要會。先不說會不會說,發音標不標準,至少要看的懂是什麽意思吧。
總而言之,送我自己和大家一句話,循序漸進。
構建環境為:JDK8+MAVNE3以上+Eclipse
本示例參考Spring官方文檔:https://spring.io/guides/gs/rest-service/
一、構建maven依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-rest-service</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <scope>test</scope> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <url>https://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project>
二、構建實體
package hello; public class Greeting { private final long id; private final String content; public Greeting(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } }
三、構建Controller
package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } }
關於RestController和Controller存在什麽不同,主要是RestController中存在一個全局的ResponseBody,從而保證返回的異步數據為JSON數據。
可參考我的博客:前後端交互之封裝Ajax+SpringMVC源碼分析
另外這裏也說說@RequestParam,其實加這個不加這個都可以獲取參數,唯一的區別是,如果不加@RequestParm,你必須要確保前臺的ajax或者同步請求的參數名必須與後臺Controller中對應方法上參數列表中的參數名保持一致,否則會導致參數傳輸不過來,從而導致某些異常錯誤信息。
而加了@RequestParam,你可以讓前臺的值不與後臺一致,你只需如下即可:
例如我前臺的參數名叫test,我後臺加了@RequestParam(value="test") String test001,這樣就可以獲取對應的參數了。同時的話,我還有可以增加一個叫required的參數,required無論是在input的屬性還是後臺,都有一個共性叫是否必填。後臺中默認是false,不必填,當為true時,為必填。
而前臺html中input,加了required,如果不在對應的表單中輸入信息,就會提示此表單為必填項諸如此類的信息。
提到@RequestParam時,還不得不提一個叫@PathVariable的註解,這個註解對於經常寫博客的友友們非常不陌生,為什麽這麽說了,比如大家有沒有觀察到博客園的導航欄
例如:
以我為例
https://home.cnblogs.com/u/youcong/
/u,我想應該是關於用戶對應的名稱或參數名,而/youcong就是對應的參數值。
這和https://i.cnblogs.com/posts?page=2本質上是一樣的,只是參數呈現的表現方式不一樣。
從而也凸顯@RequestParam和@PathVariable的區別之一。
四、構建啟動類
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
五、執行Application中的main方法即可運行一個SpringBoot的restful風格
最終結果如下圖所示:
另外不得不提下SpringBootApplication的源碼:
源碼如下:
* Copyright 2012-2017 the original author or authors. package org.springframework.boot.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.context.TypeExcludeFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.core.annotation.AliasFor; /** * Indicates a {@link Configuration configuration} class that declares one or more * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience * annotation that is equivalent to declaring {@code @Configuration}, * {@code @EnableAutoConfiguration} and {@code @ComponentScan}. * * @author Phillip Webb * @author Stephane Nicoll * @since 1.2.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude") Class<?>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName") String[] excludeName() default {}; /** * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses} * for a type-safe alternative to String-based package names. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; /** * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to * scan for annotated components. The package of each class specified will be scanned. * <p> * Consider creating a special no-op marker class or interface in each package that * serves no purpose other than being referenced by this attribute. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {}; }
另外也提提@SpringBootApplication的註解包含的意思:
-
@Configuration
標記該類作為應用程序上下文的bean定義的源。 -
@EnableAutoConfiguration
告訴Spring Boot開始根據類路徑設置,其他bean和各種屬性設置添加bean。 -
通常你會添加
@EnableWebMvc
一個Spring MVC應用程序,但Spring Boot會在類路徑上看到spring-webmvc時自動添加它。這會將應用程序標記為Web應用程序並激活關鍵行為,例如設置aDispatcherServlet
。 -
@ComponentScan
告訴Spring在包中尋找其他組件,配置和服務hello
,允許它找到控制器。
SpringBoot實戰(一)之構建RestFul風格