Http
HTTP
Https
Http请求
请求行
- 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT..
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
- post:请求能够携带的参数没有限制,大小有限制,会在浏览器的URL地址栏显示数据内容,安全,但高效
请求头
Accept: 告诉浏览器,它所支持的数据类型 Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 Is08859-1 Accept-Language: 告诉浏览器,它的语言环境 Cache-Contro1: 缓存控制 Connection: 告诉浏览器,请求完成是断开还是保持连接
|
Http响应
响应体
Accept: 告诉浏览器,它所支持的数据类型 Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 Is08859-1 Accept-Language: 告诉浏览器,它的语言环境 Cache-Control: 缓存控制 Connection: 告诉浏览器,请求完成是断开还是保持连接 HoST: 主机..../. Refresh: 告诉客户端,多久刷新一次: Location: 让网页重新定位;
|
响应状态码
- 200:成功
- 3**:请求重定向(跳转指定位置)
- 4**:找不到资源 / 资源不存在 (404)
- 5**:服务器代码错误 (500)(502:网关错误)
响应编码格式
resp.setContentType("text/html;charset=utf-8");
|
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> </web-app>
|
设置首页
<welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>
|
错误页
<error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/404.jsp</location> </error-page>
<servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
|
servlet
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.chen.servlet.HelloServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
|
session
<session-config> <session-timeout>15</session-timeout> </session-config>
|
Filter
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.chen.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
|
Listener
<listener> <listener-class>com.chen.listener.OnlineCountListener</listener-class> </listener>
|
依赖
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency>
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency>
<dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies>
|
Servlet
简介
原理

HelloServlet
1.实现Servlet接口,这里直接继承HttpServlet
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter();
writer.println("HelloServlet"); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
|
2.编写 Servlet 映射(web.xml)
为什么需要映射:写的是AVA程序,但是要通过刘览器访问,而浏览器需要连接Wb服务器,所以需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.chen.servlet.HelloServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
|
3.配置Tomcat
Mapping
1.一个Servle可以指定一个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
|
2.一个Servlet可以指定多个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hellohello</url-pattern> </servlet-mapping>
|
3.一个Servleti可以指定通用映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
|
4.默认请求路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
|
5.指定一些后缀或者前缀等等.…
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>任意字符.chen</url-pattern> </servlet-mapping>
|
6、指定错误界面
<error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/404.jsp</location> </error-page>
<servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
|
优先级
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
<servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
|
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用:
ServletContext context = this.getServletContext();
|
1、共享数据
- 在这个Servlet中保存的数据,可以在另外一个servlet中拿到

context.setAttribute("username",name);
|
String username = (String) context.getAttribute("username");
|
2、获取初始化参数
String url = context.getInitParameter("url");
|
3、请求转发
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/getc");
requestDispatcher.forward(req,resp);
req.getRequestDispatcher("success.jsp").forward(req,resp);
|
4、读取资源文件
HttpServletResponse
如果要获取客户端请求过来的参数:找HttpServletRequest
如果要给客户端响应一些信息:找HttpServletResponse
1、分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
|
负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
|
响应状态码
int SC_OK = 200;
int SC_FOUND = 302;
int SC_NOT_FOUND = 404;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;
|
2、向浏览器输出消息
public class test extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println(username+":"+password); resp.getWriter().write(username+":"+password); } }
|
3、验证码功能
前端实现
后端实现:需要用到Java的图片类,生成一个图片
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("refresh","5"); BufferedImage bufferedImage = new BufferedImage(80,20, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = (Graphics2D)bufferedImage.getGraphics(); graphics.setColor(Color.WHITE); graphics.fillRect(0,0,80,20); graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.BOLD,20)); graphics.drawString(makeNum(),0,20); resp.setContentType("image/jpeg"); resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); ImageIO.write(bufferedImage, "jpg",resp.getOutputStream()); }
private String makeNum(){ Random random = new Random(); String num = random.nextInt(9999999) + ""; StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 7-num.length(); i++) { stringBuffer.append("0"); } String s = stringBuffer.toString() + num; return s; }
|
5、实现重定向
resp.sendRedirect("/responsep_war/redtext");
|
- 面试题:请你聊聊重定向和转发的区别?
相同点
- 页面都会实现跳转
不同点
- 请求转发的时候,url不会产生变化
- 重定向时候,url地址栏会发生变化;
HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
1、请求转发
req.getRequestDispatcher("success.jsp").forward(req,resp);
|
2、获取前端传递数据【*】
- 获取请求中的数据
- 单个:getParameter(“前端命名name”)
req.getParameter("username");
|
- 多个:getParameterValues(“前端命名name”)
String[] hobbys = req.getParameterValues("hobbys"); System.out.println(Arrays.toString(hobbys));
|
Session、Cookie
Cookie

请求获取与响应
1.从请求中拿到cookie信息
2.服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();
Cookie cookie = cookies[i];
cookie.getName().equals("匹配的name")
cookie.getValue()
Cookie cookie = new Cookie("名称name", 值);
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
|
删除Cookie
不设置有效期,关闭浏览器,自动失效:
设置有效期时间为0
编码解码
- cookie中value的值为中文的时候需要编码和解码
- 编码:URLEncoder.encode(“值”,”utf-8”));
- 解码:
Cookie cookie = new Cookie("lastLoginTime", URLEncoder.encode("值","utf-8"));
(URLDecoder.decode(cookie.getValue(),"UTF-8")
|
Cookie和Session的区别
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session:把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- Session对象由服务创建;
Session【*】
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以信息或者数据放在Session中!

使用场景:
获得session
HttpSession session = req.getSession();
|
存入数据
session.setAttribute("name","辰呀");
|
获取ID及判新
String sessionId = session.getId();
if (session.isNew()) { resp.getWriter().write("sessiom创建成功:ID: "+sessionId); }else{ resp.getWriter().write("session以及在服务器中存在了,ID:"+sessionId); }
|
读取数据
String name =(String) session.getAttribute("name");
|
清除数据
session.removeAttribute("name");
|
注销Session
会话自动过期
<session-config> <session-timeout>15</session-timeout> </session-config>
|
MVC三层架构
MVC:Model(模型)、 view(视图) 、Controller(控制器)

Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View
- 展示数据
- 提供链接发起Servlet请求(a,form,img.…)
Conroller(Servlet)
- 接收用户的请求:(req:请求参数、Session信息.…)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录-->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库
|
过滤器【*】
Filter:过滤器,用来过滤网站的数据;
1、导包
import导包需要导的是 import javax.servlet.;
2、编写过滤器
public class CharacterEncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter已经初始化"); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("setCharacterEncoding执行前..."); filterChain.doFilter(servletRequest,servletResponse); System.out.println("setCharacterEncoding执行后..."); }
public void destroy() { System.out.println("CharacterEncodingFilter已经销毁"); } }
|
3、注册Filer
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.chen.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
|
登录检测
用户登录之后才能进入主页!用户注销后就不能进入主页了!
1、用户登录之后,向Sesison中放入用户的数据
public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); if (username.equals("admin")){ HttpSession session = req.getSession(); session.setAttribute("USER_SESSION",req.getSession().getId()); resp.sendRedirect("/Filer_01_war_exploded/sys/success.jsp"); }else { resp.sendRedirect("/Filer_01_war_exploded/error.jsp"); } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
|
2、进入主页的时候要判断用户是否已经登录:【过滤器实现】
public class SysFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse;
if (req.getSession().getAttribute("USER_SESSION")==null){ resp.sendRedirect("/Filer_01_war_exploded/error.jsp"); } filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() {} }
|
3、注册过滤位置
<filter> <filter-name>SysFilter</filter-name> <filter-class>com.chen.filter.SysFilter</filter-class> </filter> <filter-mapping> <filter-name>SysFilter</filter-name> <url-pattern>/sys/*</url-pattern> </filter-mapping>
|
监听器
1、实现要监听对象的接口
public class OnlineCountListener implements HttpSessionListener {
@Override public void sessionCreated(HttpSessionEvent se) { ServletContext servletContext = se.getSession().getServletContext(); System.out.println(se.getSession().getId()); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); if (onlineCount==null) { onlineCount=new Integer(2); } else { int count = onlineCount.intValue(); onlineCount=new Integer(count+1); } servletContext.setAttribute("onlineCount",onlineCount); }
@Override public void sessionDestroyed(HttpSessionEvent se) { ServletContext servletContext = se.getSession().getServletContext(); se.getSession().invalidate(); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); if (onlineCount==null) { onlineCount=new Integer(1); } else { int count = onlineCount.intValue(); onlineCount=new Integer(count-1); } servletContext.setAttribute("onlineCount",onlineCount); } }
|
2、注册监听器
<listener> <listener-class>com.chen.listener.OnlineCountListener</listener-class> </listener>
|
3、JSP
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("onlineCount")%>在线</span></h1>
|
GUI中的常见用法
public class TestPanel { public static void main(String[]args){ Frame frame=new Frame("中秋节快乐"); Panel panel=new Panel(null); frame.setLayout(null); frame.setBounds(300,300,300,500); frame.setBackground(new Color(6,0,255)); panel.setBounds(50,50,300,300); panel.setBackground(new Color(6,255,0)); frame.add(panel); frame.setVisible(true);
frame.addWindowListener(new WindowListener() { public void windowOpened(WindowEvent e) { System.out.println("打开"); }
public void windowClosing(WindowEvent e) { System.out.println("关闭ing"); System.exit(0); }
public void windowClosed(WindowEvent e) { System.out.println("关闭ed"); }
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) { }
public void windowActivated(WindowEvent e) { System.out.println("激活"); }
public void windowDeactivated(WindowEvent e) { System.out.println("未激活"); } }); } }
|
SMBMS案例
SMBMS项目
文件传输
1、提供下载
1.要获取下载文件的路径
String realPath = "D:\\1.JavaRoute\\JavaWeb\\JavaWeb\\responsep\\target\\classes\\JavaWeb.md";
|
2.下载的文件名是啥?
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
|
3.设置想办法让浏览器能够支持下载我们需要的东西
resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
|
4.获取下载文件的输入流
FileInputStream fileInputStream = new FileInputStream(realPath);
|
5.创建缓冲区
int len= 0 ; byte[] buffer = new byte[1024];
|
6.获取OutputStream对象
ServletOutputStream outputStream = resp.getOutputStream();
|
7.将FileOutputStream流写入到ouffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
while (fileInputStream.read(buffer)>0){ outputStream.write(buffer,0,len); }
fileInputStream.close(); outputStream.close(); }
|
2、文件上传
依赖
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
|
前端
- 表单需要增加属性 enctype=”multipart/form-data”
<form action=" " enctype="multipart/form-data" method="post">
<input type="file" name="file1">
<p><input type="submit"> || <input type="reset"></p>
</form>
|
后端代码编写
ServletFileUpload类
ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个Fileltem对象中.使用其parseRequest(HttpServletRequest)方法可以将通过表单中每一个HTML标签提交的数据封装成一个Fileltem对象,然后以List列表的形式返回。使用该方法处理上传文件简单易用。
public class FileServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (!ServletFileUpload.isMultipartContent(req)) { return; }
String uploadPath = this.getServletContext().getRealPath("WEB-INF/upload"); File uploadFile = new File(uploadPath); if (!uploadFile.exists()) { uploadFile.mkdir(); }
String tmpPath = this.getServletContext().getRealPath("WEB-INF/tmp"); File file = new File(tmpPath); if (!file.exists()) { file.mkdir(); }
try { DiskFileItemFactory factory = getDiskFileItemFactory(file);
ServletFileUpload upload = getServletFileUpload(factory);
String msg = uploadParseRequest(upload, req, uploadPath);
req.setAttribute("msg", msg); req.getRequestDispatcher("info.jsp").forward(req, resp);
} catch (FileUploadException e) { e.printStackTrace(); }
}
public static DiskFileItemFactory getDiskFileItemFactory(File file) { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024 * 1024); factory.setRepository(file); return factory; }
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) { ServletFileUpload upload = new ServletFileUpload(factory); upload.setProgressListener(new ProgressListener() { @Override public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead); } }); upload.setHeaderEncoding("UTF-8"); upload.setFileSizeMax(1024 * 1024 * 10); upload.setSizeMax(1024 * 1024 * 10); return upload;
}
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath) throws IOException, FileUploadException {
String msg = ""; List<FileItem> fileItems = upload.parseRequest(request); for (FileItem fileItem : fileItems) { if (fileItem.isFormField()) { String name = fileItem.getFieldName(); String value = fileItem.getString("UTF-8"); System.out.println(name + ":" + value); } else { String uploadFileName = fileItem.getName(); System.out.println("上传的文件名:" + uploadFileName); if (uploadFileName.trim().equals("") || uploadFileName == null) { continue; } String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1); String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
System.out.println("文件信息[件名:" + fileName + "---文件类型" + fileExtName + "]");
String uuidPath = UUID.randomUUID().toString();
String realPath = uploadPath + "/" + uuidPath; File realPathFile = new File(realPath); if (!realPathFile.exists()) { realPathFile.mkdir(); }
InputStream inputStream = fileItem.getInputStream();
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
byte[] buffer = new byte[1024 * 1024];
int len = 0; while ((len = inputStream.read(buffer)) > 0) { fos.write(buffer, 0, len); } fos.close(); inputStream.close();
msg = "文件上传成功"; fileItem.delete(); } } return msg;
} }
|
邮件发送

依赖
<dependencies> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> </dependencies>
|
1、简单文本邮件
邮件验证码(开线程实现)
//用户注册成功之后,给用户发送一封娜件
//我们使用线程米专门发送娜件,防止出现耗时,和网站注册人数过多的情况:
Sendmail send new Sendmail(user);
//启动线程,线程启动之后就会执行run方法来发送娜件
send.start();
public class MailTest01 { public static void main(String[] args) throws MessagingException, GeneralSecurityException { Properties prop = new Properties(); prop.setProperty("mai1.host","smtp.qq.com"); prop.setProperty("mail.transport.protocol","smtp"); prop.setProperty("mail.smtp,auth","true");
MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf);
Session session = Session.getDefaultInstance(prop,new Authenticator(){ public PasswordAuthentication getpasswordAuthentication() { return new PasswordAuthentication("1107383160@qq.com", "授权码"); } });
Transport ts = session.getTransport();
ts.connect("smtp.qq.com","1107383160@qq.com","授权码");
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("1107383160@qq.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("2931303919@qq.com"));
message.setSubject("黄芪,text");
message.setContent("你好啊!","text/html;charset=UTF-8");
ts.sendMessage(message,message.getAllRecipients());
ts.close();
} }
|
2、带图片邮件
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("D:\\1.JavaRoute\\JavaWeb\\JavaWeb\\Email\\web\\img\\ikun.png")); image.setDataHandler(dh); image.setContentID("bz.jpg");
MimeBodyPart text = new MimeBodyPart(); text.setContent("这是一封邮件正文带图片的邮件<img src='cid:bz.jpg'>","text/html;charset=UTF-8");
MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text); mm.addBodyPart(image); mm.setSubType("related");
message.setContent(mm); message.saveChanges();
|