Spring參考手冊 7 綜合

翻譯自Spring官方文檔 4.1.2版本

相關文章:

一、在Spring中使用遠程調用

Spring集成了多個可以遠程調用的技術。遠程調用支持開發遠程服務,用普通的POJO即可實現。目前Spring支持以下幾個遠程調用技術:

  • Remote Method Invocation (RMI)
  • Spring HTTP invoker
  • Hessian
  • Burlap
  • Java Message Service(JMS),在底層使用JMS作為協議
  • Advanced Message Queuing Protocol(AMQP),在底層使用AMQP作為協議

Spring自動發現功能不適用于遠程接口,主要是為了避免對遠程調用者開啟太多的入口。

當討論Spring的遠程調用能力時我們使用以下實體類和相應的services:

public class Account implements Serializable{

    private String name;

    public String getName(){
        return name;
    }

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

}
public interface AccountService {

    public void insertAccount(Account account);

    public List<Account> getAccounts(String name);

}
public class AccountServiceImpl implements AccountService {

    public void insertAccount(Account acc) {
        // do something...
    }

    public List<Account> getAccounts(String name) {
        // do something...
    }

}

使用RMI的就不翻譯了,性能不太好。只翻譯一個Hessian。Burlap與Hessian配置方式一樣,只需要把Hessian這個詞換成Burlap就行了。AMQP看這里。關于它Spring另外有個項目。

1.1 使用Hessian通過HTTP遠程調用services

Hessian提供了一個二進制基于HTTP的遠程調用協議。更多信息請查看

Hessian通過HTTP溝通,我們可以自定義一個servlet。你可以輕松的寫出如下這樣的一個servlet來曝露你的服務。

<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>remoting</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

然后在WEB-INF文件夾創建一個remoting-servlet.xml配置文件

1.1.1 使用HessianServiceExporter曝露你的beans

我們將會在remoting-servlet.xml配置文件中創建一個HessianServiceExporter來曝露你的服務:

<bean id="accountService" class="example.AccountServiceImpl"></bean>

<bean name="/AccountService" class="org.springframework.remoting.caucho.HessianServiceExporter">
    <property name="service" ref="accountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

現在我們去準備在客戶端連接服務。沒有顯式的處理器映射被指定,那么BeanNameUrlHandlerMapping將會被使用,因此,這個服務將會曝露在DispatcherServlet的映射下并且以bean名稱(也就是/AccountService)命名的URL:http://HOST:8080/remoting/AccountService

1.1.2 在客戶端連接服務

使用HessianProxyFactoryBean我們可以在客戶端鏈接服務。SimpleObject使用AccountService來管理賬戶:

<bean class="example.SimpleObject">
    <property name="accountService" ref="accountService"/>
</bean>

<bean id="accountService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
    <property name="serviceUrl" value="http://remotehost:8080/remoting/AccountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

1.2 對使用Hessian或者Burlap曝露的服務應用HTTP基本身份驗證

Hessian 和 Burlap的協議都是基于HTTP的,你可以很輕松的使用HTTP基本身份驗證,例如:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors" ref="authorizationInterceptor"/>
</bean>

<bean id="authorizationInterceptor"
        class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">
    <property name="authorizedRoles" value="administrator,operator"/>
</bean>

在這個應用程序上下文中這個攔截器只允許administrators 和 operators這兩個角色調用bean方法。

具體文檔也沒說,有興趣可以自行搜索,Apache Shiro也可以使用。

二、在Spring中使用郵件

首先添加第三方依賴:

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.5.6</version>
</dependency>

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

org.springframework.mail包是Spring Framework email支持的根級別包。發送郵件的核心接口是MailSenderSimpleMailMessage類封裝了封裝一個簡單郵件的屬性例如發件人、收件人。 這個包還提供了一個統一的郵件異常MailException

org.springframework.mail.javamail.JavaMailSender接口添加了JavaMail的特性,例如MIME信息支持。JavaMailSender還為JavaMail MIME消息的準備活動提供了一個回調接口org.springframework.mail.javamail.MimeMessagePreparator

2.1 用法

我們假設這里有一個業務接口叫做OrderManager

public interface OrderManager {

    void placeOrder(Order order);

}

2.1.1 MailSender 和 SimpleMailMessage的基本用法

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class SimpleOrderManager implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage templateMessage;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setTemplateMessage(SimpleMailMessage templateMessage) {
        this.templateMessage = templateMessage;
    }

    public void placeOrder(Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        // 創建一個線程安全的template message副本并且自定義它
        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
        msg.setTo(order.getCustomer().getEmailAddress());
        msg.setText(
            "Dear " + order.getCustomer().getFirstName()
                + order.getCustomer().getLastName()
                + ", thank you for placing order. Your order number is "
                + order.getOrderNumber());
        try{
            this.mailSender.send(msg);
        }
        catch (MailException ex) {
            // 簡單的輸出它,然后繼續
            System.err.println(ex.getMessage());
        }
    }

}

下面是一些bean定義:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="mail.mycompany.com"/>
</bean>

<!-- 這是一個template message,使用默認狀態預加載它 -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
    <!-- 發件人 -->
    <property name="from" value="customerservice@mycompany.com"/>

    <!-- 郵件主題 -->
    <property name="subject" value="Your order"/>
</bean>

<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
    <property name="mailSender" ref="mailSender"/>
    <property name="templateMessage" ref="templateMessage"/>
</bean>

2.1.2 使用JavaMailSender 和 MimeMessagePreparator

這是另一個OrderManager實現,使用的了MimeMessagePreparator回調接口。請注意mailSender參數是JavaMailSender類型,這樣我們便可使用JavaMail的MimeMessage類:

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

import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class SimpleOrderManager implements OrderManager {

    private JavaMailSender mailSender;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void placeOrder(final Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {

                mimeMessage.setRecipient(Message.RecipientType.TO,
                        new InternetAddress(order.getCustomer().getEmailAddress()));
                mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
                mimeMessage.setText(
                        "Dear " + order.getCustomer().getFirstName() + " "
                            + order.getCustomer().getLastName()
                            + ", thank you for placing order. Your order number is "
                            + order.getOrderNumber());
            }
        };

        try {
            this.mailSender.send(preparator);
        }
        catch (MailException ex) {
            // 簡單的輸出它,然后繼續
            System.err.println(ex.getMessage());
        }
    }

}

更多信息請參考JavaMail的javadoc。

2.1.3 使用JavaMail MimeMessageHelper

// 在現實中這里是通過依賴注入獲得的
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("test@host.com");
helper.setText("Thank you for ordering!");

sender.send(message);

發送附件與內聯資源

附件好理解,內聯資源舉個例子可以是圖片或者Excel顯式在你的郵件正文中而不是作為一個附件顯示。

附件

下面這個例子展示了如何使用MimeMessageHelper來發送一封郵件并且使用一張圖片作為附件:

// 在現實中這里是通過依賴注入獲得的
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// 使用true標識指明你需要一個multipart信息
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test@host.com");

helper.setText("Check out this image!");

// 讓我們添加一個附件
FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addAttachment("CoolImage.jpg", file);

sender.send(message);

內聯資源

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test@host.com");

// use the true flag to indicate the text included is HTML
helper.setText("<html><body><img src='cid:identifier1234'></body></html>", true);

// let's include the infamous windows Sample file (this time copied to c:/)
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);

sender.send(message);

一個基于Velocity的例子

要使用Velocity來創建你的郵件模版,你首先要將Velocity的類庫引入。

創建模版頁面:

# in the com/foo/package
<html>
    <body>
        <h3>Hi ${user.userName}, welcome to the Chipping Sodbury On-the-Hill message boards!</h3>

        <div>
            Your email address is <a href="mailto:${user.emailAddress}">${user.emailAddress}</a>.
        </div>
    </body>
</html>

配置:

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

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="mail.csonth.gov.uk"/>
    </bean>

    <bean id="registrationService" class="com.foo.SimpleRegistrationService">
        <property name="mailSender" ref="mailSender"/>
        <property name="velocityEngine" ref="velocityEngine"/>
    </bean>

    <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
        <property name="velocityProperties">
            <value>
                resource.loader=class
                class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
            </value>
        </property>
    </bean>

</beans>
package com.foo;

import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;

import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;

public class SimpleRegistrationService implements RegistrationService {

    private JavaMailSender mailSender;
    private VelocityEngine velocityEngine;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    public void register(User user) {

        // Do the registration logic...

        sendConfirmationEmail(user);
    }

    private void sendConfirmationEmail(final User user) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws Exception {
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
                message.setTo(user.getEmailAddress());
                message.setFrom("webmaster@csonth.gov.uk"); // could be parameterized...
                Map model = new HashMap();
                model.put("user", user);
                String text = VelocityEngineUtils.mergeTemplateIntoString(
                        velocityEngine, "com/dns/registration-confirmation.vm", model);
                message.setText(text, true);
            }
        };
        this.mailSender.send(preparator);
    }

}

未完,待續...

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容