2015-03-26 14:39

Eclipse Git 基本操作

Git 只有本地端(local)跟遠端(remote)的分別,並不是 client 跟 server 的關係,只要是非專案本身的都可以稱為遠端,例如 A 與 B 專案都在自己的電腦裡,A 專案是可以將 B 專案設為遠端進行版本傳遞。

幾個基本日常操作的名稱意義:
  • commit: 將完成的程式提交到版本控制中
  • revert: 放棄修改,將程式回復
  • merge: 將兩個不同版本的程式進行合併
  • pull: 從遠端取回有差異的程式版本
  • push: 將本地端的版本傳到遠端
  • clone: 從遠端複製一個專案到本地



在專案建立 Git 版本控制


在一個專案上滑鼠右鍵選擇 [團隊]->[共享專案]



先建立 Git 儲存庫





將專案中的異動 commit 到 Git 版本控制


隨便建立幾個文件


在專案上右鍵選擇 [團隊]->[確定]


填寫 commit 的訊息,以及選擇要 commit 的檔案




程式回復到尚未修改時


在要回復的檔案右鍵選擇 [取代為]->[HEAD Revision]




版本合併


在專案上右鍵選擇 [團隊]->[Pull] 從遠端取回有差異的程式



當檔案出現衝突時會顯示紅色的標記,這時候檔案右鍵選擇 [團隊]->[Merge Tool]



接著就會出現合併的工具,修改完儲存關閉


最後檔案右鍵選擇 [團隊]->[Add to Index] 將檔案加到 commit 清單中




將本地端的版本傳到遠端






從遠端複製一個專案






指定來源的遠端


目的地目錄最好修改到 Workspace 中




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-10 15:18

[Java] 產生驗證碼圖片

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;

import javax.imageio.ImageIO;

public class TestCaptchaImage {

    public static void main(String[] args) throws Exception {
        String captcha = "09875";

        int width = 55;
        int height = 20;
        Color fontColor = new Color(36, 85, 92); /*文字顏色*/
        Color lineColor = new Color(65, 161, 175); /*線條顏色*/
        Color bgColor = new Color(208, 226, 229); /*底色*/

        Random random = new Random();
        random.setSeed(System.currentTimeMillis());

        BufferedImage image = new BufferedImage(
            width, height, BufferedImage.TYPE_INT_RGB
        );
        Graphics g = image.getGraphics();

        /* 底色 */
        g.setColor(bgColor);
        g.fillRect(0, 0, width, height);

        /* 畫線 */
        g.setColor(lineColor);
        for (int i=0; i < 20; i++) {
            g.drawLine(
                random.nextInt(width), 0,
                random.nextInt(width), height
            );
        }

        /* 畫出文字 */
        g.setFont(new Font("Atlantic Inline", Font.BOLD, 20));
        g.setColor(fontColor);
        g.drawString(captcha, 0, 18);

        /* 畫線 */
        g.setColor(lineColor);
        for (int i=0; i < 4; i++) {
            g.drawLine(
                0, random.nextInt(height),
                width, random.nextInt(height)
            );
        }

        g.dispose();

        ImageIO.write(image, "png", new File("captcha_image.png"));
    }
}

參考文件:
Graphics (Java 2 Platform SE 6)
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-05 10:24

用 Spring 取得 JSP 執行後的字串內容

為了取得執行後的字串內容,我們需要建立 Response 並且替換 PrintWriter,這樣才有辦法取得執行後的內容。

接著可以從 Spring 的 ViewResolver 去取得 View,再透過 View 去處理 render 前的包裝,最後才由 dispatcher 真正去處理 render 的動作。

想到要建立 Request 跟 Response 就感覺讓人頭痛,還好 Spring 有提供 Mock 的類別可以簡單地去建立 Request 跟 Response。


JspRenderer

package com.orion.webmvc.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.ui.Model;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;


public class JspRenderer {

    @Autowired
    private ServletContext servletContext;


    private ViewResolver viewResolver;

    public void setViewResolver(ViewResolver viewResolver) {
        this.viewResolver = viewResolver;
    }


    public String render(String viewName, Model model) 
        throws IOException 
    {
        return render(viewName, model.asMap());
    }

    public String render(String viewName, Map<String,Object> modelMap) 
        throws IOException 
    {

        RendererRequest request = new RendererRequest(servletContext);
        RendererResponse response = new RendererResponse();

        try {
            /* 透過 ViewResolver 取得 View 進行 render 的動作 */
            View view = viewResolver.resolveViewName(
                viewName, Locale.getDefault()
            );
            view.render(modelMap, request, response);

            return response.getContentAsString();
        }
        catch(Exception e) {
            throw new IOException(e);
        }
    }
}


class RendererRequest extends MockHttpServletRequest {

    private ServletContext servletContext;

    public RendererRequest(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public RequestDispatcher getRequestDispatcher(String path) {
        /* 需要透過真實的 RequestDispatcher 進行 Render */
        return servletContext.getRequestDispatcher(path);
    }
}


class RendererResponse extends MockHttpServletResponse {

    private StringWriter writer = new StringWriter();

    @Override
    public PrintWriter getWriter() throws UnsupportedEncodingException {
        /* 用 StringWriter 作為輸出的容器 */
        return new PrintWriter(writer);
    }

    @Override
    public boolean isCommitted() {
        /* true 是為了讓 View 可以採用 include 方式 Render 到 Response */
        return true;
    }

    @Override
    public String getContentAsString() throws UnsupportedEncodingException {
        /* 取得 Render 後的內容 */
        return writer.getBuffer().toString();
    }
}


配置 spring.xml

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

<bean id="jspRenderer" class="com.orion.webmvc.util.JspRenderer">
    <property name="viewResolver" ref="viewResolver"/>
</bean>


使用範例

//@Autowired
//private JspRenderer jspRenderer;

Map<String,Object> jspMap = new HashMap<String,Object>();
jspMap.put("jspMessage", "中文訊息測試");
jspMap.put("costMessage", 4567.89);

String jspOutput = jspRenderer.render("/mailer/test", jspMap);
System.out.println(jspOutput);


參考自:Render and capture the output of a JSP as a String | Technological Oddity