RESTfulサービスを作成


## 空のWebApplicationを作成

他のIDEでもMavenでなくても良いが
今回はNetBeansでMavenProjectのWebApplicationを作成。

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/1db39924-f5a7-d7b2-c786-79d94624c69c.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/ee34e92c-b10b-a9ed-7041-8e01d886ef3a.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/2315d043-3a49-33ed-659f-4ed7b7610da7.png)

## 必要なライブラリを設定

jerseyとjacksonは入れておく。
dependenciesタグに追加。
あと、今回は glassfish-embedded-all これも。

```xml:pom.xml
       <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.main.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <type>jar</type>
            <version>4.1</version>
            <scope>provided</scope>
        </dependency>
 ```

## フィルタを設定
他にもやり方はあるみたいだが、フィルタを追加する方式で。

### beans.xmlを作成する(しなくても動くとは思う)

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/a78c822f-12c0-aeb7-b641-d62d85b0bce8.png)

```xml:beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:weld="http://jboss.org/schema/weld/beans"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"
       bean-discovery-mode="annotated">
    <weld:scan>
    </weld:scan>
    <alternatives></alternatives>
</beans>
```

### web.xmlを作成する

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/669046b2-87a3-b9fd-29d7-7e945e464b1b.png)

```xml:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="false" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <filter>
      <filter-name>servlet-container</filter-name>
      <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
      <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.mycompany.myrestwar.MyWebApplication</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>servlet-container</filter-name>
      <url-pattern>/rest/*</url-pattern>
    </filter-mapping>    
</web-app>
```
Applicationクラスは続いて作成する

## 実装を行う

### RESTサービスクラスの作成

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/a4b1ee76-dddb-9a82-c131-2b126a1967ed.png)


```java:TestRestREsource.java
package com.mycompany.myrestwar;

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;

/**
 * RESTのサービスクラス
 * @author foo
 */
@Path("/rest/test")
@RequestScoped
public class TestRestResource {

    @Context
    private UriInfo context;

    /**
     * Creates a new instance of TestResource
     */
    public TestRestResource() {
        
    }

    /**
     * Retrieves representation of an instance of jp.co.infomart.dataServiceNgs.product.rest.TestResource
     * @return an instance of java.lang.String
     */
    @GET
    @Produces("text/plain")
    public String getText() {
        return "this is just test for restful...";
    }

    /**
     * PUT method for updating or creating an instance of TestResource
     * @param content representation for the resource
     * @return an HTTP response with content of the updated or created resource.
     */
    @PUT
    @Consumes("text/plain")
    public void putText(String content) {
        // なにもしない
    }
    
}
```

### Applicationクラスを作成

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/7ec98e5e-9f1f-9ee1-dc22-c260a9a4f535.png)

```java:MyWebApplication.java
package com.mycompany.myrestwar;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

/**
 * RESTのアプリケーションクラス
 * @author foo
 */
@ApplicationPath("rest")
public class MyWebApplication extends ResourceConfig  {

    public MyWebApplication() {

        // 本当はパッケージ配下のやつを全部登録できるが
        // packages(this.getClass().getPackage().getName());
        
        // 今回は個別で
        this.register(TestRestResource.class);
    }
   
}
```

## 動かす

これで終わり、デプロイしてURLを叩くと・・・

![image](https://qiita-image-store.s3.amazonaws.com/0/101086/90a8bdf5-4cfe-5020-a67a-72c1d903484f.png)

無事に動作する。本当にこれだけ。

PUTやPOSTを実装したり
json形式で設定や取得を行うこともjacksonを使えば簡単にできる。


#### 参考：jsonを扱う

```java:GETメソッド
    import java.io.IOException;
    import java.security.InvalidParameterException;
    import com.fasterxml.jackson.core.JsonGenerationException;
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;

    private static ObjectMapper mapper = new ObjectMapper();

    @GET
    @Produces("application/json")
    public String getJson() {

        Map<String, Object> responseData = new HashMap<>();
        responseData.put("Name", "Hakozaki");
        responseData.put("Age", 39);
        
        try {
            return mapper.writeValueAsString(responseData);
        } catch (JsonMappingException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        
    }
```

なお、json -> Objectへの変換は以下のような感じ

```java:sample
    Map<String, Object> m 
        = mapper.readValue(
            jsonString, new TypeReference<Map<String, Object>>() {});
```

#### POSTで入出力を扱う

```java:POSTメソッド
    @POST
    @Produces("text/plain")
    @Consumes("text/plain")
    public String postText(String content) {
        return content + " is Post Data...";
    }    
```