整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Web時代-Servlet

          ervlet

          今天文章較長,因為包含了幾個案例,請耐心看。

          Java Servlet 是運行在 Web 服務器或應用服務器上的程序,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 服務器上的數據庫或應用程序之間的中間層。

          使用 Servlet,您可以收集來自網頁表單的用戶輸入,呈現來自數據庫或者其他源的記錄,還可以動態創建網頁。

          Java Servlet 通常情況下與使用 CGI(Common Gateway Interface,公共網關接口)實現的程序可以達到異曲同工的效果。但是相比于 CGI,Servlet 有以下幾點優勢:

          • 性能明顯更好。
          • Servlet 在 Web 服務器的地址在空間內執行。這樣它就沒有必要再創建一個單獨的進程來處理每個客戶端請求。
          • Servlet 是獨立于平臺的,因為它們是用 Java 編寫的。
          • 服務器上的 Java 安全管理器執行了一系列限制,以保護服務器計算機上的資源。因此,Servlet 是可信的。
          • Java 類庫的全部功能對 Servlet 來說都是可用的。它可以通過 sockets 和 RMI 機制與 applets、數據庫或其他軟件進行交互。

          Servlet生命周期

          Servlet 生命周期可被定義為從創建直到毀滅的整個過程。以下是 Servlet 遵循的過程:

          • Servlet 初始化后調用 init () 方法。
          • Servlet 調用 service() 方法來處理客戶端的請求。
          • Servlet 銷毀前調用 destroy() 方法。
          • 最后,Servlet 是由 JVM 的垃圾回收器進行垃圾回收的。

          現在讓我們詳細討論生命周期的方法。

          Servlet調用過程

          Servlet的調

          源于視頻

          Servlet過濾器與監聽器

          Servlet 過濾器可以動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。

          可以將一個或多個 Servlet 過濾器附加到一個 Servlet 或一組 Servlet。Servlet 過濾器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 頁面。調用 Servlet 前調用所有附加的 Servlet 過濾器。

          Servlet 過濾器是可用于 Servlet 編程的 Java 類,可以實現以下目的:

          • 在客戶端的請求訪問后端資源之前,攔截這些請求。
          • 在服務器的響應發送回客戶端之前,處理這些響應。

          例如:統一字符編碼,字符的壓縮,加密,實施安全控制等;

          與過濾器有關的有三個包:Filter FilterChain和FilterConfig;

          Filter:所有過濾器都必須實現這個接口;
                  生命周期:web應用加載后立即創建這個web應用的所有過濾器,創建后是駐留在內存中init();過濾器初始化,容器會創建實例后調用這個方法
          FilterConfig:代表web.xml中對filter的配置信息
                  獲取servletContext對象
                  獲取初始信息  
          FilterChain:doFilter();用于調用過濾器鏈中的下一個過濾器,如果是最后一個則將請求提交給處理程序或響應到客戶端上;filterChain代表一個連對象,一個資源可以用多個過濾器進行攔截,攔截順序和filtermapping的順序決定鏈的最后一各節點就是訪問的資源;
          FilterConfig:用于過濾器初始化階段提供過濾器的名字,初始化參數,servlet上下文的信息;
              String getFilterName();返回web.xml文件定義的名稱
              ServletContext getServletContext()方法,返回調用者所處的Servlet的上下文
              String getInitParameter(String name):返回配置過濾器名是name的初始值;‘
              Enumeration getgetInitParameterNames()以Enumeration形式返回過濾器所有初始化參數的名稱
          出現servlet3.0后在eclipes中就不需要配置web.xml了
          如何進行創建出filter中的參數,寫在web.xml中是不能實現的:
          范式:創建filter過濾器,然后在其中的參數列表中選擇是否創建參數,然后在改下對應的url-parttern參數
          讓他對應你的jsp文件就可以解決這個問題;
          @WebFilter(
              urlPatterns = { "/jsp/index.jsp" }, 
              initParams = { 
                      @WebInitParam(name = "count", value = "5000")
              })
              用filterConfig來獲取屬性的值是多少
              filterConfig.getInitParameter(String name);
          @WebFilter(asyncSupported = true, description = "filterdemo", urlPatterns = { "/*" })
          在myeclipse中就必須在web.xml逐一配置出來
          有:
              <filter>
                  <filter-name>Filter1</filter-name>
                    <filter-class>cn.itcast.filter.Filter1</filter-class>
              </filter>   
              <!-- 配置過濾器去攔截哪個資源 -->
              <filter-mapping>
                    <filter-name>Filter1</filter-name>
                    <url-pattern>/hello.jsp</url-pattern>
                  <dispatcher>REQUEST</dispatcher>--用來配置以哪種方式對資源的訪問(request/forward/include/error)
              可以配置多個dispatcher如果不配置默認為request請求
              </filter-mapping>   
          
          @WebFilter(asyncSupported = true, description = "filterdemo", urlPatterns = { "/demo1Filr" })
          public class Demo1Filter implements Filter {
              /**
               * Default constructor. 
               */
              public Demo1Filter() {
                  // TODO Auto-generated constructor stub
              }
              /**
               * @see Filter#destroy()
               */
              public void destroy() {
                  // TODO Auto-generated method stub
              System.out.println("filter銷毀了");
              }
              /**
               * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
               */
              public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                  // TODO Auto-generated method stub
                  // place your code here
                  System.out.println("demo1前");
                  // pass the request along the filter chain
                  //意思是執行下一個節點可以為過濾器可以為資源
                  chain.doFilter(request, response);
                  System.out.println("demo1后");
              }
              /**
               * @see Filter#init(FilterConfig)
               */
              public void init(FilterConfig fConfig) throws ServletException {
                  // TODO Auto-generated method stub
              System.out.println("filter創建了");
              }
          }
          

          Servlert經典實例

          文件上傳

          
          /**
           * Servlet implementation class UploaddisckServlet
           */
          @WebServlet("/UploaddisckServlet")
          @MultipartConfig
          public class UploaddisckServlet extends HttpServlet {
              private static final long serialVersionUID = 1L;
              /**
               * @see HttpServlet#HttpServlet()
               */
              public UploaddisckServlet() {
                  super();
                  // TODO Auto-generated constructor stub
              }
              /**
               * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
               */
              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  // TODO Auto-generated method stub
                  //1.上傳文件
                  String upload=this.getServletContext().getRealPath("WEB-INF/upload");
                  String temp=this.getServletContext().getRealPath("WEB_INF/temp");
                  //創建工廠設置緩沖大小和穿就緩沖區路徑
                  DiskFileItemFactory factory=new DiskFileItemFactory();
                  factory.setSizeThreshold(1024*100);
                  factory.setRepository(new File(temp));
                  //2.生產文件上傳核心類
                  ServletFileUpload fileUpload=new ServletFileUpload(factory);
                  //設置編碼
                  fileUpload.setHeaderEncoding("UTF-8");
                  //設置文件大小的上傳限制
                  fileUpload.setFileSizeMax(1024*1024*10);
                  fileUpload.setSizeMax(1024*1024*100);
                  //檢查當前是項目是否為上傳文件
                  //if (fileUpload.isMultipartContent(request)) {
                      //throw new RuntimeException("請用正確的表單上傳");
                  //}
                  //解析request
                  //3.利用文件上傳核心類來解析request
                  try {
                      List<FileItem> list=fileUpload.parseRequest(request);
                      Map<String,String> map=new HashMap<>();
                      //循環遍歷
                      for(FileItem item :list){
                          if (item.isFormField()) {
                              //普通的字段獲得的是一個表單
                              String name=item.getFieldName();
                              String value=item.getString("utf-8");
                              map.put(name, value);
                              System.out.println(name+":"+value);
                          }else{
                              //當前一個文件上傳項
                              String filename=item.getName();//文件名
                              //設置一個獨一無二的文件名
                              String uuidfilename=UUID.randomUUID().toString()+"_"+filename;
                              map.put("realname", filename);
                              map.put("uuidname",uuidfilename);
                              map.put("ip", request.getRemoteAddr());
                              String savepath="/WEB-INF/upload";
                              //轉換為hash值
                              int hash=uuidfilename.hashCode();
                              //轉化為hash字符串
                              String hashstr=Integer.toHexString(hash);
                              char[] hss=hashstr.toCharArray();
                              for(char c:hss){
                                  upload+="/"+c;
                                  savepath+="/"+c;
                              }
                              new File(upload).mkdirs();
                              map.put("savepath", savepath);
                              InputStream inputStream=item.getInputStream();
                              OutputStream outputStream=new FileOutputStream(new File(upload,uuidfilename)); 
                              IOUtils.In2Out(inputStream, outputStream);
                              IOUtils.close(inputStream, outputStream);
                              //刪除臨時文件
                              item.delete();
                          }
                      }
                      //像數據庫中插入
                      Resource resource=new Resource();
                      BeanUtils.populate(resource, map);
                      String sql="insert into netdisk values(null,?,?,?,?,null,?)";
                      QueryRunner runner=new QueryRunner(DaoUtils.getSource());
                      runner.update(sql,resource.getUuidname(),resource.getRealname(),resource.getSavepath(),resource.getIp(),resource.getDescription() );
                      //3.重定向回主頁
                      response.sendRedirect(request.getContextPath()+"/disk/index.jsp");
                  } catch (FileUploadException | IllegalAccessException | InvocationTargetException | SQLException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
              /**
               * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
               */
              protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  // TODO Auto-generated method stub
                  doGet(request, response);
              }
          }
          

          版本二:

          
          /**
           * Servlet implementation class UploadServlet
           */
          @WebServlet(description = "文件上傳", urlPatterns = { "/UploadServlet" })
          public class UploadServlet extends HttpServlet {
              private static final long serialVersionUID = 1L;
              /**
               * @see HttpServlet#HttpSep=rvlet()
               */
              public UploadServlet() {
                  super();
                  // TODO Auto-generated constructor stub
              }
              /**
               * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
               */
              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  // TODO Auto-generated method stub
                  //通過工廠類來實現
                  DiskFileItemFactory factory=new DiskFileItemFactory();
                  //設置緩沖區大小
                  factory.setSizeThreshold(100*1024);
                  //設置臨時文件夾
                  factory.setRepository(new File(this.getServletContext().getRealPath("WEB-INF/temp")));
                  //2.生產文件上傳核心類
                  ServletFileUpload fileUpload=new ServletFileUpload(factory);
                  try {
                  //判斷是否為真正的表單上傳文件
                  //if (fileUpload.isMultipartContent(request)) {
                      //throw new RuntimeException("請用正確的表單上傳");
                  //}
                  //設置文件大小的上傳限制
                  fileUpload.setFileSizeMax(1024*1024*10);
                  fileUpload.setSizeMax(1024*1024*100);
                  //設置編碼
                  fileUpload.setHeaderEncoding("UTF-8");
                  //設置上傳監聽進度條:
                  fileUpload.setProgressListener(new ProgressListener() {
                      //
                      Long beginTime = System.currentTimeMillis();
                      //已經讀了,總共多少 ,讀到第幾個了
                      @Override
                      public void update(long pBytesRead, long pContentLength, int pItems) {
                          // TODO Auto-generated method stub
                          //轉換為kb
                          //double br=pBytesRead*1.0/1024;
                          //double cl=pContentLength*1.0/1024;
                          //為了保留字節用以下方法
                          BigDecimal br = new BigDecimal(pBytesRead).divide(new BigDecimal(1024),2,BigDecimal.ROUND_HALF_UP);
                          BigDecimal cl = new BigDecimal(pContentLength).divide(new BigDecimal(1024),2,BigDecimal.ROUND_HALF_UP);
                          System.out.print("當前讀取的是第"+pItems+"個上傳項,總大小"+cl+"KB,已經讀取"+br+"KB");
                          //剩余字節數
                          BigDecimal ll = cl.subtract(br);
                          System.out.print("剩余"+ll+"KB");
                          //上傳百分比
                          BigDecimal per = br.multiply(new BigDecimal(100)).divide(cl,2,BigDecimal.ROUND_HALF_UP);
                          System.out.print("已經完成"+per+"%");
                          //上傳用時
                          Long nowTime = System.currentTimeMillis();
                          Long useTime = (nowTime - beginTime)/1000;
                          System.out.print("已經用時"+useTime+"秒");
                          //上傳速度
                          BigDecimal speed = new BigDecimal(0);
                          if(useTime!=0){
                              //四舍五入模式向“最近鄰居”轉彎,除非兩個鄰居都是等距的,在這種情況下是圓括弧的。
                              speed = br.divide(new BigDecimal(useTime),2,BigDecimal.ROUND_HALF_UP);
                          }
                          System.out.print("上傳速度為"+speed+"KB/S");
                          //大致剩余時間
                          BigDecimal ltime = new BigDecimal(0);
                          if(!speed.equals(new BigDecimal(0))){
                              //返回一個 BigDecimal ,其值為 (this / divisor) ,其比例為指定。
                              ltime = ll.divide(speed,0,BigDecimal.ROUND_HALF_UP);
                          }
                          System.out.print("大致剩余時間為"+ltime+"秒");
                          System.out.println();
                          }
                  });
                  //3.利用文件上傳核心類來解析request
                      List<FileItem> list=fileUpload.parseRequest(request);
                      //循環遍歷
                      for(FileItem item :list){
                          if (item.isFormField()) {
                              //普通的字段獲得的是一個表單??
                              String name=item.getFieldName();
                              String value=item.getString("utf-8");
                              System.out.println(name+":"+value);
                          }else{
                              //當前一個文件上傳項
                              String filename=item.getName();//文件名
                              //設置一個獨一無二的文件名
                              String uuidfilename=UUID.randomUUID().toString()+"_"+filename;
                              //轉換為hash值
                              int hash=uuidfilename.hashCode();
                              //轉化為hash字符串
                              String hashstr=Integer.toHexString(hash);
                              char[] hss=hashstr.toCharArray();
                              String path=this.getServletContext().getRealPath("upload");
                              for(char c:hss){
                                  path+="/"+c;
                              }
                              new File(path).mkdirs();
                              InputStream inputStream=item.getInputStream();
                              OutputStream outputStream=new FileOutputStream(new File(path,uuidfilename)); 
                              IOUtils.In2Out(inputStream, outputStream);
                              IOUtils.close(inputStream, outputStream);
                              //刪除臨時文件
                              item.delete();
                          }
                      }
                  } catch (FileUploadException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                      throw new RuntimeException();
                  }
              }
              /**
               * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
               */
              protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  // TODO Auto-generated method stub
                  doGet(request, response);
              }
          }
          

          IOUtils

          public class IOUtils {
              private IOUtils() {
              }
              public static void In2Out(InputStream in,OutputStream out) throws IOException{
                  byte [] bs = new byte[1024];
                  int i = 0;
                  while((i=in.read(bs))!=-1){
                      out.write(bs,0,i);
                  }
              }
              public static void close(InputStream in,OutputStream out){
                  if(in!=null){
                      try {
                          in.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }finally{
                          in = null;
                      }
                  }
                  if(out!=null){
                      try {
                          out.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }finally{
                          out = null;
                      }
                  }
              }
          }
          

          自動登錄攔截器

          package com.itheima.filter;
          import java.io.IOException;
          import java.sql.SQLException;
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.annotation.WebFilter;
          import javax.servlet.annotation.WebInitParam;
          import javax.servlet.http.Cookie;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.commons.dbutils.QueryRunner;
          import org.apache.commons.dbutils.handlers.BeanHandler;
          import com.itheima.domain.User;
          import com.itheima.util.DaoUtils;
          /**
           * Servlet Filter implementation class AutologinFilter
           */
          @WebFilter(
                  description = "自動登錄過濾器", 
                  urlPatterns = { "/*" }, 
                  initParams = { 
                          @WebInitParam(name = "encode", value = "utf-8", description = "編碼過濾")
                  })
          public class AutologinFilter implements Filter {
              /**
               * Default constructor. 
               */
              public AutologinFilter() {
                  // TODO Auto-generated constructor stub
              }
              /**
               * @see Filter#destroy()
               */
              public void destroy() {
                  // TODO Auto-generated method stub
              }
              /**
               * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
               */
              public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                  // TODO Auto-generated method stub
                  // place your code here
                  //1.只有未登錄的才能自動登錄
                  HttpServletRequest req=(HttpServletRequest)request;
                  HttpServletResponse rsp=(HttpServletResponse)response;
                  if (req.getSession(false)==null|| req.getSession().getAttribute("user")==null) {
                      //2.只有帶自動登錄的的cookie才能自動登錄
                      Cookie[]cs=req.getCookies();
                      Cookie findC=null;
                      if (cs!=null) {
                          for(Cookie c:cs) {
                              if ("autologin".equals(c.getName())) {
                                  findC=c;
                                  break;
                              }
                          }
                      }
                      if (findC!=null) {
                          //3.自動登錄cookie中保存的用戶名密碼正確才能登錄
                          String name=findC.getValue().split(":")[0];
                          String password=findC.getValue().split(":")[1];
                          User user=null;
                          String sql="select *from user where name=?and password=?";
                          //數據庫的操作
                          try {
                              QueryRunner runner=new QueryRunner(DaoUtils.getSource());
                              user=runner.query(sql,new BeanHandler<User>(User.class),name,password);
                          } catch (SQLException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                          if (user!=null) {
                              req.getSession().setAttribute("user", user);
                          }
                      }
                  }
                  // pass the request along the filter chain
                  chain.doFilter(request, response);
              }
              /**
               * @see Filter#init(FilterConfig)
               */
              public void init(FilterConfig fConfig) throws ServletException {
                  // TODO Auto-generated method stub
              }
          }
          

          全站亂碼過濾器

          package com.itheima.filter;
          import java.io.IOException;
          import java.io.UnsupportedEncodingException;
          import java.util.Map;
          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.annotation.WebFilter;
          import javax.servlet.annotation.WebInitParam;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;
          /**
           * Servlet Filter implementation class EncodingFilter
           */
          @WebFilter(description = "全站亂碼過濾器", urlPatterns = { "/*" },
          initParams = { 
                  @WebInitParam(name ="encode", value = "UTF-8")
          })
          public class EncodingFilter implements Filter {
              private FilterConfig config=null;
              private String encode=null;
              /**
               * Default constructor. 
               */
              public EncodingFilter() {
                  // TODO Auto-generated constructor stub
              }
              /**
               * @see Filter#destroy()
               */
              public void destroy() {
                  // TODO Auto-generated method stub
              }
              /**
               * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
               */
              public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                  // TODO Auto-generated method stub
                  // place your code here
                  //處理get請求的亂碼
                  response.setCharacterEncoding(encode);
                  response.setContentType("text/html;charset="+encode);
                  //處理post請求亂碼
                  //request.setCharacterEncoding(encode);
                  // pass the request along the filter chain
                  chain.doFilter(new MyHttpServletRequest((HttpServletRequest)request), response);
              }
              /**
               * @see Filter#init(FilterConfig)
               */
              public void init(FilterConfig fConfig) throws ServletException {
                  // TODO Auto-generated method stub
                  this.config=fConfig;
                  //獲取參數看參數是哪一個然后把他設置給新的編碼方式
                  encode=config.getInitParameter(encode)==null?"utf-8":config.getInitParameter(encode);
              }
              //裝飾:寫一個類實現被裝飾的一個接口在構造方法傳入被裝飾者,不想改造的方法調用原有的方法,想改造
              //的自己來寫邏輯
          class MyHttpServletRequest extends HttpServletRequestWrapper{
                  private HttpServletRequest request=null;
                  private boolean isNotEncode=true;
                  public MyHttpServletRequest(HttpServletRequest request) {
                      super(request);
                      // TODO Auto-generated constructor stub
                      this.request=request;
                  }
                  @Override
                  public String getParameter(String name) {
                      // TODO Auto-generated method stub
                      return getParameterValues(name)==null?null:getParameterValues(name)[0];
                  }
                  @Override
                  public Map<String, String[]> getParameterMap() {
                      // TODO Auto-generated method stub
                      try {
                          //post提交處理方式
                      if (request.getMethod().equalsIgnoreCase("post")) {
                              request.setCharacterEncoding(encode);
                              return request.getParameterMap();
                          }else if (request.getMethod().equalsIgnoreCase("get")) {
                              //get處理方式
                              Map<String, String[]> map=request.getParameterMap();
                              if (isNotEncode) {
                                  for(Map.Entry<String, String[]> entry:map.entrySet()){
                                      String[] vsString=entry.getValue();
                                      for(int i=0;i<vsString.length;i++){
                                      vsString[i]=new String(vsString[i].getBytes("iso8859-1"),encode);
                                      }
                                  }
                                  isNotEncode=false;
                              }
                              return map;
                          }else{
                              return super.getParameterMap();
                              }
                          } catch (UnsupportedEncodingException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                              throw new RuntimeException();
                          }
                  }
                  @Override
                  public String[] getParameterValues(String name) {
                      // TODO Auto-generated method stub
                      return getParameterMap().get(name);
                  }   
              }
          }
          

          郵件發送

          public class MailUtils {
              //email:郵件發給誰  subject:主題  emailMsg:郵件的內容
              public static void sendMail(String email, String subject, String emailMsg)
                      throws AddressException, MessagingException {
                  // 1.創建一個程序與郵件服務器會話對象 Session
                  Properties props = new Properties();
                  props.setProperty("mail.transport.protocol", "SMTP");//發郵件的協議
                  props.setProperty("mail.host", "localhost");//發送郵件的服務器地址
                  props.setProperty("mail.smtp.auth", "true");// 指定驗證為true
                  // 創建驗證器
                  Authenticator auth = new Authenticator() {
                      public PasswordAuthentication getPasswordAuthentication() {
                          return new PasswordAuthentication("tom", "12345");//發郵件的賬號的驗證
                      }
                  };
                  Session session = Session.getInstance(props, auth);
                  // 2.創建一個Message,它相當于是郵件內容
                  Message message = new MimeMessage(session);
                  message.setFrom(new InternetAddress("leokay555@163.com")); // 設置發送者
                  message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設置發送方式與接收者
                  message.setSubject(subject);//郵件的主題
                  message.setContent(emailMsg, "text/html;charset=utf-8");
                  // 3.創建 Transport用于將郵件發送
                  Transport.send(message);
              }
          }
          
          (1) javax.mail.Properties類   
                    JavaMail需要Properties來創建一個session對象。它將尋找字符串"mail.smtp.host",屬性值就是發送郵件的主機.   
                  用法:   
                      Properties props = new Properties ();  //Properties props = System.getProperties();  
                      props.put("mail.smtp.host", "smtp.163.com");//可以換上你的smtp主機名。   
          (2) javax.mail.Session類   
                    這個Session類代表JavaMail 中的一個郵件session. 每一個基于 JavaMail的應用程序至少有一個session但是可以有任意多的session。 在這個例子中, Session對象需要知道用來處理郵件的SMTP 服務器。   
                  用法:   
                     Session sendMailSession = Session.getInstance(props, null);   //不須認證  
          (3) javax.mail.Transport類   
                    郵件是既可以被發送也可以被受到。JavaMail使用了兩個不同的類來完成這兩個功能:Transport 和Store. Transport 是用來發送信息的,而Store用來收郵件。在這發送郵件我們只需要用到Transport對象。   
                      用法:   
                          Transport  transport = sendMailSession.getTransport("smtp");   
                        用JavaMail Session對象的getTransport 方法來初始化Transport。傳過去的字符串申明了對象所要使用的協議,如"smtp"。這將為我們省了很多時間。因為JavaMail以經內置了很多協議的實現方法。   
                       注意: JavaMail并不是絕對支持每一個協議,目前支持IMAP、 SMTP和 POP3.   
          (4) javax.mail.MimeMessage類   
                Message對象將存儲我們實際發送的電子郵件信息,Message對象被作為一個MimeMessage對象來創建并且需要知道應當選擇哪一個JavaMail session。   
                用法:   
                       Message newMessage = new MimeMessage(sendMailSession);   
          (5) javax.mail.InternetAddress類   
                  一旦您創建了 Session 和 Message,并將內容填入消息后,就可以用Address確定信件地址了。和 Message 一樣,Address 也是個抽象類。您用的是Javax.mail.internet.InternetAddress 類.   
                  用法:   
                      InternetAddress from=new InternetAddress("xxf@cafe.com");   //收件人郵箱地址  
          (6) javax.mail.Store類   
                  Store類實現特定郵件協議上的讀、寫、監視、查找等操作。通過Javax.mail.Store類可以訪問Javax.mail.Folder類。   
                  用法:   
                      Store store=s.getSorte("pop3");  //s為一個郵件會話   
                      store.connect(popserver,username,password);//通過你提供的popserver地址(郵箱服務器),用戶名和密碼登錄你的郵箱    
          (7) javax.mail.Folder類   
                  Folder類用于分級組織郵件,并提供照Javax.mail.Message格式訪問email的能力。   
                      用法:   
                          Folder folder=store.getFolder("INBOX");   
                          folder.open(Folder.READ_ONLY);   
          (8) javax.mail.Internet.MimeMultipart   
                  一般保存電子郵件內容的容器是Multipart抽象類,它定義了增加和刪除及獲得電子郵件不同部分內容的方法.由于Multipart是抽象類,我們必須為它使用一個具體的子類,JavaMail API提供javax.mail.Internet.MimeMultpart類來使用MimeMessage對象.   
                      用法:   
                          MimeMultipart multipart=new MimeMultipart();   
                  注:我們使用MimeMultipart對象的一個方法是addBodyPart(),它在我們的電子郵件內容里添加BodyPart(BodyPart類在下面緊接著要介紹)對象.消息可以有很多部分,一個BodyPart可以代表一個部分.   
          (9) javax.mail.Internet.MimeBodyPart類   
                  MimeBodyPart是BodyPart具體用于mimeMessage的一個子類.   
                  MimeBodyPart對象代表一個MimeMessage對象內容的一部分.每個MimeBodyPart被認為有兩部分:   
                  ⊙一個MIME類型   
                  ⊙匹配這個類型的內容   
                  用法:   
                      MimeBodyPart mdp=new MimeBodyPart();   
                      String text="Hello JavaMail!";   
                  //定義MIME類型為text/plain,并設置MimeBodyPart的內容.   
                      mdp.setContent(text,"text/plain");    
          (10) javax.activation.DataHandler類(包含在JAF中)   
                  JavaMail API不限制信息只為文本,任何形式的信息都可能作繭自縛MimeMessage的一部分.除了文本信息,作為文件附件包含在電子郵件信息的一部分是很普遍的.JavaMail API通過使用DataHandler對象,提供一個允許我們包含非文本BodyPart對象的簡便方法.   
                  用法:   
                      DataHandler dh=new DataHandler(text,type);   
                      mdp.setDatahandler(dh);  //mdp是一個MimeBodyPart對象   
          (11) javax.activation.FileDataSource類(包含在JAF中)   
                  一個FileDataSource對象可以表示本地文件和服務器可以直接訪問的資源.一個本地文件可以通過創建一個新的MimeBodyPart對象附在一個mimeMessage對象上.   
                  用法:   
                      MimeMultipart mm=new MimeMultipart();   
                      MimeBodyPart mdp=new MimeBodyPart();   
                      FileDataSource fds=new FileDataSource("c:/exam.txt");   
                      mdp.setDataHandler(new DataHandler(fds));   //設置數據源   
                      mm.addBodyPart(mdp);  //為當前消息MimeMultipart對象增加MimeBodyPart   
          (12) javax.activation.URLDataSource類(包含在JAF中)   
          遠程資源,URL不會指向它們,由一個URLDataSource對象表示.一個遠程資源可以通過創建一個新mimeBodyPart對象附在一個mimeMessage對象上(同FileDataSource差不多).   
          

          文件下載

          package com.leo.crazy;
          import java.io.InputStream;
          import java.io.RandomAccessFile;
          import java.net.HttpURLConnection;
          import java.net.URL;
          /**
           *下載
           *download()方法負責按如下步驟來實現多線程下載。
          (1)創建URL對象。
          (2)獲取指定URL對象所指向資源的大小(通過getContentLength()方法獲得),此處用到了URLConnection類,該類代表Java應用程序和URL之間的通信鏈接。后面還有關于URLConnection更詳細的介紹。
          (3)在本地磁盤上創建一個與網絡資源具有相同大小的空文件。
          (4)計算每個線程應該下載網絡資源的哪個部分(從哪個字節開始,到哪個字節結束)。
          (5)依次創建、啟動多個線程來下載網絡資源的指定部分。
           * @author leoi555
           *@date 2018年10月20日
           */
          public class DownUtil {
                  // 定義下載資源的路徑
                  private String path;
                  // 指定所下載的文件的保存位置
                  private String targetFile;
                  // 定義需要使用多少個線程下載資源
                  private int threadNum;
                  // 定義下載的線程對象
                  private DownThread[] threads;
                  // 定義下載的文件的總大小
                  private int fileSize;
                  public DownUtil(String path, String targetFile, int threadNum)
                  {
                        this.path=path;
                        this.threadNum=threadNum;
                        // 初始化threads數組
                        threads=new DownThread[threadNum];
                        this.targetFile=targetFile;
                  }
                  public void download() throws Exception
                  {
                        URL url=new URL(path);
                        HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                        conn.setConnectTimeout(5*1000);
                        conn.setRequestMethod("GET");
                        conn.setRequestProperty(
                              "Accept",
                              "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
                              + "application/x-shockwave-flash, application/xaml+xml, "
                              + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
                              + "application/x-ms-application, application/vnd.ms-excel, "
                              + "application/vnd.ms-powerpoint, application/msword, */*");
                        conn.setRequestProperty("Accept-Language", "zh-CN");
                        conn.setRequestProperty("Charset", "UTF-8");
                        conn.setRequestProperty("Connection", "Keep-Alive");
                        // 得到文件大小
                        fileSize=conn.getContentLength();
                        conn.disconnect();
                        int currentPartSize=fileSize / threadNum + 1;
                        RandomAccessFile file=new RandomAccessFile(targetFile, "rw");
                        // 設置本地文件的大小
                        file.setLength(fileSize);
                        file.close();
                        for (int i=0; i < threadNum; i++)
                        {
                              // 計算每個線程下載的開始位置
                              int startPos=i*currentPartSize;
                              // 每個線程使用一個RandomAccessFile進行下載
                              RandomAccessFile currentPart=new RandomAccessFile(targetFile,
                                  "rw");
                              // 定位該線程的下載位置
                              currentPart.seek(startPos);
                              // 創建下載線程
                              threads[i]=new DownThread(startPos, currentPartSize,
                                  currentPart);
                              // 啟動下載線程
                              threads[i].start();
                        }
                  }
                  // 獲取下載的完成百分比
                  public double getCompleteRate()
                  {
                        // 統計多個線程已經下載的總大小
                        int sumSize=0;
                        for (int i=0; i < threadNum; i++)
                        {
                              sumSize +=threads[i].length;
                        }
                        // 返回已經完成的百分比
                        return sumSize*1.0 / fileSize;
                  }
                  private class DownThread extends Thread
                  {
                        // 當前線程的下載位置
                        private int startPos;
                        // 定義當前線程負責下載的文件大小
                        private int currentPartSize;
                        // 當前線程需要下載的文件塊
                        private RandomAccessFile currentPart;
                        // 定義該線程已下載的字節數
                        public int length;
                        public DownThread(int startPos, int currentPartSize,
                              RandomAccessFile currentPart)
                        {
                              this.startPos=startPos;
                              this.currentPartSize=currentPartSize;
                              this.currentPart=currentPart;
                        }
                        public void run()
                        {
                              try
                              {
                                  URL url=new URL(path);
                                  HttpURLConnection conn=(HttpURLConnection)url
                                        .openConnection();
                                  conn.setConnectTimeout(5*1000);
                                  conn.setRequestMethod("GET");
                                  conn.setRequestProperty(
                                        "Accept",
                                        "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
                                        + "application/x-shockwave-flash, application/xaml+xml, "
                                        + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
                                        + "application/x-ms-application, application/vnd.ms-excel, "
                                        + "application/vnd.ms-powerpoint, application/msword, */*");
                                  conn.setRequestProperty("Accept-Language", "zh-CN");
                                  conn.setRequestProperty("Charset", "UTF-8");
                                  InputStream inStream=conn.getInputStream();
                                  // 跳過startPos個字節,表明該線程只下載自己負責的那部分文件
                                  inStream.skip(this.startPos);
                                  byte[] buffer=new byte[1024];
                                  int hasRead=0;
                                  // 讀取網絡數據,并寫入本地文件
                                  while (length < currentPartSize
                                        && (hasRead=inStream.read(buffer)) !=-1)
                                  {
                                        currentPart.write(buffer, 0, hasRead);
                                        // 累計該線程下載的總大小
                                        length +=hasRead;
                                  }
                                  currentPart.close();
                                  inStream.close();
                              }
                              catch (Exception e)
                              {
                                  e.printStackTrace();
                              }
                        }
                  }
          }
          

          ok 今天的回顧就這么多了,我們緊接著看下關于javaweb的一些有關的面試題吧。

          、JavaWeb概念

          Java web,是用java技術來解決相關web互聯網領域的技術的總稱。web包括:web服務器和web客戶端兩部分。

          java在最早web客戶端的應用有java applet程序,不過這種技術在很久之前就已經被淘汰了。java在服務器端的應用非常豐富,

          比如Servlet,jsp和第三方框架等等。java技術對web領域的發展注入了強大的動力

          簡單的說,就是使用java語言實現瀏覽器可以訪問的程序內容。稱之為Java Web。

          javaweb開發是基于請求和響應的:

          請求:瀏覽器(客戶端)向服務器發送信息

          響應:服務器向(客戶端)瀏覽器回送信息

          請求和響應是成對出現的。

          2、web資源分類:

          所謂web資源即放在Internet網上供外界訪問的文件或程序,又根據它們呈現的效果及原理不同,將它們劃分為靜態資源和動態資源。

          靜態web資源:固定不變數據文件(靜態網頁 HTML、CSS文件、文本、音頻、視頻)

          靜態web技術:HTML+CSS+JavaScript

          動態web資源:一段服務程序,運行后,生成的數據文件

          動態web技術:servlet,jsp,php, .net ,ruby、python等等

          3、常見的web服務器

          web服務器簡介:

          Tomcat:由Apache組織提供的一種Web服務器,提供對jsp和Servlet的支持。它是一種輕量級的javaWeb容器(服務器),也是當前應用最廣的JavaWeb服務器(免費)。

          Jboss:是一個遵從JavaEE規范的、開放源代碼的、純Java的EJB服務器,它支持所有的JavaEE規范(免費)。

          GlassFish: 由Oracle公司開發的一款JavaWeb服務器,是一款強健的商業服務器,達到產品級質量(應用很少,收費)。

          Resin:是CAUCHO公司的產品,是一個非常流行的應用服務器,對servlet和JSP提供了良好的支持,性能也比較優良,resin自身采用JAVA語言開發(收費,應用比較多)。

          WebLogic:是Oracle公司的產品,是目前應用最廣泛的Web服務器,支持JavaEE規范,而且不斷的完善以適應新的開發要求,適合大型項目(收費,用的不多,適合大公司)。

          3.1、Tomcat服務器

          開源小型web服務器 ,完全免費,主要用于中小型web項目,只支持Servlet和JSP 等少量javaee規范(就是JavaWeb編程接口)

          3.2、tomcat服務器與servlet版本的關系

          servlet:sun公司提供的用于開發動態web資源的技術。

          jsp:(java server page),java提供的一門開發web網頁的技術。

          tomcat軟件:java開發的。java軟件運行的時候需要jdk。

          向下兼容。tomcat7也支持servlet3.0/jsp2.2規范,可以支持javaee6.0當前企業常用的版本 6.* / 7.*/8.*

          3.3、tomcat下載和安裝說明

          到http://tomcat.apache.org 下載

          1) Tomcat首頁

          2)Tomcat下載

          3)下載后的包

          4)安裝:解壓

          5)tomcat的安裝目錄介紹:

          bin:可以執行文件。

          conf:tomcat服務器的配置文件

          lib:tomcat啟動后需要依賴的jar包

          logs:tomcat工作之后的日志文件

          webapps:是tomcat布暑工程的目錄。

          work:jsp文件在被翻譯之后,保存在當前這個目錄下,session對象被序列化之后保存的位置

          3.4、Tomcat服務器啟動(**重點)

          注意事項:

          1、JAVA_HOME:環境變量。并且配置到jdk的目錄,其完整過程如下:

          打開控制臺(cmd命令打開窗口)。輸入java -version測試

          2、啟動tomcat目錄。 tomcat目錄/bin/startup.bat(window啟動文件) 找到startup.bat 雙擊運行。會有一個黑窗口,黑窗口不要關閉。(如果關閉,相當于把tomcat停止了。)

          3、在瀏覽器地址欄中輸入:http://localhost:8080 或者 http://127.0.0.1:8080localhost ,如果看到如下頁面,證明啟動成功

          3.5、配置tomcat的端口(****重點)

          tomcat默認的端口是8080(訪問端口)

          http的默認端口是80,如果訪問的時候輸入http://www.baidu.com相當于http://www.baidu.com:80。當真正在項目上線之后,通常采用80,修改方法如下:

          1)找到tomcat目錄/conf/server.xml

          2)修改port的值,將port端口的值修改為80

          3)然后在瀏覽器中輸入 http://127.0.0.1:80 或 http://127.0.0.1 訪問測試

          訪問成功!!!

          3.6、catalina run 啟動Tomcat

          Tomcat啟動,還有一種啟動的方法就是在命令行中,先把你的當前目錄切換 到你tomcat目錄\bin目錄下,如下是我的位置

          再執行catalina run 這個命令啟動Tomcat。這個命令有什么好處。當Tomcat啟動失敗的時候,會有一閃而過的情況,

          當我們使用catalina run 這個命令啟動Tomcat的時候,哪怕有錯誤,我們也可以清楚的看到tomcat失敗的原因。不會一閃而過。

          3.7、tomcat關閉

          有三種方法。

          第一種:Ctrl+C鍵 關閉Tomcat服務器

          第二種:點擊Tomcat窗口的右上角關閉按鈕 (暴力停止服務器)

          第三種:找到tomcat目錄/bin/shutdown.bat文件,雙擊執行關閉Tomcat。

          4、常用的布署工程到Tomcat中的兩種方式

          把我們自己書寫的html,servlet這些信息,部署到tomcat的方式。

          4.1、第一種方法:在tomcat目錄/conf/server.xml 配置---了解

          在conf/server.xml文件的host元素中配置,例如:

          在host標簽內書寫如下內容

          <Context path="/atguigu" docBase="D:\atguigu"/>

          <Context path=”瀏覽器要訪問的目錄---虛擬目錄” docBase=”網站所在磁盤目錄”/>

          配置好之后,要重啟服務器。

          缺點(Tomcat7.0之后):如果配置錯誤:tomcat會啟動失敗。(如果tomcat里面存放的其他的網站),其他網站也會停機。

          4.2、第二種方式:將網站目錄復制到tomcat/webapps目錄(常用,必須掌握)

          有一個網站(一個文件夾),把文件夾復制到tomcat的webapps目錄下。

          文件夾的名字,就是網站或者工程的訪問目錄.相當于之前配置 <Context path=”” 的配置

          4.3、把網站目錄壓縮成war包部署到tomcat中

          war包:就是一個壓縮文件 zip格式的壓縮文件。 只不過擴展名不是.zip 而是.war

          把我們的項目進行壓縮zip,改成war,把war文件拷貝到tomcat/webapps目錄下

          步驟1、把文件夾中的內容壓縮成zip的格式,點擊一個要部署的文件夾下面,全選 然后壓縮

          步驟2、修改文件的后綴名為.war

          步驟3.把war文件復制到webapps目錄下。tomcat會自己把war的文件進行解壓

          4.4、webapps目錄下/ROOT工程的訪問

          當我們在瀏覽器中直接輸入http://ip地址:端口號 那么 默認訪問的是Tomcat目錄/webapps/ROOT目錄

          如果webapps下面有一個ROOT的項目。那么在訪問的時候,直接可以省略項目的名字/ 表示找到root目錄

          5、整合Tomcat和Eclipse開發工具中(***常用必須掌握)

          5.1、打開Eclipse的Server視圖窗口

          第一種情況,直接打開Servers窗口

          第二種情況,搜索Servers窗口打開

          圖一,打開總的eclipse視圖

          圖二:輸入Server過濾出服務器窗口選項

          Servers服務器窗口已成功打開,如下圖:

          5.2、創建Tomcat 服務器

          1)在Servers窗口中,點擊 創建 server 的文字提示連接。如下圖:

          2)創建一個新的Tomcat服務器實例

          3)點擊Browse按鈕,打開目錄選擇窗口。選擇Tomcat 解壓目錄

          4)選擇Tomcat目錄,然后點擊確定按鈕

          5)Tomcat目錄選擇好之后,點擊 【Next】按鈕繼續操作

          6)點擊 【Finish】按鈕結束操作

          7)Tomcat 服務器創建成功!!!

          5.3、啟動Eclipse中的Tomcat服務器

          1)Debug模式啟動Tomcat服務器

          提示當前為Debug模式啟動!!!

          Tomcat啟動成功的控制臺提示!!!

          2)Run模式啟動Tomcat服務器

          Run模式啟動顯示

          Tomcat啟動成功的控制臺提示!!!

          5.4、停止 Eclipse 中的Tomcat 服務器

          暴力停止 Tomcat (相當于電腦被拔掉電源一樣。沒有執行關機的準備操作。)

          正常停止 Tomcat (相當于點擊操作系統中的關機按鈕,執行關機保存操作,然后關機)

          5.5、配置Eclipse 中的Tomcat 布暑的Web工程路徑

          1)打開Servers窗口,雙擊Tomcat v6.0 Server 服務器打開 Tomcat的配置窗口

          這里是Eclipse把工程發布后的三種不同的選項。

          2)Tomcat 位置-選項介紹說明:

          2.1、User workspance metadata (does not modify Tomcat installation) 將在eclipse的工作區間目錄下eclipse的工作空間目錄\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\ 有一份tomcat的拷貝所有布暑的web工程都會布暑到eclipse的工作空間目錄\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps目錄中

          2.2、 User Tomcat installation (takes control of Tomcat installation) 在原Tomcat目錄下做更改操作所有布暑的web工程都會發布到Tomcat目錄下的\wtpwebapps目錄中

          2.3、 User custom location ( does not modify Tomcat installtion ) 自定義一個目錄去布暑Web工程

          比如操作如下:

          一:選擇自定義的布暑目錄

          二:選擇你自定義的目錄,然后點擊確定。之后Tomcat的一些目錄會被拷貝過來。布暑的工程也在這個目錄下的wtpwebapps目錄下

          三:選中你要布暑的工程,右鍵選擇菜單 Run As --->>> Run on Server 將工程布暑到剛剛自定義的目錄下。

          四:選擇你當前的web工程需要使用的哪個服務器運行。

          如果勾選中 Always use this server when running this project 表示下次運行服務器的時候默認使用當勾時時候選擇的服務器運行。

          五:等待Tomcat啟動,web工程布暑成功后。查看

          六:在瀏覽器中輸入http://127.0.0.1:8080/day06/index.html 測試查看

          6 HTTP協議介紹

          6.1、 HTTP協議

          1.HTTP(hypertext transport protocol),即超文本傳輸協議。這個協議詳細規定了瀏覽器和萬維網服務器之間互相通信的規則。

          2.客戶端與服務端通信時傳輸的內容我們稱之為報文。

          3.HTTP就是一個通信規則,這個規則規定了客戶端發送給服務器的報文格式,也規定了服務器發送給客戶端的報文格式。實際我們要學習的就是這兩種報文。客戶端發送給服務器的稱為”請求報文“,服務器發送給客戶端的稱為”響應報文“。

          大白話說,什么是協議。是雙方相互約定好的規則;比如:租房協議:租房協議就是租客和房東之間相互約定好的租房規則

          6.2、請求的協議格式

          請求的HTTP協議格式:

          請求行

          請求頭

          空行

          請求體

          GET請求協議格式 (get請求沒有請求體)

          POST請求協議格式

          6.3、常見請求頭的說明

          GET /Hello/index.jsp HTTP/1.1:GET請求,請求服務器資源的路徑 Hello/index.jsp, 協議為http 版本為1.1;

          Host:localhost:請求的主機名為localhost;

          User-Agent: Mozilla/4.0 (compatible; MSIE 8.0…:與瀏覽器和OS相關的信息。有些網站會顯示用戶的系統版本和瀏覽器版本信息,這都是通過獲取User-Agent頭信息而來的;

          Accept: */*:告訴服務器,當前客戶端可以接收的數據類型, */*,就表示什么都可以接收;

          Accept-Language: zh-CN:當前客戶端支持的語言,可以在瀏覽器的工具選項中找到語言相關信息;

          Accept-Encoding: gzip, deflate:支持的壓縮格式。數據在網絡上傳遞時,可能服務器會把數據壓縮后再發送;

          Connection: keep-alive:客戶端支持的鏈接方式,保持一段時間鏈接,默認為3000ms;

          6.4、get請求和post請求都分別是哪些?

          GET請求

          1)、輸入瀏覽器地址欄輸入地址,直接按回車

          2)、點擊<a>超鏈接

          3)、GET請求 表單提交

          4)、script src=””,引入外部文件

          5)、img src=”路徑”,引入圖片

          6)、引入外部css。。。

          POST請求

          1)只有表單提交的時候method=post,提交表單就是發post請求

          6.5、響應的協議格式

          響應的HTTP協議格式

          響應首行

          響應頭信息

          空行

          響應體

          6.6、常見的響應碼

          響應碼對瀏覽器來說很重要,它告訴瀏覽器響應的結果;

          200:請求成功,瀏覽器會把響應體內容(通常是html)顯示在瀏覽器中;

          404:請求的資源沒有找到,說明客戶端錯誤的請求了不存在的資源;

          500:請求資源找到了,但服務器內部出現了錯誤;

          302:請求重定向,當響應碼為302時,表示服務器要求瀏覽器重新再發一個請求,服務器會發送一個響應頭Location,它指定了新請求的URL地址;

          7、servlet(重點*****)

          7.1、servlet簡介

          servlet 是運行在 Web 服務器中的小型 Java 程序。servlet 通常通過 HTTP(超文本傳輸協議)接收和響應來自 Web 客戶端的請求。

          要實現此接口,可以編寫一個擴展 javax.servlet.GenericServlet 的一般 servlet,或者編寫一個擴展 javax.servlet.http.HttpServlet 的 HTTP servlet。

          此接口定義了初始化 servlet 的方法、為請求提供服務的方法和從服務器移除 servlet 的方法。這些方法稱為生命周期方法,它們是按以下順序調用的:

          1.構造 servlet,然后使用 init 方法將其初始化。

          2.處理來自客戶端的對 service 方法的所有調用。

          3.從服務中取出 servlet,然后使用 destroy 方法銷毀它,最后進行垃圾回收并終止它。

          Servlet:

          1、接受瀏覽器發送過來的消息。

          2、給瀏覽器返回消息。瀏覽器認識html。可以動態去輸出html

          7.2、servlet快速入門

          7.2.1、如何創建動態的Web工程

          1)先創建 動態的Web工程

          2) 配置工程的選項

          3)勾選生成web.xml配置文件

          4)動態web工程創建完成!!!

          5)web工程的介紹和說明

          7.2.2、手動編寫servlet實現

          寫servlet做兩件事

          1、實現servlet接口。 由sun公司定義的一個接口。(定義一個規范)

          2、把類部署到web服務器中(tomcat)。

          sun公司定義一個servlet的規范。定義了servlet應該有哪些方法,以及方法需要的參數。

          1、實現servlet接口(javax.servlet.Servlet)

          2、重寫service方法(service方法每次請求都會調用一次)

          [java] view plain copy

          1. package com.atguigu.web;
          2. import java.io.IOException;
          3. import javax.servlet.Servlet;
          4. import javax.servlet.ServletConfig;
          5. import javax.servlet.ServletException;
          6. import javax.servlet.ServletRequest;
          7. import javax.servlet.ServletResponse;
          8. public class Hello implements Servlet{
          9. @Override
          10. public void destroy() {
          11. // TODO Auto-generated method stub
          12. System.out.println("Servlet銷毀了!");
          13. }
          14. @Override
          15. public ServletConfig getServletConfig() {
          16. // TODO Auto-generated method stub
          17. return ;
          18. }
          19. @Override
          20. public String getServletInfo() {
          21. // TODO Auto-generated method stub
          22. return ;
          23. }
          24. @Override
          25. public void init(ServletConfig arg0) throws ServletException {
          26. // TODO Auto-generated method stub
          27. System.out.println("ServerConfig 初始化了");
          28. }
          29. @Override
          30. public void service(ServletRequest arg0, ServletResponse arg1)
          31. throws ServletException, IOException {
          32. // TODO Auto-generated method stub
          33. System.out.println("hello servlet service方法被調用");
          34. }
          35. }

          當瀏覽器輸入地址,訪問servlet的時候,servlet會執行servcie方法。

          3、在WebContent/WEB-INF/web.xml中配置servlet的訪問路徑 。瀏覽器訪問servlet的路徑

          web.xml(新建web工程的時候,eclipse自動創建出來的)的位置:

          在web.xml的根標簽下,直接書寫如下內容。

          [html] view plain copy

          1. <?xml version="1.0" encoding="UTF-8"?>
          2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
          3. <display-name>day06</display-name>
          4. <servlet>
          5. <servlet-name>Hello</servlet-name>
          6. <servlet-class>com.atguigu.web.Hello</servlet-class>
          7. </servlet>
          8. <servlet-mapping>
          9. <servlet-name>Hello</servlet-name>
          10. <url-pattern>/hello</url-pattern>
          11. </servlet-mapping>
          12. <welcome-file-list>
          13. <welcome-file>index.html</welcome-file>
          14. <welcome-file>index.htm</welcome-file>
          15. <welcome-file>index.jsp</welcome-file>
          16. <welcome-file>default.html</welcome-file>
          17. <welcome-file>default.htm</welcome-file>
          18. <welcome-file>default.jsp</welcome-file>
          19. </welcome-file-list>
          20. </web-app>

          4、把項目部署到tomcat中,去啟動tomcat。在地址欄中輸入信息,訪問servlet

          控制臺打印:

          7.2.3、訪問servlet的細節

          瀏覽器地址欄中輸入:http://localhost:8080/day06/hello

          訪問過程分析:

          7.2.4、servlet生命周期

          Servlet的生命周期

          1.調用 init 方法 初始化Servlet

          2.調用 Servlet中的service方法 處理請求操作

          3.調用 destory方法 執行Servlet銷毀的操作

          init方法:當服務器創建一個serlvet的時候,會去調用init方法。當我們第一次去訪問一個servlet的時候,會去創建這個servlet對象。并且只會創建一次。如果配置了load-on-startup 表示服務器啟動的時候就創建servlet實例。

          service方法:客戶端每一次請求,tomcat都會去調用servcie方法。處理用戶的請求。并且給其響應。每一次請求都會調用servcie方法。

          estroy 方法:當服務器銷毀一個servlet的時候,會調用里面的destory方法。當我們的web服務器,正常關閉的時候,會去調用destroy方法。否則不會調用destroy的方法。

          7.3、使用Eclipse創建Servlet程序(重點*****)

          1)通過Eclipse自動新建一個Servlet程序

          2)修改Servlet的訪問url地址

          3)勾選需要生成的Servlet方法

          4) 查看自動生成的結果內容!!!

          5) 在瀏覽器中輸出http://127.0.0.1:80/day06/helloServlet 訪問測試

          訪問成功

          7.4、Servlet是單例的。Servlet中的變量,它有線程安全問題。

          7.4.1、全局變量,數據不安全。

          7.4.2、方法內的局部變量,數據安全

          用 Servlet 發送一封電子郵件是很簡單的,但首先您必須在您的計算機上安裝 JavaMail APIJava Activation Framework)JAF)

          • 您可以從 Java 網站下載最新版本的 JavaMail,打開網頁右側有個 Downloads 鏈接,點擊它下載。

          • 您可以從 Java 網站下載最新版本的 JAF(版本 1.1.1)。

          你也可以使用本站提供的下載鏈接:

          • JavaMail mail.jar 1.4.5

          • JAF(版本 1.1.1) activation.jar

          下載并解壓縮這些文件,在新創建的頂層目錄中,您會發現這兩個應用程序的一些 jar 文件。您需要把 mail.jaractivation.jar 文件添加到您的 CLASSPATH 中。

          發送一封簡單的電子郵件

          下面的實例將從您的計算機上發送一封簡單的電子郵件。這里假設您的本地主機已連接到互聯網,并支持發送電子郵件。同時確保 Java Email API 包和 JAF 包的所有的 jar 文件在 CLASSPATH 中都是可用的。

          // 文件名 SendEmail.javaimport java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import javax.mail.*;import javax.mail.internet.*;import javax.activation.*;
          public class SendEmail extends HttpServlet{
           public void doGet(HttpServletRequest request,
           HttpServletResponse response)
           throws ServletException, IOException
           {
           // 收件人的電子郵件 ID
           String to = "abcd@gmail.com";
           // 發件人的電子郵件 ID
           String from = "web@gmail.com";
           // 假設您是從本地主機發送電子郵件
           String host = "localhost";
           // 獲取系統的屬性
           Properties properties = System.getProperties();
           // 設置郵件服務器
           properties.setProperty("mail.smtp.host", host);
           // 獲取默認的 Session 對象
           Session session = Session.getDefaultInstance(properties);
           // 設置響應內容類型
           response.setContentType("text/html;charset=UTF-8");
           PrintWriter out = response.getWriter();
           try{
           // 創建一個默認的 MimeMessage 對象
           MimeMessage message = new MimeMessage(session);
           // 設置 From: header field of the header.
           message.setFrom(new InternetAddress(from));
           // 設置 To: header field of the header.
           message.addRecipient(Message.RecipientType.TO,
           new InternetAddress(to));
           // 設置 Subject: header field
           message.setSubject("This is the Subject Line!");
           // 現在設置實際消息
           message.setText("This is actual message");
           // 發送消息
           Transport.send(message);
           String title = "發送電子郵件";
           String res = "成功發送消息...";
           String docType = "<!DOCTYPE html> \n";
           out.println(docType +
           "<html>\n" +
           "<head><title>" + title + "</title></head>\n" +
           "<body bgcolor=\"#f0f0f0\">\n" +
           "<h1 align=\"center\">" + title + "</h1>\n" +
           "<p align=\"center\">" + res + "</p>\n" +
           "</body></html>");
           }catch (MessagingException mex) {
           mex.printStackTrace();
           }
           }}

          現在讓我們來編譯上面的 Servlet,并在 web.xml 文件中創建以下條目:

          ....
          <servlet>
           <servlet-name>SendEmail</servlet-name>
           <servlet-class>SendEmail</servlet-class>
          </servlet>
          <servlet-mapping>
           <servlet-name>SendEmail</servlet-name>
           <url-pattern>/SendEmail</url-pattern>
          </servlet-mapping>....

          現在通過訪問 URL http://localhost:8080/SendEmail 來調用這個 Servlet。這將會發送一封電子郵件到給定的電子郵件 ID abcd@gmail.com,并將顯示下面所示的響應:

          發送電子郵件

          成功發送消息...

          如果您想要發送一封電子郵件給多個收件人,那么請使用下面的方法來指定多個電子郵件 ID:

          void addRecipients(Message.RecipientType type,
           Address[] addresses)throws MessagingException

          下面是對參數的描述:

          • type:這將被設置為 TO、CC 或 BCC。在這里,CC 代表抄送,BCC 代表密件抄送。例如 Message.RecipientType.TO。

          • addresses:這是電子郵件 ID 的數組。當指定電子郵件 ID 時,您需要使用 InternetAddress() 方法。

          發送一封 HTML 電子郵件

          下面的實例將從您的計算機上發送一封 HTML 格式的電子郵件。這里假設您的本地主機已連接到互聯網,并支持發送電子郵件。同時確保 Java Email API 包和 JAF 包的所有的 jar 文件在 CLASSPATH 中都是可用的。

          本實例與上一個實例很類似,但是這里我們使用 setContent() 方法來設置第二個參數為 "text/html" 的內容,該參數用來指定 HTML 內容是包含在消息中的。

          使用這個實例,您可以發送內容大小不限的 HTML 內容。

          // 文件名 SendEmail.javaimport java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import javax.mail.*;import javax.mail.internet.*;import javax.activation.*;
          public class SendEmail extends HttpServlet{
           public void doGet(HttpServletRequest request,
           HttpServletResponse response)
           throws ServletException, IOException
           {
           // 收件人的電子郵件 ID
           String to = "abcd@gmail.com";
           // 發件人的電子郵件 ID
           String from = "web@gmail.com";
           // 假設您是從本地主機發送電子郵件
           String host = "localhost";
           // 獲取系統的屬性
           Properties properties = System.getProperties();
           // 設置郵件服務器
           properties.setProperty("mail.smtp.host", host);
           // 獲取默認的 Session 對象
           Session session = Session.getDefaultInstance(properties);
           // 設置響應內容類型
           response.setContentType("text/html;charset=UTF-8");
           PrintWriter out = response.getWriter();
           try{
           // 創建一個默認的 MimeMessage 對象
           MimeMessage message = new MimeMessage(session);
           // 設置 From: header field of the header.
           message.setFrom(new InternetAddress(from));
           // 設置 To: header field of the header.
           message.addRecipient(Message.RecipientType.TO,
           new InternetAddress(to));
           // 設置 Subject: header field
           message.setSubject("This is the Subject Line!");
           // 設置實際的 HTML 消息,內容大小不限
           message.setContent("<h1>This is actual message</h1>",
           "text/html" );
           // 發送消息
           Transport.send(message);
           String title = "發送電子郵件";
           String res = "成功發送消息...";
           String docType = "<!DOCTYPE html> \n";
           out.println(docType +
           "<html>\n" +
           "<head><title>" + title + "</title></head>\n" +
           "<body bgcolor=\"#f0f0f0\">\n" +
           "<h1 align=\"center\">" + title + "</h1>\n" +
           "<p align=\"center\">" + res + "</p>\n" +
           "</body></html>");
           }catch (MessagingException mex) {
           mex.printStackTrace();
           }
           }}

          編譯并運行上面的 Servlet ,在給定的電子郵件 ID 上發送 HTML 消息。

          在電子郵件中發送附件

          下面的實例將從您的計算機上發送一封帶有附件的電子郵件。這里假設您的本地主機已連接到互聯網,并支持發送電子郵件。同時確保 Java Email API 包和 JAF 包的所有的 jar 文件在 CLASSPATH 中都是可用的。

          // 文件名 SendEmail.javaimport java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import javax.mail.*;import javax.mail.internet.*;import javax.activation.*;
          public class SendEmail extends HttpServlet{
           public void doGet(HttpServletRequest request,
           HttpServletResponse response)
           throws ServletException, IOException
           {
           // 收件人的電子郵件 ID
           String to = "abcd@gmail.com";
           // 發件人的電子郵件 ID
           String from = "web@gmail.com";
           // 假設您是從本地主機發送電子郵件
           String host = "localhost";
           // 獲取系統的屬性
           Properties properties = System.getProperties();
           // 設置郵件服務器
           properties.setProperty("mail.smtp.host", host);
           // 獲取默認的 Session 對象
           Session session = Session.getDefaultInstance(properties);
           // 設置響應內容類型
           response.setContentType("text/html;charset=UTF-8");
           PrintWriter out = response.getWriter();
           try{
           // 創建一個默認的 MimeMessage 對象
           MimeMessage message = new MimeMessage(session);
           // 設置 From: header field of the header.
           message.setFrom(new InternetAddress(from));
           // 設置 To: header field of the header.
           message.addRecipient(Message.RecipientType.TO,
           new InternetAddress(to));
           // 設置 Subject: header field
           message.setSubject("This is the Subject Line!");
           // 創建消息部分
           BodyPart messageBodyPart = new MimeBodyPart();
           // 填寫消息
           messageBodyPart.setText("This is message body");
           // 創建一個多部分消息
           Multipart multipart = new MimeMultipart();
           // 設置文本消息部分
           multipart.addBodyPart(messageBodyPart);
           // 第二部分是附件
           messageBodyPart = new MimeBodyPart();
           String filename = "file.txt";
           DataSource source = new FileDataSource(filename);
           messageBodyPart.setDataHandler(new DataHandler(source));
           messageBodyPart.setFileName(filename);
           multipart.addBodyPart(messageBodyPart);
           // 發送完整的消息部分
           message.setContent(multipart );
           // 發送消息
           Transport.send(message);
           String title = "發送電子郵件";
           String res = "成功發送電子郵件...";
           String docType = "<!DOCTYPE html> \n";
           out.println(docType +
           "<html>\n" +
           "<head><title>" + title + "</title></head>\n" +
           "<body bgcolor=\"#f0f0f0\">\n" +
           "<h1 align=\"center\">" + title + "</h1>\n" +
           "<p align=\"center\">" + res + "</p>\n" +
           "</body></html>");
           }catch (MessagingException mex) {
           mex.printStackTrace();
           }
           }}

          編譯并運行上面的 Servlet ,在給定的電子郵件 ID 上發送帶有文件附件的消息。

          用戶身份認證部分

          如果需要向電子郵件服務器提供用戶 ID 和密碼進行身份認證,那么您可以設置如下屬性:

          props.setProperty("mail.user", "myuser");
          props.setProperty("mail.password", "mypwd");

          電子郵件發送機制的其余部分與上面講解的保持一致。


          主站蜘蛛池模板: 午夜精品一区二区三区免费视频| 一区二区三区免费看| 在线日韩麻豆一区| 一区二区三区视频在线观看| 亚洲韩国精品无码一区二区三区| 国产一区二区三区在线观看免费 | 久久久一区二区三区| 国产精品第一区第27页| 免费在线观看一区| 日本精品一区二区三区在线视频| 天天综合色一区二区三区| 国内精自品线一区91| 国产精品一区二区久久乐下载 | 国产精品特级毛片一区二区三区 | 日本精品一区二区三区在线观看| 538国产精品一区二区在线| 一区二区三区杨幂在线观看| 久久国产香蕉一区精品| 国产成人无码一区二区在线观看| 激情综合一区二区三区| 鲁丝片一区二区三区免费| 少妇特黄A一区二区三区| 亚洲福利一区二区三区| 亚洲欧美成人一区二区三区| 国产精品一区二区久久乐下载| 国产精品一区二区无线| 国产在线精品一区免费香蕉| 久久国产一区二区三区| 亚洲AV无码片一区二区三区| 国产主播福利精品一区二区| 中文字幕精品一区二区三区视频| 国产精品视频一区二区三区四| 国产美女一区二区三区| 国产成人精品一区二三区| 中文字幕不卡一区| 中文字幕日韩丝袜一区| 乱色熟女综合一区二区三区| 国产成人一区二区三区在线观看| 中文精品一区二区三区四区| 无码国产亚洲日韩国精品视频一区二区三区| V一区无码内射国产|