java发送邮件实现已读未读功能实现的问题记录

需求:通过img标签嵌入服务器图片地址的方式解决接收用户是否已读或者未读。

发送邮件的java代码:

1、使用图片链接的方式,将图片的地址放入超链接中;

2、使用java的MimeMessage类,将图片作为附件的形式发送,这样QQ网页邮箱就可以正常显示图片。

以下是java代码示例:

// 创建MimeMessage实例
MimeMessage message = new MimeMessage(session);

// 设置发件方地址
message.setFrom(new InternetAddress(from));

// 设置收件方地址
message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));

// 设置邮件主题
message.setSubject("测试邮件发送,包含图片");

// 创建邮件正文
MimeBodyPart text = new MimeBodyPart();

// 设置邮件正文
text.setContent("<html><body>这是一封包含图片的测试邮件,请注意查收!<br/><img='http://xxx.jpg' alt='test'></body></html>", "text/html;charset=UTF-8");

// 创建邮件正文部分
MimeMultipart mm = new MimeMultipart();

// 添加邮件正文
mm.addBodyPart(text);

// 设置邮件正文
message.setContent(mm);

// 保存邮件
message.saveChanges();

下载邮件的代码

 
import java.io.InputStream;
 
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.jeff.utils.HttpUtils;
 
@RestController
public class FileController {
 
	/**
	 * 
	 * @description: 从服务器端获得图片,并输出到页面
	 */
	@RequestMapping("getImage")
	public void getImage(HttpServletResponse resp) {
		// 服务器图片url
		String urlPath = "http://192.168.1.100:8080/images/jie.jpg";
		// 从服务器端获得图片,并输出到页面
		InputStream inputStream = HttpUtils.getInputStream(urlPath);
		HttpUtils.writeFile(resp, inputStream);
	}
 
}
 

 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
 
import javax.servlet.http.HttpServletResponse;
 
public class HttpUtils {
 
	/**
	 * 创建测试类(FileController.java)
	 * @description: 从服务器获得一个输入流(本例是指从服务器获得一个image输入流)
	 */
	public static InputStream getInputStream(String urlPath) {
		InputStream inputStream = null;
		HttpURLConnection httpURLConnection = null;
		try {
			URL url = new URL(urlPath);
			httpURLConnection = (HttpURLConnection) url.openConnection();
			// 设置网络连接超时时间
			httpURLConnection.setConnectTimeout(3000);
			// 设置应用程序要从网络连接读取数据
			httpURLConnection.setDoInput(true);
			httpURLConnection.setRequestMethod("GET");
			int responseCode = httpURLConnection.getResponseCode();
			System.out.println("responseCode is:" + responseCode);
			if (responseCode == HttpURLConnection.HTTP_OK) {
				// 从服务器返回一个输入流
				inputStream = httpURLConnection.getInputStream();
			} else {
				inputStream = httpURLConnection.getErrorStream();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return inputStream;
	}
 
	/**
	 * 创建http工具类(HttpUtils.java)
	 * @description: 将输入流输出到页面
	 */
	public static void writeFile(HttpServletResponse resp, InputStream inputStream) {
		OutputStream out = null;
		try {
			out = resp.getOutputStream();
			int len = 0;
			byte[] b = new byte[1024];
			while ((len = inputStream.read(b)) != -1) {
				out.write(b, 0, len);
			}
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
 
}
 

>存在的问题:

上面的方法可以获取用户已读状态,但是在有的邮件客户端,图片无法隐藏,所以我们需要在服务URL请求结束后,真实返回一张图片,但是图片最好近乎不可见。

用java简单生成一个不可见的图片(一个近乎不可见的点),代码如下:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import jodd.util.Base64;

public class TestImage {

  public String getImageBase64() {
    ByteArrayOutputStream baos = null;
    StringBuffer sb = null;
    try {
      int width = 1;
      int height = 1;
      BufferedImage image = new BufferedImage(width, height, 
          BufferedImage.TYPE_INT_RGB);
      Graphics2D g2d = image.createGraphics();
      g2d.setBackground(new Color(255, 255, 255));
      g2d.setPaint(new Color(0, 0, 0));
      g2d.clearRect(0, 0, width, height);
      g2d.dispose();
      baos = new ByteArrayOutputStream();
      ImageIO.write(image, "png", baos);
      sb = new StringBuffer("data:image/png;base64,");
      sb.append(Base64.encodeToString(baos.toByteArray()));
    } catch (Exception ex) {
      ex.printStackTrace();
    } finally {
      if (baos != null) {
        try {
          baos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    // System.out.println(sb.toString());
    return sb.toString();
  }

  public static void main(String[] args) {
    new TestImage().getImageBase64();
  }
}

>优化一下:

我们可以直接保存图片base64字符串,它本身就代表图片,无需每次生成,生成字符串如下:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4//8/AAX+Av4zEpUUAAAAAElFTkSuQmCC

我们在浏览器预览一下,效果如下:

这样我们利用image元素,成功跟踪到用户已读邮件的状态了。

 

注:由于现在QQ、网易等web收件箱限制访问各自服务器上的图片地址,故通过web页面访问时无法正常加载该图。该问题目前无法通过技术规避解决。

 (完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值