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的注解包含的意思:
-
标記該類作為應用程式上下文的bean定義的源。@Configuration
-
告訴Spring Boot開始根據類路徑設定,其他bean和各種屬性設定添加bean。@EnableAutoConfiguration
- 通常你會添加
一個Spring MVC應用程式,但Spring Boot會在類路徑上看到spring-webmvc時自動添加它。這會将應用程式标記為Web應用程式并激活關鍵行為,例如設定a@EnableWebMvc
。DispatcherServlet
-
告訴Spring在包中尋找其他元件,配置和服務@ComponentScan
,允許它找到控制器。hello