Webで簡単にProcessing!

/** boid
* Copyright 2011 Yutaka Kachi
* Licensed by New BSD License
*
* Boid:生き物の群れのように動き回るボール
*
**/

Windows Live Writer连接WordPress时出错问题

很久以前一直用WLW写WordPress博客,最近总是有部分WordPress博客总是和wlw连接不上,连接到日志时出错

错误显示如下:
———————————————————————————————————————
尝试连接到您的日志时出错:服务器响应无效 – 从日志服务器接收的对 blogger.getUsersBlogs 方法的响应无效:Invalid response document returned from XmlRpc server必须先纠正此错误才能继续操作。
———————————————————————————————————————

原因是XML-RPC返回的XML最后破损。几次上网查看都没有解决,今天终于找到解决方法。

原始的解决方案出自以下链接:

https://www.corelan.be/index.php/2008/10/14/windows-live-writer-unable-to-connect-to-wordpress-blog/

This is caused because something (a plugin ? my webserver (IIS) ? something else ?) decided to add UTF-8 BOM to the XML-RPC response. Result : the xml response is 3 bytes longer than expected, which causes the xml response to be truncated.

原因说是可能IIS的问题。可是我用的是LAMP,不过方法一样有效。

解决方法如下:
(1)在wp-includes目录下找到文件class.IXR.php,
(2)找到 $length = strlen($xml);  替换成 $length = strlen($xml)+3

Java JSON Processing

Java SEの標準APIだけでJSONを扱うサンプル

ファイル指定の場合ファイルから読み込む、指定しない場合、標準入力から読み込むように改造した。

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class JsonSample {

    public static void main(String[] args) throws Exception {
        // 起動時にオプションを指定しなかった場合は、このサンプルデータを使用する。
        String script = "{ \"key1\" : \"val1\", \"key2\" : \"val2\", \"key3\" : { \"ckey1\" : \"cval1\", \"ckey2\" : [ \"cval2-1\", \"cval2-2\" ] } }";
        if (args.length > 0) {
            java.io.File f = new java.io.File(args[0]);
            if (f.exists() && f.isFile()) {
                // 起動時の第1引数がファイルならファイルから読み込み(java 6 対応版なので、try-with-resources すら使えません。実際は、こんな書き方せずにちゃんとエラー処理してください)
                byte[] buf = new byte[new Long(f.length()).intValue()];
                java.io.FileInputStream fin = null; try { fin = new java.io.FileInputStream(f); fin.read(buf); } catch (Exception ex) { throw ex; } finally { if (fin != null) { fin.close(); }}
                script = args.length > 1 ? new String(buf, args[1]) : new String(buf); // ファイルの文字コードがシステムの文字コードと異なる場合は、第2引数で指定。例えば「UTF-8」や「JISAutoDetect」など。
            } else {
                script = args[0]; // ファイルでなければ、第1引数の文字列をそのまま JSON として扱う
            }
        } else {
            InputStreamReader pr; try {
                    pr = new InputStreamReader(System.in, "UTF-8");

                    BufferedReader br = new BufferedReader(pr);
                    String line = null;
                    while ((line = br.readLine()) != null) {
                       script = script + line;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        // ScriptEngine の eval に JSON を渡す時は、括弧で囲まないと例外が発生します。eval はセキュリティ的には好ましくないので、安全であることが不明なデータを扱うことは想定していません。
        Object obj = engine.eval(String.format("(%s)", script));
        // Rhino は、jdk1.6,7までの JavaScript エンジン。jdk1.8は「jdk.nashorn.api.scripting.NashornScriptEngine」
        Map<String, Object> map = jsonToMap(obj, engine.getClass().getName().equals("com.sun.script.javascript.RhinoScriptEngine"));
        System.out.println(map.toString());
    }

    static Map<String, Object> jsonToMap(Object obj, boolean rhino) throws Exception {
        // Nashorn の場合は isArray で obj が配列かどうか判断できますが、特に何もしなくても配列番号をキーにして値を取得し Map に格納できるので、ここでは無視しています。
        // Rhino だとインデックスを文字列として指定した場合に値が返ってこないようなので、仕方なく処理を切り分けました。
        // 実際は HashMap なんか使わずに自分で定義したクラス(配列はそのオブジェクトの List プロパティ)にマップすることになると思うので、動作サンプルとしてはこんなもんでよろしいかと。
        boolean array = rhino ? Class.forName("sun.org.mozilla.javascript.internal.NativeArray").isInstance(obj) : false;
        Class scriptObjectClass = Class.forName(rhino ? "sun.org.mozilla.javascript.internal.Scriptable" : "jdk.nashorn.api.scripting.ScriptObjectMirror");
        // キーセットを取得
        Object[] keys = rhino ? (Object[])obj.getClass().getMethod("getIds").invoke(obj) : ((java.util.Set)obj.getClass().getMethod("keySet").invoke(obj)).toArray();
        // get メソッドを取得
        Method method_get = array ? obj.getClass().getMethod("get", int.class, scriptObjectClass) : (rhino ? obj.getClass().getMethod("get", Class.forName("java.lang.String"), scriptObjectClass) : obj.getClass().getMethod("get", Class.forName("java.lang.Object")));
        Map<String, Object> map = new HashMap<String, Object>();
        for (Object key : keys) {
            Object val = array ? method_get.invoke(obj, (Integer)key, null) : (rhino ? method_get.invoke(obj, key.toString(), null) : method_get.invoke(obj, key));
            if (scriptObjectClass.isInstance(val)) {
                map.put(key.toString(), jsonToMap(val, rhino));
            } else {
                map.put(key.toString(), val.toString()); // サンプルなので、ここでは単純に toString() してますが、実際は val の型を有効に活用した方が良いでしょう。
            }
        }
        return map;
    }
}

 

参考:

Tannka Get Posts

Posts

記事の取得について、複数件が含まれるので、配列とオブジェクトのネストになる。

記事API のURL : http://tannka.com/wp-json/posts/

[{記事1オブジェクト},  {記事2オブジェクト},  {記事3オブジェクト}, ……]

 

スクリーンショット 2015-09-10 09.51.22

 

スクリーンショット 2015-09-10 11.26.00

課題:

  1. tannka サイト記事の取得と表示

Java http post

Create a Post Requires authentication


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
 
 
public class Main {
    public static void main(String[] args) {
        try {
            String content = '{"title": "This is a post","content_raw": "This is some content"}';
            URL url = new URL("http://wp-api.pw/wp-json/posts");
 
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString("test:password".getBytes(StandardCharsets.UTF_8)));
            conn.setRequestProperty("Content-Length", String.valueOf(content.getBytes("UTF-8").length));
            conn.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(content);
            wr.flush();
            wr.close();
 
            System.out.printf("Response: %d %s\n", conn.getResponseCode(), conn.getResponseMessage());
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String input;
 
            while ((input = br.readLine()) != null) {
                System.out.println(input);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

To create the raw data for an attachment. This is a binary object (blob), such as image data or a video.
(この部分のコードは未完成です、jpgファイル正しく転送されない、バイナリ形式の対応が必要)


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;


public class Main {
    public static void main(String[] args) {
        try {
            char[] buffer = new char[1024000];
            StringWriter writer = new StringWriter();
            FileInputStream in = new FileInputStream("/usr/share/backgrounds/nature/Aqua.jpg");
            for (int n = 0; -1 != (n = in.read());) {
                writer.write(buffer, 0, n);
            }
            in.close();
            String content = writer.toString();
            URL url = new URL("http://wp-api.pw/wp-json/media");

            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "image/jpeg");
            conn.setRequestProperty("Content-Disposition", "attachment; filename=large_meme12.jpg");
            conn.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString("test:nihao123".getBytes(StandardCharsets.UTF_8)));
            conn.setRequestProperty("Content-Length", String.valueOf(content.getBytes("UTF-8").length));
            conn.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(content);
            wr.flush();
            wr.close();

            System.out.printf("Response: %d %s\n", conn.getResponseCode(), conn.getResponseMessage());
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String input;

            while ((input = br.readLine()) != null) {
                System.out.println(input);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java http get

Tannka Get API endpoint

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
 
 
public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://tannka.com/wp-json/");
 
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
 
            System.out.printf("Response: %d %s\n", conn.getResponseCode(), conn.getResponseMessage());
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String input;
 
            while ((input = br.readLine()) != null) {
                System.out.println(input);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Tannka Get Posts

The Posts endpoint returns a Post Collection containing a subset of the site’s posts.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
 
 
public class Main {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://tannka.com/wp-json/posts");
 
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
 
            System.out.printf("Response: %d %s\n", conn.getResponseCode(), conn.getResponseMessage());
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String input;
 
            while ((input = br.readLine()) != null) {
                System.out.println(input);
            }
            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

cURL

cURLとは

cURLはURLシンタックスを用いてファイルを送信または受信するコマンドラインツールである。

cURLはlibcurlを使うため、幅広いインターネットプロトコルをサポートする。サポートしているプロトコル(より正確にはスキーム)は前項参照。

Daniel Stenbergは1997年にコマンドラインインタフェースでhttp、ftp、gopherその他多くのプロトコルでファイルを転送するための方法としてcURLを書き始めた。その他複数の人々がプロジェクトに重要な貢献をしている。 cURLはMIT Licenseに基づき配布されている。cURLはフリーソフトウェアである。

WordPress JSON API のcURLのサンプルコマンド

API endpoint

[chen@luna ~]$ curl -l http://wp-api.pw/wp-json/

Posts

Get

The Posts endpoint returns a Post Collection containing a subset of the site’s posts.

[chen@luna ~]$ curl -l http://wp-api.pw/wp-json/posts

Post

Create a Post Requires authentication

[chen@luna ~]$ cat data.json
{
    "title": "This is a post",
    "content_raw": "This is some content"
}
[chen@luna ~]$ curl --user test:password -X POST http://wp-api.pw/wp-json/posts --data @data.json

Delete

Delete a Post Requires authentication

[chen@luna ~]$ curl --user test:password -X DELETE http://wp-api.pw/wp-json/posts/229
{"message":"Deleted post"}

Media

Post

To create the raw data for an attachment. This is a binary object (blob), such as image data or a video.

[chen@luna ~]$ curl --user test:password -H 'Content-Type:image/jpeg' -H 'Content-Disposition: attachment; filename="test1551.jpg"' -X POST http://wp-api.pw/wp-json/media --data-binary @/home/chen/IMG_1551.jpg

Users

Get

This endpoint offers a permalink to get the current user, without needing to know the user’s ID.

[chen@luna ~]$ curl --user test:password http://wp-api.pw/wp-json/users/me
参考:
  • http://wp-api.net/curl/

WordPress JSON REST API

WordPress とは

世界No1ブログ、CMSツール。

通常下記のようなページ構造になっている。

wordpress_fundamentals

WordPress JSON REST APIとは

この API を使うことで、WordPress に関するありとあらゆる操作が REST API 化され、結果が JSON で返ってきます。

wp-api is an easy-to-use API which Access your WordPress site’s data through HTTP REST API.

wordpress-as-a-backend-9-638

wp-api Documentation:

 

Javaサンプルコード

  • http://wp-api.net/java/

數碼書齋