文件下载、JavaMail

下载:
1、下载就是向客户端响应字节数据
    原来我们响应的都是html的字符数据
    把一个文件变成字节数组,使用response.getOutputStream()来响应给浏览器

2、下载的要求
    两个头一个流  
        Content-Type:传递给客户端的文件是什么MIME类型,例如:image/pjpeg
            通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型
        Content-Disposition:它的默认值是inline,表示在浏览器窗口中打开。attachment;filename=xxx    
            在filename=后面跟随的是显示在下载框中的文件名称
        流:要下载的文件数据
            自己new一个输入流即可

下载的细节
1、显示在下载框中的中文名称时,会出现乱码
    FireFox:Base64编码。   
    其他大部分浏览器:URL编码  

    通用方案:filename = new String(filename.getBytes("GBK"),"ISO-8859-1")

 



public class DownloadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        /*
         * 两个头一个流 1、Content-Type 2、Content-Disposition 3、流:下载文件的数据
         */
        String filename = "D:/歌曲.mp3";
        // 为了使下载框中显示中文名称不出乱码
        String framename = new String("歌曲.mp3".getBytes("GBK"), "ISO-8859-1");
        // String framename = filenameEncoding("歌曲.mp3",request);
        String contentType = this.getServletContext().getMimeType(filename);// 通过文件名称获取MIME类型
        System.out.println(framename);
        String contentDisposition = "attachment;filename=" + framename;
        // 一个流
        FileInputStream input = new FileInputStream(filename);

        // 设置头
        response.setHeader("Content-Type", contentType);
        response.setHeader("Content-Disposition", contentDisposition);

        // 获取绑定了响应端的流
        ServletOutputStream output = response.getOutputStream();

        IOUtils.copy(input, output);// 把输入流中的数据写入到输出流中
        input.close();
    }

    public static String filenameEncoding(String filename,
            HttpServletRequest request) throws IOException {
        String agent = request.getHeader("User-Agent");// 获取浏览器
        if (agent.contains("FireFox") || agent.contains("Mozilla")) {
            BASE64Encoder base64Encoder = new BASE64Encoder();
            // 用把字符串变成Base64编码 和URL编码很像 通过utf-8变成字符数组
            filename = "=?UTF-8?B?"
                    + base64Encoder.encode(filename.getBytes("UTF-8")) + "?=";
        } else if (agent.contains("MSIE")) {
            filename = URLEncoder.encode(filename, "utf-8");
        } else {
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

}

JavaMail
是java提供的一组API,用来发送      

收发邮件
    发邮件是从客户端把邮件发送到邮件服务器,收邮件是把邮件服务器的邮件下载到客户端

邮件协议概述
    与HTPP协议相同,收发邮件也需要传输协议
        SMTP(Simple Mail Transfer Protocol,简单邮件传输协议) 发邮件协议
        POP3(Post Office Protocol Version 3,邮局协议第3版) 收邮件协议
        IMAP(Internet Message Access Protocol,因特网消息访问协议)收发邮件协议  
SMTP服务器的端口为25服务器名称为smtp.xxx.xxx
pop3服务器的端口号为110,服务器名称为pop3.xxx.xxx

163: smtp.163.com 和pop3.163.com
1、与服务器打招呼:ehlo 你的名字
2、发出登录请求 auth login
3、输入加密后的邮箱名 【邮箱@163.com】bGFsYWxAMTYzLmNvbQ==
4、输入加密后的邮箱密码
5、输入谁来发送邮件 mail from:<邮箱@163.com>
6、输入把邮件发给谁即 rcpt to:<***@163.com>
7、发送填写数据请求:data
8、开始输入数据,数据包含:from、to、subject以及邮件内容,如果输入结束后,以一个"."为一行表示结束
9、最后:quit

telnet收邮件
pop3无需使用Base64加密
收邮件连接的服务器是pop3.xxx.xxx默认端口是110
    连接Pop3服务器:telnet pop3.xxx.com 110
    user 命令:user 用户名 
    pass命令 pass 密码
    stat命令:用来查看邮箱中邮件的个数,所占的空间
    list:用来查看所有邮件,或指定邮件的状态。list 1是查看第一封邮件的大小。list是查看邮件列表
    retr:查看指定邮件的内容 retr 1#
    dele:标记某邮件删除。不是马上,在退出后删除
    quit:退出

JavaMail
使用MyEclipse创建web项目时。如果只在web项目运行javamail没事 发布到Tomcat也没事
但是如果在web项目写测试就出现问题
Myeclipse会自动给web项目导入javax.mail包中的类,但是不全(只有接口,没有接口实现类)如果导入mail.jar会出现冲突
    在D:\myeclipse\plugins\com.genuitec.eclipse.j2eedt.core_13.0.0.me201605020208\data\libraryset\EE_5 中的javaee.jar文件删除javax.mail

1、导包
    mail.jar
    actvition.jar

核心类
1、Session
    如果得到,就代表和服务器连接了,与Connection作用相似
    得到Session。需要使用Session.getInstance(Properties,Authenticator);
    Properties props = new Properties();
    props.setProperty("mail.host","smtp.163.com");
    props.setProperty("mail.stmp.auth","true");

    Authenticator auth = new Authenticator(){
            protected PaswordAuthentication getPasswordAuthentication(){
                return new PasswordAuthentication("root","root");
            }
    };
    Session session = Session.getInstance(props,auth);
2、MimeMessage
    表示一个邮件对象,可以调用它的setFrom();设置发件人、收件人、主题、正文
3、TransPost
    只有一个功能,发邮件          

在使用telnet发邮件时,需要处理Base64编码的问题,但使用JavaMail不必处理。由JavaMail来处理
第一步:获得session
    Session session = Session.getInstance(Properties prop,Authenticator auth)
    其中prop需要指定两个键值,一个是指定服务器主机名,另一个是指定是否需要认证。我们需要认证
    Properties prop = new Properties();
    prop.setProperty("mail.host","smtp.163.com");//设置服务器主机名
    prop.setProperty("mail.smtp.auth","true");//设置需要认证

    其中Authenticator是一个接口表示认证器,即校验客户端的身份,需要自己去实现。实现这个接口需要账户和密码
        Authenticator auth = new Authenticator(){
            public PasswordAuthentication getPasswordAuthentication(){
                new PasswordAuthentication("root","root");//用户名和密码
            }
        }       

    通过上面的就可以获取Session对象了
        Session session = Session.getInstance(prop,auth);   

第二步:创建MimeMessage对象
    创建MimeMessage需要使用Session对象来创建
        MinmeMessage msg = new MimeMessage(session

public class Demo {
    // @Test
    public void fun() throws AddressException, MessagingException {
        /*
         * 1.得到session
         */
        Properties prop = new Properties();
        prop.setProperty("mail.host", "smtp.163.com");
        prop.setProperty("mail.smtp.auth", "true");

        Authenticator auth = new Authenticator() {

            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("***@163.com",
                        "*密码*");
            }

        };
        Session session = Session.getInstance(prop, auth);
        /*
         * 2.创建MimeMessage
         */
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress("***@163.com"));// 设置发件人
        message.setRecipients(RecipientType.TO, "***@qq.com");// 设置收件人
        message.setRecipients(RecipientType.CC, "***@qq.com");// 设置抄送
        message.setRecipients(RecipientType.BCC, "***@qq.com");// 设置暗送

        message.setSubject("Javamail 测试");
        message.setContent("javamail 测试邮件", "text/html;charset=utf-8");
        /*
         * 3.发送
         */
        Transport.send(message);
    }

    /**
     * 带有附件的邮件
     * 
     * @throws MessagingException
     * @throws IOException
     */
    @Test
    public void fun2() throws MessagingException, IOException {
        /*
         * 1、得到session
         */
        Properties props = new Properties();
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");

        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {

                return new PasswordAuthentication("***@163.com",
                        "*密码*");
            }
        };

        Session session = Session.getInstance(props, auth);
        /*
         * 2、创建MimeMessage
         */
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("***@163.com"));// 设置发件人
        msg.setRecipients(RecipientType.TO, "***@qq.com");// 设置收件人

        msg.setSubject("看看附件是啥");
        /*
         * 当发送包含附件的邮件时,邮件体就为多部件形式 1、创建一个多部件的部件内容。MimeMultipart
         * MimeMultipart就是一个集合,用来装载多个主体部件 2、需要创建两个主体部件,一个是文本内容的,一个是附件的
         * 主体部件也叫MimeBodyPart 3、把MimeMultipart设置给MimeMessage的内容
         */
        MimeMultipart list = new MimeMultipart();// 创建多部分主体
        // 创建MimeBodyPart
        MimeBodyPart part1 = new MimeBodyPart();
        // 设置主体部件的内容
        part1.setContent("这是一封包含附件的邮件", "text/html;charset=utf-8");
        // 把主体部件添加到集合中
        list.addBodyPart(part1);
        // 创建MimeBodyPart
        MimeBodyPart part2 = new MimeBodyPart();
        part2.attachFile(new File("D:/歌曲.mp3"));
        part2.setFileName(MimeUtility.encodeText("歌曲.mp3"));// 设置显示的文件名称,其中encodeText用来处理乱码问题
        list.addBodyPart(part2);
        msg.setContent(list);// 设置给邮件作为邮件的内容
        /*
         * 3、发
         */
        Transport.send(msg);
    }

}

注:

javaMail使用网易163邮箱、126或者是网易其他邮箱报535 Error: authentication failed

如果你是163或者126邮箱或者是其他的网易企业邮再或者是网易个人vip邮箱,请你检查一下你网页端邮箱设置中SMTP是否开启,如果开启的话,在程序代码中登录的密码是之前设置的授权码!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值