RESTful实战笔记一——REST介绍及JERSEY快速体验

JAX-RS2入门

解读REST

    (Representation State Transfer)表属性状态转移,六个特点:客户端-服务器的、无状态的、可缓存的、统一接口的、分层系统和按需编码。优势:跨平台、跨语言。

     REST风格将对象视为一种资源(resource)。

     REST资源可寻址:

          HTTP协议定义通用动词方法(GET、POST、DELETE、PUT);

          URI协议唯一标识资源公布的接口。

标准:HTTP+URL+XML(XML借指数据格式),标准是基本实现格式,但是不是唯一实现形式。满足基本实现格式的不一定就是REST服务。

REST对比RPC风格对比MVC风格

    REST风格更轻量和快捷。从方法角度看,REST采用标准的HTTP方法,而RPC请求都是采用POST方法,其方法信息包含于SOAP协议包或HTTP协议包中,方法名称不具有通用性。从作用于的角度来看,REST采用URI显示定义作用域,而RPC的这一信息包含于协议包中,不能直观呈现。

    RPC是面向方法调用的过程,相对而言,REST是面向资源状态的。

    MVC风格将模型、视图、控制解耦,从前到后的一致性,结构整洁逻辑清晰易于扩展和增强,REST风格偏重统一接口,可实现跨语言、跨平台解耦,推进了前后端分离。MVC和REST并不互斥

RESTful Web Service(REST式Web服务)

REST服务是一种面向资源你的架构(ROA)应用,特点是方法信息存在于HTTP协议中,作用域存在于URI中。(区别RPC风格:RPC将请求方式放在信封中全部采用POST方法传送,没有体现HTTP协议的优势),所以REST风格更轻量和快速。

JAX-RS2的目标

要掌握一门技术,先要掌握其背后标准的定义。(我不想掌握jesery~)

1)基于POJO;

2)以HTTP为中心;

3)格式独立性;

4)容器独立性;

5)内置于javaEE;

为什么是JERSEY?

 JERSEY框架从2019年起在github上不再更新?https://github.com/jersey 但是JERSEY是JAVA领域中最纯正的REST服务开发框架。来自GlassFish项目的子项目。

JERSEY的模块

容器提供三种HTTP容器:Grizzly2、JDK-HTTP、SIMPLE-HTTP,Grizzly2同时提供Servlet容器。

快速实现Java REST服务

创建服务可以使用Jersey提供的Maven模型创建,使用IDEA创建快速启动的Jersey项目步骤如下:

GroupId:org.glassfish.jersey.archetypes

ArtifactId:jersey-quickstart-grizzly2

Version:2.22.1

创建完成后会生成如下的工程目录结构:

我们启动main方法,Jersey会启动web容器,我们根据uri访问便可完成简单的Jersey体验。

主类:

package my.restful;

import java.io.IOException;
import java.net.URI;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

/**
 * Main class.
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/myapp/";

    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     *
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in my.restful package
        final ResourceConfig rc = new ResourceConfig().packages("my.restful");

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    /**
     * Main method.
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
            + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.shutdown();
    }
}

资源类:

package my.restful;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }
}

请求uri:http://localhost:8080/myapp/myresource

结果:

扩展——webapp

webapp在jetty容器上提供rest服务:

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/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>my.restful</groupId>
    <artifactId>my-first-webapp</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>my-first-webapp</name>

    <build>
        <finalName>my-first-webapp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.3.5.v20151012</version>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.glassfish.jersey</groupId>
                <artifactId>jersey-bom</artifactId>
                <version>${jersey.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <!-- use the following artifactId if you don't need servlet 2.x compatibility -->
            <!-- artifactId>jersey-container-servlet</artifactId -->
        </dependency>
        <!-- uncomment this to get JSON support
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>
        -->
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers/jersey-container-servlet -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.19</version>
        </dependency>
    </dependencies>
    <properties>
        <jersey.version>2.22.1</jersey.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

index.jsp

<html>
<body>
    <h2>Jersey RESTful Web Application!</h2>
    <p><a href="webapi/myresource">Jersey resource</a>
    <p>Visit <a href="http://jersey.java.net">Project Jersey website</a>
    for more information on Jersey!
</body>
</html>

myResource.java

package my.restful;

import java.util.concurrent.ConcurrentHashMap;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {

    private static ConcurrentHashMap<String, MyDomain> map = new ConcurrentHashMap<>();

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return "Got it!";
    }

    @GET
    @Path("{key}")
    @Produces(MediaType.APPLICATION_XML)
    public MyDomain getMy(@PathParam("key") final String key) {
        final MyDomain myDomain = map.get(key);
        if (myDomain == null) {
            return new MyDomain();
        }
        return myDomain;
    }

    @POST
    @Consumes(MediaType.APPLICATION_XML)//POST传输application/xml
    public void addMy(final MyDomain myDomain) {
        map.put(myDomain.getName(), myDomain);
    }
}
MyDomain.java
package my.restful;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement//对象转xml
public class MyDomain {
    private String name;
    private String value;

    public MyDomain() {
    }

    public MyDomain(String name, String value) {
        this.name = name;
        this.value = value;
    }

    @XmlAttribute
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlAttribute
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

测试:

无参访问:

带请求实体POST:

GET方法访问eric:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章