fileSampleCxf.zip サンプルアプリ (Netbeans/Maven)

CXFとは?

サンプルアプリ

Maven の動的 Web アプリを作成する

cxf1.png

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

    <groupId>com.mycompany</groupId>
    <artifactId>SampleCxf</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>SampleCxf</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.2.0.RELEASE</version>
        </dependency>    
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>1.9.11</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.icu</groupId>
            <artifactId>icu4j</artifactId>
            <version>50.1.1</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

WEB-INF/web.xml

/rest/* を CXFServlet に割り付ける

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>JAX-RS Simple Service</display-name>
    <description>JAX-RS Simple Service</description>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/beans.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>ServletAdaptor</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ServletAdaptor</servlet-name>
        <url-pattern>/webresources/*</url-pattern>
    </servlet-mapping>
</web-app>

WEB-INF/bean.xml

Webサービスのインタフェースを実現する POJO を設定。
Provider については、後述 → JSONPを返す

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />

    <context:property-placeholder/>
    <context:annotation-config/>
    <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"/>
    <bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"/>

    <jaxrs:server id="services" address="/">
        <jaxrs:serviceBeans>
            <bean class="com.mycompany.samplecxf.HelloWorld" />
        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <!-- <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> -->
            <bean class="com.mycompany.samplecxf.MyJsonpProvider" />
        </jaxrs:providers>
    </jaxrs:server>

</beans>

HelloWorld?.java (JAX-RS インタフェース)

ICU4J を使った時刻形式の変換。HTTP GET (URLパラメータ) でパラメータを受け取って JSON、XML、CSV 形式で返却する。詳細は後述 → JSONを返すXMLを返すTEXTを返すJSONPを返す

package com.mycompany.samplecxf;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.ChineseCalendar;
import com.ibm.icu.util.JapaneseCalendar;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/timeconv")
public class HelloWorld {

    @GET
    @Produces("application/json")
    public Response conv(@QueryParam("time") String time) {
        return jsonJst(time);
    }

    @GET
    @Path("/json/jst/{jst}")
    @Produces("application/json")
    public Response jsonJst(@PathParam("jst") String jst) {
        try {
            return Response.ok(timeconv(jst, +9)).build();
        } catch (Exception e) {
            e.printStackTrace();
            return Response.serverError().build();
        }
    }

    @GET
    @Path("/xml/jst/{jst}")
    @Produces("application/xml")
    public Response xmlJst(@PathParam("jst") String jst) {
        try {
            return Response.ok(timeconv(jst, +9)).build();
        } catch (Exception e) {
            e.printStackTrace();
            return Response.serverError().build();
        }
    }

    @GET
    @Path("/csv/jst/{jst}")
    @Produces("text/plain")
    public String csvJst(@PathParam("jst") String jst) {
        try {
            return timeconv(jst, +9).toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "failed";
        }
    }

    private JsonBean timeconv(String timeString, int diff) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = df.parse(timeString);

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR, -1 * diff);

        Date utcDate = cal.getTime();

        Calendar jpCal = Calendar.getInstance();
        jpCal.setTime(utcDate);
        jpCal.add(Calendar.HOUR, +9);
        Date jpDate = jpCal.getTime();

        JsonBean res = new JsonBean();

        // 日本時間
        res.setJst(new com.ibm.icu.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(jpDate));

        // 和暦
        JapaneseCalendar jc = new JapaneseCalendar();
        DateFormat jdf = new SimpleDateFormat("Gyy年MM月dd日", new DateFormatSymbols(jc, Locale.JAPANESE));
        jdf.setCalendar(jc);
        res.setJp(jdf.format(jpDate));

        // 干支
        ChineseCalendar cc = new ChineseCalendar();
        DateFormat cdf = new SimpleDateFormat("U", new DateFormatSymbols(cc, Locale.CHINESE));
        cdf.setCalendar(cc);
        res.setCycric(cdf.format(jpDate));

        // GMT
        res.setGmt(new com.ibm.icu.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(utcDate));

        // Julian Day
        res.setJd(new com.ibm.icu.text.SimpleDateFormat("g").format(utcDate));

        // MJD
        res.setMjd(Double.toString(Double.parseDouble(res.getJd()) - 2400000.5));

        return res;
    }
}

JSONBean.java (処理結果 Bean)

普通の POJO

package com.mycompany.samplecxf;

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

@XmlRootElement(name = "time")
public class JsonBean {

    private String cycric;
    private String gmt;
    private String jd;
    private String jp;
    private String jst;
    private String mjd;

    public JsonBean() {
        super();
    }

    /**
     * @return cycric
     */
    @XmlElement
    public final String getCycric() {
        return cycric;
    }

    /**
     * @return gmt
     */
    @XmlElement
    public final String getGmt() {
        return gmt;
    }

    /**
     * @return julian
     */
    @XmlElement
    public final String getJd() {
        return jd;
    }

    /**
     * @return jp
     */
    @XmlElement
    public final String getJp() {
        return jp;
    }

    /**
     * @return jst
     */
    @XmlElement
    public final String getJst() {
        return jst;
    }

    @XmlElement
    public final String getMjd() {
        return mjd;
    }

    /**
     * @param cycric セットする cycric
     */
    public final void setCycric(String cycric) {
        this.cycric = cycric;
    }

    /**
     * @param gmt セットする gmt
     */
    public final void setGmt(String gmt) {
        this.gmt = gmt;
    }

    /**
     * @param julian セットする julian
     */
    public final void setJd(String jd) {
        this.jd = jd;
    }

    /**
     * @param jp セットする jp
     */
    public final void setJp(String jp) {
        this.jp = jp;
    }

    /**
     * @param jst セットする jst
     */
    public final void setJst(String jst) {
        this.jst = jst;
    }

    /**
     * @param mjd セットする mjd
     */
    public final void setMjd(String mjd) {
        this.mjd = mjd;
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append("cycric,");
        sb.append("gmt,");
        sb.append("jd,");
        sb.append("jp,");
        sb.append("jst,");
        sb.append("mjd,");
        sb.append("\r\n");
        sb.append(getCycric()).append(",");
        sb.append(getGmt()).append(",");
        sb.append(getJd()).append(",");
        sb.append(getJp()).append(",");
        sb.append(getJst()).append(",");
        sb.append(getMjd());

        return sb.toString();
    }
}

JSONを返す

 @GET
 @Produces("application/json")
 public Response conv(@QueryParam("time") String time) {
     return jsonJst(time);
 }
 
 @GET
 @Path("/json/jst/{jst}")
 @Produces("application/json")
 public Response jsonJst(@PathParam("jst") String jst) {
     try {
         return Response.ok(timeconv(jst, +9)).build();
     } catch (Exception e) {
         e.printStackTrace();
         return Response.serverError().build();
     }
 }

XMLを返す

TEXTを返す

JSONPを返す

JSONP ってなに?

MyJsonpProvider?.java

package com.mycompany.samplecxf;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

@javax.ws.rs.ext.Provider
@javax.ws.rs.Consumes(value = {"application/json", "text/json"})
@javax.ws.rs.Produces(value = {"application/json", "text/json"})
public class MyJsonpProvider extends JacksonJsonProvider {

    @Context
    private HttpServletRequest request;
    
    public MyJsonpProvider() {
        super();
    }

    @Override
    public void writeTo(Object obj, Class<?> cls, Type genericType,
            Annotation[] anns, MediaType m,
            MultivaluedMap<String, Object> headers, OutputStream os)
            throws IOException {
        String fname = request.getParameter("callback");
        
        if (fname == null || "".equals(fname)) {
            // It's very important. The JSONPFunctionName is cached by JacksonJsonProvider.
            // So, we must null clear, if callback parameter on http-get is none.
            super.setJSONPFunctionName(null);
        } else {
            super.setJSONPFunctionName(fname);
        }
        super.writeTo(obj, cls, genericType, anns, m, headers, os);
    }
}

JacksonJsonProvider? を継承して、Bean を 文字列表記にする (Serialize) ときに、ID() を付け足すようにしたもの

WEB-INF/bean.xml

サンプルクライアント (jQuery)

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>JAX RS Ajax Example</title>
        <style type="text/css">
            /* ==================== STYLES ==================== */
            /* ==================== STYLES ==================== */
        </style>
        <script type="text/javascript"
        src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript">
            /* ==================== SCRIPTS ==================== */
            var URL = 'rest/timeconv?callback=?';
            $(document).ready(function() {
                $('button').on('click', function() {
                    var arg = {
                        time : $('#date').val(),
                        type : "jst"
                    }
                    $.getJSON(URL, arg, function(data) {
                        console.log(data);
                        $('div#JST').text(data.jst);
                        $('div#CYCRIC').text(data.cycric);
                        $('div#JP').text(data.jp);
                        $('div#GMT').text(data.gmt);
                        $('div#JD').text(data.jd);
                        $('div#MJD').text(data.mjd);
                    });
                });
            });
            /* ==================== SCRIPTS ==================== */
        </script>
    </head>
    <body>
        <input type="text" id="date" value="20130405060708"/>
        <button>Translate Time</button>
        <table>
            <tbody>
                <tr><td>JST</td>  <td>:</td> <td><div id="JST"></div></td></tr>
                <tr><td>干支</td> <td>:</td> <td><div id="CYCRIC"></div></td></tr>
                <tr><td>和暦</td> <td>:</td> <td><div id="JP"></div></td></tr>
                <tr><td>GMT</td>  <td>:</td> <td><div id="GMT"></div></td></tr>
                <tr><td>ユリウス日</td> <td>:</td> <td><div id="JD"></div></td></tr>
                <tr><td>修正ユリウス日</td> <td>:</td> <td><div id="MJD"></div></td></tr>
            </tbody>
        </table>
    </body>
</html>

List を返す

JSON や XML に変換する Bean に List<Sub> のフィールドを設定すれば良いだけ
XML に変換する場合には、デフォルトコンストラクタ (引数なしコンストラクタ public Entry(){}) を忘れずに

@XmlRootElement(name = "time")
public class JsonBean {

    private String cycric;
    private String gmt;
    private String jd;
    private String jp;
    private String jst;
    private String mjd;
    private List<Entry> person;

    @XmlElement
    public List<Entry> getPerson() {
        return person;
    }

    public void setPerson(List<Entry> person) {
        this.person = person;
    }
    
    (略)
@XmlRootElement
public class Entry {
    private String name;
    private String sex;
    
    public Entry(){
        super();
    }
    public Entry(String name, String sex) {
        this();
        this.name = name;
        this.sex = sex;
    }

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

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

    @XmlElement
    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
    
}

実行結果

[~]$ curl http://localhost:8080/SampleCxf/rest/timeconv/xml/jst/20130405060708 | tidy -xml -utf8 -indent
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   316  100   316    0     0  31246      0 --:--:-- --:--:-- --:--:-- 39500
No warnings or errors were found.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<time>
  <cycric>癸巳</cycric>
  <gmt>2013-04-04 21:07:08</gmt>
  <jd>2456387</jd>
  <jp>平成25年04月05日</jp>
  <jst>2013-04-05 06:07:08</jst>
  <mjd>56386.5</mjd>
  <person>
    <name>Sachi</name>
    <sex>female</sex>
  </person>
  <person>
    <name>Taro</name>
    <sex>male</sex>
  </person>
</time>

To learn more about HTML Tidy see http://tidy.sourceforge.net
Please send bug reports to html-tidy@w3.org
HTML and CSS specifications are available from http://www.w3.org/
Lobby your company to join W3C, see http://www.w3.org/Consortium
 
[~]$ curl http://localhost:8080/SampleCxf/rest/timeconv/json/jst/20130405060708 | python -mjson.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   207    0   207    0     0  17252      0 --:--:-- --:--:-- --:--:-- 20700
{
    "cycric": "\u7678\u5df3", 
    "gmt": "2013-04-04 21:07:08", 
    "jd": "2456387", 
    "jp": "\u5e73\u621025\u5e7404\u670805\u65e5", 
    "jst": "2013-04-05 06:07:08", 
    "mjd": "56386.5", 
    "person": [
        {
            "name": "Sachi", 
            "sex": "female"
        }, 
        {
            "name": "Taro", 
            "sex": "male"
        }
    ]
}

Java#JavaEE


添付ファイル: fileSampleCxf.zip 2143件 [詳細] filecxf3.png 2713件 [詳細] filecxf2.png 2795件 [詳細] filecxf1.png 2738件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2013-02-09 (土) 02:06:20 (4319d)
Short-URL: http://at-sushi.com/pukiwiki/index.php?cmd=s&k=5dae07944b
ISBN10
ISBN13
9784061426061