Spring系列——RESTful的web项目

原文链接:http://www.dubby.cn/detail.html?id=9040

1.目标是什么

构建一个web应用,我们可以请求:

http://localhost:8080/greeting

返回一个JSON

{"id":1,"content":"Hello, World!"}

还可以发起一个带参数的请求:

http://localhost:8080/greeting?name=User

返回一个JSON

{"id":1,"content":"Hello, User!"}

2.你需要有什么

  • 大约15分钟的时间
  • 一个喜欢的文本编辑器或者IDE
  • JDK 8(或者更高)
  • Maven 3.0+

3.开始我们的教程

3.1 maven依赖

创建一个maven项目,项目结构如下:

└── src
    └── main
        └── java
            └── hello

pom.xml


<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.0modelVersion>

    <groupId>org.springframeworkgroupId>
    <artifactId>gs-rest-serviceartifactId>
    <version>0.1.0version>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>1.5.8.RELEASEversion>
    parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>com.jayway.jsonpathgroupId>
            <artifactId>json-pathartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <properties>
        <java.version>1.8java.version>
    properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

    <repositories>
        <repository>
            <id>spring-releasesid>
            <url>https://repo.spring.io/libs-releaseurl>
        repository>
    repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releasesid>
            <url>https://repo.spring.io/libs-releaseurl>
        pluginRepository>
    pluginRepositories>
project>

其中,spring-boot-maven-plugin给我们提供了这么几个功能:
+ 他会把classpath下的jar统一打包成一个可直接运行的”über-jar”,方便我们运行。
+ 他会自动搜索public static void main()作为程序执行的入口。
+ 他内置一个依赖版本决定者。也就是他会指定依赖的版本。当然你也可以指定版本,如果你不指定,默认由他来决定版本。

3.2 实体类

根据

{
    "id": 1,
    "content": "Hello, World!"
}

来写出一个表达这个json的beansrc/main/java/hello/Greeting.java

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

Spring会使用Jackson JSON自动把Greeting的实例序列化成JSON

3.3 controller

在Spring构建的restful应用中,HTTP请求是由controller接收并处理的。想要创建一个controller可以使用@RestController修饰一个类,那么这个类就变成了一个controller。一个controller里的每个方法都可以接收一个特定的URI,需要使用@RequestMapping来修饰每个方法,来制定URI的路径,参数,方法等。

src/main/java/hello/GreetingController.java

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

这个controller很简洁明了,但是在背后隐藏了很多事先细节,我们一点点来分解。

@RequestMapping这个注解确保/greeting这个HTTP请求会被路由到greeting()这个方法上来处理。

上面的例子没有指明GETPUST或者是PUT等HTTP方法,因为@RequestMapping默认是映射所有的方法。如果你只希望某个方法被映射到这个方法,可以使用@RequestMapping(method=GET)来缩小映射范围。

@RequestParam把请求参数中的name的值绑定到greeting()的参数name上。这个参数被标记为可选的,也就是可传可不传的,(默认情况下,required=true是必须要传的),在这里,如果没有传name,就会使用defaultValue的值。

greeting()方法里创建了一个Greeting对象,然后返回,用一个自增的int作为id,用name的值拼接成content

传统的MVC的controller和RESTful的controller的最大的区别就是返回的HTTP的response。传统的controller返回的是一个由后端渲染的HTML,而RESTful返回的是一个对象,然后被序列化成JSON字符串。

@RestController是Spring4新加的一个注解,用它修饰的controller返回的是一个对象(也就是JSON),而不是一个视图(也就是HTML)。这个注解等同于同时使用@Controller@ResponseBody

上面提到Spring会自动把对象转化成JSON,我们还不需要手动来转换,那么是谁帮我们做的呢?真相是,只要Jackson 2在classpath下,Spring就会使用MappingJackson2HttpMessageConverter来自动转换。

3.4 可执行Jar

虽然也可以打包成传统的war包然后交给servlet容器来执行,但是更多的时候是打包成一个可以直接执行的Jar。

src/main/java/hello/Application.java

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

@SpringBootApplication注解等同于同时使用一下注解:
+ @Configuration修饰的类会被作为定义context上下文的bean。
+ @EnableAutoConfiguration允许Spring从配置文件,其他bean,等各种方式来加载bean。
+ 一般来说,对于Spirng MVC项目,你需要使用@EnableWebMvc,不过对于Spring Boot来说,只要你的classpath里包含spring-webmvc,他就会自动帮你加上这个,比如,设置DispatcherServlet
+ @ComponentScan告诉Spirng去扫描hello包下的其他组件,包含controller,service等。

main()就是这个应用的入口。发现了吗,整个应用没有一个XML文件,全部都是Java代码,没有任何配置,这就是Spring Boot想带给你的礼物。

3.5 生成可执行Jar

java -jar restful-web-1.0-SNAPSHOT.jar

结果:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.8.RELEASE)

2017-10-19 19:38:00.944  INFO 3923 --- [           main] hello.Application                        : Starting Application v1.0-SNAPSHOT on teedeMacBook-Pro.local with PID 3923 (/Users/teeyoung/Desktop/code4me/spring-demo/restful-web/target/restful-web-1.0-SNAPSHOT.jar started by teeyoung in /Users/teeyoung/Desktop/code4me/spring-demo/restful-web/target)
2017-10-19 19:38:00.949  INFO 3923 --- [           main] hello.Application                        : No active profile set, falling back to default profiles: default
2017-10-19 19:38:01.019  INFO 3923 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4f6ee6e4: startup date [Thu Oct 19 19:38:01 CST 2017]; root of context hierarchy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (jar:file:/Users/teeyoung/Desktop/code4me/spring-demo/restful-web/target/restful-web-1.0-SNAPSHOT.jar!/BOOT-INF/lib/spring-core-4.3.12.RELEASE.jar!/) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2017-10-19 19:38:02.374  INFO 3923 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
……
2017-10-19 19:38:03.219  INFO 3923 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-10-19 19:38:03.219  INFO 3923 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-10-19 19:38:03.263  INFO 3923 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-10-19 19:38:03.396  INFO 3923 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-10-19 19:38:03.465  INFO 3923 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-10-19 19:38:03.474  INFO 3923 --- [           main] hello.Application                        : Started Application in 2.924 seconds (JVM running for 3.436)

项目源代码:https://github.com/dubby1994/spring-demo

你可能感兴趣的:(Java,spring,springmvc,restful,Spring实践,spring,web,restful,springmvc)