準備技術:
Servlet
Servlet Container
HTTPServlet Request/Response
Sevlet Filter
Servlet Listener
Web是靠HTTP協定傳輸Server與Client之間的資料。
Servlet是一個Class,Container是一個抽象概念,管理一些東西,而Servlet Container是管理Servlet物件,負責HTTP資料處理。
Java Web Server的設計,是包含Container,Container種類眾多,其中是Servlet Container,多數是這種。
Servlet典型的處理HTTP程式。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/demoServlet")
public class demoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public demoServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理HTTP GET方式
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理HTTP POST方式
}
}
一個Servlet Container其實也是Servlet,只是提供管理功能,一般是Java Web Server來實做,框架本身如果要實做,就要先處理HTTP進來後轉到框架的Filter。
import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class PrimitiveServlet implements Servlet {
public void init(ServletConfig config) throws ServletException {
System.out.println("init");
}
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("from service");
PrintWriter out = response.getWriter();
out.println("Hello. Roses are red.");
out.print("Violets are blue.");
}
public void destroy() {
System.out.println("destroy");
}
public String getServletInfo() { return null; }
public ServletConfig getServletConfig() { return null; }
}
什麼是HTTPServletRequest/Response?Java提供介面給Java Servlet物件實做,包裝(Wrapper)了HTTP Request/Response,處理HTTP資料。
在第五點提到Filter,當Client傳送HTTP Request給Server時,如果Servlet想要過濾訊息,可設下機制,就是一個Filter,Filter是Servlet的一個功能。
基本的Filter舉例,攔截傳輸的 HTTP log資料 。
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.;
@WebFilter("/*")
public class LoggingFilter implements Filter {
private FilterConfig filterConf = null;
public void init(FilterConfig filterConf) {
this.filterConf = filterConf;
}
//如果有多個Filter ,要設定FilterChain,並且設定順序,Filter會一個個順序執行。
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException, ServletException {
String userName = request.getRemoteHost();
//攔截Log的使用者IP
filterConf.getServletContext().log("User IP: " + userName);
chain.doFilter(request, response);
}
@Override
public void destroy() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Servlet提供Listener機制觀看Servlet運作,Listener種類眾多,這裡提供一個Listener程式來看Servlet 的Context狀況。
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;
@WebListener
public class StartupShutdownListener implements ServletContextListener {
//Context初始,送一封信給系統。
public void contextInitialized(ServletContextEvent event) {
System.out.println("Servlet startup. . .");
System.out.println(event.getServletContext().getServerInfo());
System.out.println(System.currentTimeMillis());
sendEmail("Servlet context has initialized");
}
//Context結束,送一封信給系統。
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Servlet shutdown. . .");
System.out.println(event.getServletContext().getServerInfo());
System.out.println(System.currentTimeMillis());
sendEmail("Servlet context has been destroyed. . .");
private boolean sendEmail(String message) {
boolean result = false;
//借用Google Gmail發信
String smtpHost = "smtp.gmail.com";
String smtpUsername = "username";
String smtpPassword = "password";
String from = "fromaddress";
String to = "toaddress";
int smtpPort = 587;
System.out.println("sending email. . .");
try {
//利用 java property存入一些資料
Properties props = new Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
//信存入到Session暫存
Session session = Session.getInstance(props);
Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress(from);
msg.setFrom(addressFrom);
InternetAddress[] address = new InternetAddress[1];
address[0] = new InternetAddress(to);
//信的內容
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("Servlet container shutting down");
msg.setContent(message, "text/plain");
//信件送出設定
Transport transport = session.getTransport("smtp");
transport.connect(smtpHost, smtpPort, smtpUsername, smtpPassword);
Transport.send(msg);
result = true;
} catch (javax.mail.MessagingException ex) {
ex.printStackTrace();
result = false;
}
return result;
}
}
參考資料
Day2 結束