顯示具有 筆記 標籤的文章。 顯示所有文章
顯示具有 筆記 標籤的文章。 顯示所有文章
2023-02-21 10:33

[Python] Flask Log 配置

import os
import logging
import logging.handlers

from flask import Flask, g, request, json

app = Flask(__name__)


#[ Log 配置 ]#############################################################
 # 用來記錄無法處理的錯誤 (PS: 使用 WSGI 會依附 Apache 的設定,可以不用配置)

# https://docs.python.org/zh-cn/3/library/logging.html
formatter = logging.Formatter("%(asctime)s [%(levelname)s]  %(message)s")

# https://docs.python.org/zh-tw/3/library/logging.handlers.html#timedrotatingfilehandler
handler = logging.handlers.TimedRotatingFileHandler("log/web-api",
    when = "D",
    interval = 1,
    backupCount = 7,
    encoding = "UTF-8",
    delay = False,
    utc = True)
handler.setFormatter(formatter)

app.logger.addHandler(handler)
2023-02-21 10:13

[Python] Flask 自訂日期的 Json 轉換

import os
import datetime
import time

from flask import Flask, g, request, json
from flask.json import JSONEncoder


class CustomJsonEncoder(JSONEncoder):
    # 針對日期自訂 Json 轉換

    def default(self, obj):
        if isinstance(obj, datetime.date):
            return obj.isoformat().replace('T', ' ')

        return super().default(obj)


app = Flask(__name__)

app.json_encoder = CustomJsonEncoder
app.config['JSON_AS_ASCII'] = False  # 返回結果可以正確顯示中文
2023-02-21 10:05

[Python] Flask MySQL 連線管理

import os
import mysql.connector as sql

from werkzeug.exceptions import HTTPException, BadRequest
from flask import Flask, g, request, json


app = Flask(__name__)



#[ DB 處裡 ]#############################################################

# https://docsxyz.com/zh-hant/wiki/python/connector-python-connectargs
db_config = {
    'host'      : "localhost",
    'user'      : "XXXX",
    'passwd'    : "XXXX",
    'db'        : 'XXXX',
    'use_pure'  : True,
    'autocommit': True,
    'charset'   : 'utf8',
}


@app.before_request
def before_request():
    # 在 request 前開啟 DB 連線
    # g 是 Flask global 在每個 request 有獨立的 context

    g.cnt = sql.connect(**db_config)
    g.cursor = g.cnt.cursor(dictionary = True)



@app.after_request
def after_request(response):
    # 在 request 後結束 DB 連線

    cursor = g.get('cursor', None)
    if cursor is not None:
        # 當 cursor 還有 row 沒有取出,close 會發生錯誤
        if cursor.with_rows : cursor.fetchall()
        cursor.close()

    cnt = g.get('cnt', None)
    if cnt is not None:
        cnt.close()

    return response
2023-02-21 09:55

[Python] Flask 筆記

相依套件:
-------------------------------------------------------------------------------
python-3.8.10-amd64.exe

pip install Flask
pip install flask_cors
pip install mysql-connector-python
pip install pycryptodomex
pip install py-linq     # https://viralogic.github.io/py-enumerable/


Apache CGI 配置,用虛擬 Script 指向到 app.cgi
-------------------------------------------------------------------------------


ScriptAlias /web-api  D:/iog-project/web-api/app.cgi

<Directory "D:/iog-project/web-api/">
Options ExecCGI 
AllowOverride all
Require local
</Directory>


-------------------------------------------------------------------------------

# 正常執行
flask run

# 除錯執行  (flask 會提供除錯功能,並將 logger 從 warning 提升到 debug 
export FLASK_ENV=development    # for linux / git  bash 
set FLASK_ENV=development       # for windows cmd
flask run

# 列出設定的路徑
flask routes


其他
-------------------------------------------------------------------------------

因為 web-api 的格式是 Json,所以遵照 JS 的命名風格,欄位名稱開頭小寫第二個字大寫

2023-02-21 09:53

[Python] Flask 錯誤處裡


from werkzeug.exceptions import HTTPException, BadRequest
from flask import Flask, g, request, json

app = Flask(__name__)


#[ 錯誤處裡 ]#############################################################
@app.errorhandler(Exception)
def handle_exception(e):
    if isinstance(e, HTTPException): return e  # 讓 HTTPException 交由下一個處理

    app.logger.exception("Internal Server Error.")  # log 錯誤訊息
    if app.debug : return e

    return json.jsonify({'message': 'Internal Server Error.'}), 500


@app.errorhandler(HTTPException)
def handle_exception(e):
    response = e.get_response()
    return json.jsonify({'message': e.description}), e.code
2019-07-22 16:49

C# COM 元件使用 MTA

先前有用到一個通訊用的 COM 元件,因為連線不穩的時候會影響到 Main Thread 造成這個 WinForm UI 卡住,連帶所有 Main Thread 下的其他 Thread 都卡住,最先找到的方法是在 Program Main 上改用 MTAThreadAttribute,的確是可以解決卡住的問題。

但 WPF 就不可以用 MTAThreadAttribute,因為 WPF 必須執行在 STAThread 的環境上,又開始苦惱這個問題了,問題應該還是有解套的辦法的只是知識不足,最後在 WIKI 中看到重要的知識。

WIKI 元件物件模型
一個COM物件只能存在於一個套間。COM物件一經建立就確定所屬套間,並且直到銷毀它一直存在於這個套間。

所以只要用其他 Thread 去建立 COM 元件就不會影響到 Main Thread 了,簡單的解決問題,果然是知識不足。

ActEasyIF actConnection;

var waiter = new AutoResetEvent(false);

new Thread(() =>
{
    /* 建構 COM 元件 */
    _actConnection = new ActEasyIF();

    waiter.Set();
}).Start();

waiter.WaitOne(500); /* 等待建立結束 */
2019-07-22 15:36

C# struct 轉換到 byte array

StructLayout: https://docs.microsoft.com/zh-tw/dotnet/api/system.runtime.interopservices.layoutkind?view=netframework-4.8
Pack: 資料欄位的對齊,這會影響最短欄位的 byte 長度

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct PollResponse
{
    public int AppId;
    public byte Serial;
    public short Station;
}


void Main()
{
    var data = new PollResponse
    {
        AppId = 1,
        Serial = 2,
        Station = 3,
    };

    Type type = typeof(PollResponse);
    int size = Marshal.SizeOf(type);
    var bytes = new byte[size];

    /* struct to byte array */
    IntPtr ptrIn = Marshal.AllocHGlobal(size);
    Marshal.StructureToPtr(data, ptrIn, true);
    Marshal.Copy(ptrIn, bytes, 0, size);
    Marshal.FreeHGlobal(ptrIn);

    BitConverter.ToString(bytes).Dump();
    /* 01-00-00-00 - 02 - 03-00 */


    /* byte array to struct */
    IntPtr ptrOut = Marshal.AllocHGlobal(size);
    Marshal.Copy(bytes, 0, ptrOut, size);
    var result = (PollResponse)Marshal.PtrToStructure(ptrOut, type);
    Marshal.FreeHGlobal(ptrOut);

    result.Dump();
    /* { AppId = 1, Serial = 2, Station = 3 } */
}
2019-07-21 17:21

C# 讓 Dequeue 更方便的擴充方法

void Main()
{
    var queue = new Queue<int>();

    for (int i = 0; i < 10; i++) { queue.Enqueue(i); }
    string.Join(",", queue).Dump(); /* 0,1,2,3,4,5,6,7,8,9 */


    var take = queue.EnumerateDequeue().Take(4).ToList();
    string.Join(",", take).Dump(); /* 0,1,2,3 */
    string.Join(",", queue).Dump(); /* 4,5,6,7,8,9 */


    var take2 = queue.EnumerateDequeue().Take(40).ToList();
    string.Join(",", take2).Dump(); /* 4,5,6,7,8,9 */
    string.Join(",", queue).Dump(); /* */
}



public static class QueueExtensions
{

   public static IEnumerable<T> EnumerateDequeue<T>(this Queue<T> source)
   {
       while (source.Count > 0) { yield return source.Dequeue(); }
   }

   public static IEnumerable<T> EnumerateDequeue<T>(this ConcurrentQueue<T> source)
   {
       T outValue;
       while (source.TryDequeue(out outValue)) { yield return outValue; }
   }

}
2019-07-21 17:06

C# 在 Enum 上增加附加資訊

C# 的 Enum 是個很方便的類型,如果可以再增加額外的資訊就更方便了,這裡利用 Attribute 去定義 Enum 額外的資訊,再用擴充方法取得 Enum 所屬的資訊。

用 Attribute 來定義有個好處,未來在增減 Enum 時可以一起進行修改,不用擔心會有遺漏而沒修改的問題。

void Main()
{
    PortAreaCode.F1Front.GetFloor().Dump(); /* F1 */
}


public enum PortAreaCode
{
    [AreaMeta("None", 0)]
    None,

    [AreaMeta("F1", 1)]
    F1Front,

    [AreaMeta("F2", 1)]
    F2Front,
}



/// <summary>PortAreaCode 額外附屬資訊定義的 Attribute</summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
class AreaMetaAttribute : Attribute
{
    public string Floor { get; private set; }
    public int WarehouseId { get; private set; }

    public AreaMetaAttribute() : this("None", 0) { }

    public AreaMetaAttribute(string floor, int warehouseId)
    {
        Floor = floor;
        WarehouseId = warehouseId;
    }
}



/// <summary>PortAreaCode 的擴充方法</summary>
public static class PortAreaCodeExtensions
{
    private static AreaMetaAttribute _defaultMeta = new AreaMetaAttribute();

    private static AreaMetaAttribute getMeta(PortAreaCode value)
    {
        FieldInfo field = typeof(PortAreaCode).GetField(value.ToString());
        if(field == null) { return _defaultMeta; }

        var meta = field.GetCustomAttribute<AreaMetaAttribute>();
        return meta ?? _defaultMeta;
    }

    public static string GetFloor(this PortAreaCode value)
    {
        return getMeta(value).Floor;
    }

    public static int GetWarehouseId(this PortAreaCode value)
    {
        return getMeta(value).WarehouseId;
    }
}
2019-07-21 16:29

C# 用 gzip 壓縮字串並取得 base64 字串

這個使用方式的效果是有但書的,當 Source 的重複率不高壓縮的效果就不會好,再加上 base64 就是用可見文字去表示 byte 值,這會讓 base64 後的結果比 byte array 還要長,所以壓縮率沒有到達一定的程度下,輸出反而會比 Source 的字串還要長。

//using System.IO.Compression;


void Main()
{
    string text = "OptionPostal,OptionClassType,OptionTalentItem";
    text.Length.Dump(); /* 45 */

    string compressBase64 = compress(text);
    compressBase64.Length.Dump(); /* 76 */
    compressBase64.Dump(); 
    /* H4sIAAAAAAAEAPMvKMnMzwvILy5JzNHxB3OccxKLi0MqC1Kh/JDEnNS8Es+S1FwAaY6qVC0AAAA= */

    string decompressText = decompress(compressBase64);
    decompressText.Dump(); 
    /* OptionPostal,OptionClassType,OptionTalentItem */

    text = "OptionPostal,OptionClassType,OptionTalentItem,OptionPostal,OptionClassType,OptionTalentItem,OptionPostal,OptionClassType,OptionTalentItem,OptionPostal,OptionClassType,OptionTalentItem";
    text.Length.Dump(); /* 183 */

    compressBase64 = compress(text);
    compressBase64.Length.Dump(); /* 84 */
    compressBase64.Dump(); 
    /* H4sIAAAAAAAEAPMvKMnMzwvILy5JzNHxB3OccxKLi0MqC1Kh/JDEnNS8Es+S1FyowCBQDQBPmlWktwAAAA== */

}


/*壓縮*/
private static string compress(string text)
{
    if (string.IsNullOrEmpty(text)) { return text; }

    byte[] buffer = Encoding.UTF8.GetBytes(text);

    using (var outStream = new MemoryStream())
    using (var zip = new GZipStream(outStream, CompressionMode.Compress))
    {
        zip.Write(buffer, 0, buffer.Length);
        zip.Close();

        string compressedBase64 = Convert.ToBase64String(outStream.ToArray());
        return compressedBase64;
    }
}


/*解壓縮*/
private static string decompress(string compressed)
{
    if (string.IsNullOrEmpty(compressed)) { return compressed; }

    byte[] buffer = Convert.FromBase64String(compressed);

    using (var inStream = new MemoryStream(buffer))
    using (var outStream = new MemoryStream())
    using (var zip = new GZipStream(inStream, CompressionMode.Decompress))
    {
        zip.CopyTo(outStream);
        zip.Close();

        string text = Encoding.UTF8.GetString(outStream.ToArray());
        return text;
    }
}
2019-07-21 15:53

產生 IP v6 的 mask byte array

int length = 121; /* total 128 */

var mask = new byte[16];

for (int i = 0; i < 16; i++)
{
    mask[i] = 0xff;
    if (length > -8) { length -= 8; }
    if (length < 0) { mask[i] = (byte)(mask[i] << -length); }
    /* 當 length 出現負值時代表需要進行位移 */
}

BitConverter.ToString(mask).Dump();
/* FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-80 */
2019-07-21 15:43

C# DateTimeOffset Parse Patch

DateTimeOffset 在 Parse 時會使用 Local TimeZone,這會與期望的 TimeZone 產生偏差,需要進行差值修補。

//TimeZoneInfo.GetSystemTimeZones().Dump();

/* (UTC+02:00) 開羅 */
var zone = TimeZoneInfo.FindSystemTimeZoneById("Egypt Standard Time");
zone.Dump();

var date = DateTimeOffset.Parse("2019-07-01 15:00:00");
date.Dump(); /* 2019/7/1 下午 03:00:00 +08:00 */

var diff = date.Offset - zone.BaseUtcOffset;
diff.Dump(); /* 06:00:00 */

date = date.Add(diff);
date.Dump(); /* 2019/7/1 下午 09:00:00 +08:00 */

date = TimeZoneInfo.ConvertTime(date, zone);
date.Dump(); /* 2019/7/1 下午 03:00:00 +02:00 */
2015-03-13 13:12

[Java] Ant zip 解壓縮筆記

<unzip dest="./target_dir">

    <!-- 來源的壓縮檔 -->
    <fileset dir="lib">
        <include name="tiles-jsp-*.jar"/>
    </fileset>

    <!-- 要解出的檔案 -->
    <patternset>
        <include name="**/*.tld"/>
    </patternset>

    <!-- 解出路徑的轉換 -->
    <mapper type="flatten"/>

</unzip>

參考文件:
Apache Ant™ User Manual : Unzip Task
Apache Ant™ User Manual : Mapper
2015-03-13 11:59

[Java] Reflection 筆記

@SuppressWarnings("unused")
Object obj = new Object() {
    String id = "123";
    public String name = "Jax";
};

Class<?> cl = obj.getClass();

for (Field field : cl.getFields()) {
    System.out.printf("%s = %s {%s}\n",
        field.getName(), field.get(obj), field.getType());
}

System.out.println("=======================");

for (Field field : cl.getDeclaredFields()) {
    System.out.printf("%s = %s {%s}\n",
        field.getName(), field.get(obj), field.getType());
}

Output:
name = Jax {class java.lang.String}
=======================
id = 123 {class java.lang.String}
name = Jax {class java.lang.String}
2015-03-06 17:12

[Java] 製作縮圖筆記

package test_image;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class TestImageResize {

    private static int targetWidth = 120;
    private static int targetHeight = 80;
    private static double targetRate = (double) targetWidth / targetHeight;

    public static void main(String[] args) throws Exception {

        System.out.printf("Target w:%s, h:%s, r:%s\n", 
            targetWidth, targetHeight, targetRate);


        BufferedImage image = ImageIO.read(new File("input.jpg"));

        int type = image.getType();
        if(type == 0) { type = BufferedImage.TYPE_INT_ARGB; }

        int width = image.getWidth();
        int height = image.getHeight();
        double rate = (double) width / height;

        System.out.printf("Source w:%s, h:%s, r:%s\n", width, height, rate);



        /* 等比例縮小至指定大小內 */
        int rWidth = targetWidth;
        int rHeight = targetHeight;

        if(width < targetWidth && height < targetHeight) {
            rWidth = width;
            rHeight = height;
        } else if(rate > targetRate) {
            rHeight = (int) (targetWidth / rate);
        } else {
            rWidth = (int) (targetHeight * rate);
        }
        System.out.printf("Resize w:%s, h:%s\n", rWidth, rHeight);

        BufferedImage resize1 = new BufferedImage(rWidth, rHeight, type);
        Graphics g1 = resize1.getGraphics();
        g1.drawImage(image, 0, 0, rWidth, rHeight, null);
        g1.dispose();

        ImageIO.write(resize1, "jpg", new File("output_1.jpg"));




        /* 等比例縮小填滿指定大小 */
        BufferedImage resize2 = new BufferedImage(targetWidth,targetHeight,type);
        Graphics g2 = resize2.getGraphics();

        int startX = 0;
        int startY = 0;
        int size = 0;

        if(rate > targetRate) {
            startX = (int) (width - height * targetRate) / 2;
            size = height;
        } else {
            startY = (int) (height - width / targetRate) / 2;
            size = width;
        }
        System.out.printf("x:%s, y:%s, size:%s\n", startX, startY, size);

        g2.drawImage(
            image,
            0, 0, targetWidth, targetHeight,
            startX, startY, (size + startX), (size + startY),
            null
        );

        g2.dispose();

        ImageIO.write(resize2, "jpg", new File("output_2.jpg"));
    }
}

參考文件:
Graphics (Java 2 Platform SE 6)
2015-03-06 15:33

[Java] Jsoup 筆記

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class TestJsoup {

    public static void main(String[] args) throws Exception {

        String url = "http://epg.dishstar.net/calendar.php?s=DISC&d=1";

        // Document doc = Jsoup.parse(new URL(url), 5000);
        Document doc = Jsoup.connect(url)
                            .userAgent("Mozilla/5.0")
                            .timeout(5000).get();

        Elements trs = doc.select("table tr");
        for (Element tr : trs) {
            String time = tr.select("td:eq(0)").text();
            String title = tr.select("td:eq(1)").text();

            System.out.println(time + " <=> " + title);
        }
    }
}
2015-03-06 11:57

Spring JavaMail 筆記

Gmail via SSL
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com" />
    <property name="port" value="465" />
    <property name="username" value="smtp-user" />
    <property name="password" value="smtp-passwd" />

    <property name="javaMailProperties">
        <props>
            <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
            <prop key="mail.smtp.auth">true</prop>
        </props>
    </property>
</bean>


Gmail via TLS
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com" />
    <property name="port" value="587" />
    <property name="username" value="smtp-user" />
    <property name="password" value="smtp-passwd" />
    <property name="javaMailProperties">
        <props>
            <prop key="mail.smtp.starttls.enable">true</prop>
            <prop key="mail.smtp.auth">true</prop>
        </props>
    </property>
</bean>


Sample Code
package test_mail;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class TestSpringMail {

    public static void main( String[] args ) throws Exception {

        AbstractApplicationContext context
            = new ClassPathXmlApplicationContext("test_mail/spring-mail.xml");

        JavaMailSender mailSender 
            = (JavaMailSender) context.getBean("mailSender");

        sample1(mailSender);
        sample2(mailSender);
        sample3(mailSender);

        context.close();
    }


    public static void sample1(JavaMailSender mailSender) throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();

        mimeMessage.setFrom("from@no-spam.com");
        mimeMessage.setRecipients(
            Message.RecipientType.TO, "to@no-spam.com"
        );
        mimeMessage.setSubject("Testing Subject");
        mimeMessage.setContent(
            "<b>Testing Content.</b>", 
            "text/html; charset=utf-8"
        );

        mailSender.send(mimeMessage);
    }


    public static void sample2(JavaMailSender mailSender) throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "utf-8");

        message.setFrom("from@no-spam.com");
        message.setTo("to@no-spam.com");
        message.setSubject("Testing Subject");
        message.setText("<b>Testing Content.</b>", true);

        mailSender.send(mimeMessage);
    }


    public static void sample3(JavaMailSender mailSender) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("from@no-spam.com");
        message.setTo("to@no-spam.com");
        message.setSubject("Testing Subject");
        message.setText("Testing Content.");

        mailSender.send(message);
    }

}


參考自:
JavaMail API – Sending email via Gmail SMTP example : Mkyong
Spring – Sending e-mail with attachment : Mkyong
Spring – Define an E-mail template in bean configuration file : Mkyong
Spring – Sending E-mail via Gmail SMTP server with MailSender : Mkyong
2015-03-04 11:33

[Java] FileFilter 筆記

File dir = new File("D:/log");

File[] list = dir.listFiles(new FileFilter(){
    public boolean accept(File file) {
        return file.getName().endsWith(".txt");
    }
});

for(File file : list){
    System.out.println(file.getAbsoluteFile());
}

// 004.txt
2015-03-04 11:23

[Java] Object Serializable 筆記

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Address implements Serializable {

    private static final long serialVersionUID = 1L;

    String street;
    String country;

    public Address() {}

    public Address(String s, String c) {
        street = s; country = c;
    }

    public void setStreet(String street){ this.street = street; }
    public String getStreet(){ return this.street; }

    public void setCountry(String country){ this.country = country; }
    public String getCountry(){ return this.country; }

    @Override
    public String toString() {
        return String.format("Street : %s Country : %s", street, country);
    }
}


public class TestSerializable {

    public static void main(String[] args) throws Exception {
        Address addr = new Address("wall street", "united state");

        FileOutputStream fout = new FileOutputStream("address.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        oos.writeObject(addr);
        oos.close();

        FileInputStream fin = new FileInputStream("address.ser");
        ObjectInputStream ois = new ObjectInputStream(fin);
        Address addr2 = (Address) ois.readObject();
        ois.close();

        System.out.println(addr2);
        // Street : wall street Country : united state
    }
}

參考自:
How to read an Object from file in Java : Mkyong
How to write an Object to file in Java : Mkyong
Understand the serialVersionUID : Mkyong
2015-03-01 20:14

[Java] Jackson Json Parser 筆記

Object Encode / Decode
import java.util.Arrays;
import java.util.Date;

import com.fasterxml.jackson.databind.ObjectMapper;

class Album {
    private int id;
    private String title;
    private Date date;
    private String[] list;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    public Date getDate() { return date; }
    public void setDate(Date date) { this.date = date; }

    public String[] getList() { return list; }
    public void setList(String[] list) { this.list = list; }

    @Override
    public String toString() {
        return String.format("id: %s, title: %s, date: %s, list: %s",
            id, title, date, Arrays.toString(list)
        );
    }
}

public class TestJackson {

    public static void main(String[] args) throws Exception {
        Album album = new Album();
        album.setId(1);
        album.setTitle("Go Go Go!");;
        album.setDate(new Date());
        album.setList(new String[]{"Love", "Despair"});

        ObjectMapper jsonMapper = new ObjectMapper();

        String json = jsonMapper.writeValueAsString(album);
        System.out.println(json);
        // {"id":1,"title":"Go Go Go!","date":1425211903948,"list":["Love","Despair"]}

        Album album2 = jsonMapper.readValue(json, Album.class);
        System.out.println(album2);
        // id: 1, title: Go Go Go!, date: Sun Mar 01 20:11:43 CST 2015, list: [Love, Despair]
    }
}


Parser to Map
ObjectMapper jsonMapper = new ObjectMapper();
Map<String,String> map;

map = jsonMapper.readValue(
    "{\"name\":\"jax\", \"age\":\"31\"}",
    new TypeReference<HashMap<String,String>>(){}
);
System.out.println(map);
// {age=31, name=jax}


jsonMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
jsonMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

map = jsonMapper.readValue(
    "{name:'jax', age:'31'}",
    new TypeReference<HashMap<String,String>>(){}
);
System.out.println(map);
// {age=31, name=jax}


Encode Date
Date date = new Date();

String json;
ObjectMapper jsonMapper = new ObjectMapper();

json = jsonMapper.writeValueAsString(date);
System.out.println(json);
// 1425211840183


jsonMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

json = jsonMapper.writeValueAsString(date);
System.out.println(json);
// "2015-03-01T12:10:40.183+0000"

參考自:FasterXML/jackson-databind · GitHub