寫在前面
在上篇博文JSP內置對象中介紹JSP的9個內置對象的含義和常用方法,但都是比較理論的知識。今天為大家帶來一個小應用,用application制作的簡易留言板。
包括三個功能模塊:留言提交、留言展示、查看留言板。用3個JSP頁面展示信息(視圖層),一個servlet處理用戶的請求(控制層),因為比較簡單沒有用到javaBean作為模型層。還有一個filter初始化應用。
表單提交
本例中用submit.jsp頁面提交留言。用表單提交用戶的請求參數,action參數處理用戶請求程序的路徑。關於表單提交有兩點說明:
1.路徑
在JSP頁面中,建議用絕對路徑,形如:<%=request.getContextPath()%>/MsgPane,request.getContextPath()代表項目的根目錄。其原因是絕對路徑簡單不容易出錯。在寫JSP程序是經常會犯路徑的錯誤,就是沒明白一些基本的概念。
在html標簽中,“/”是代表服務器的根目錄:形如:http://localhost:8080/
在JSP腳本中,“/”Web應用的根目錄:形如:http://localhost:8080/yourwebapp/
為了統一前后端路徑的使用,IDE在新建JSP的會加入<base>標簽,這個時候相對路徑是不起作用的,瀏覽器解析時會在其前面加上base的href屬性值。例如:
有<base>標簽的存在,<form action="MsgPane" method="post"> 瀏覽器解析的路徑為“http://localhost:8080/yourwebapp/”+Msgpane。
2.方法
post提交時,參數不會附加在URL中,安全性更高,表單提交建議使用post。
submit.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<form action="<%=request.getContextPath()%>/MsgPane" method="post">
請輸入你的姓名:<br><input type="text" name="name"><br>
請輸入你的標題:<br><input type="text" name="title"><br>
留言內容:<br><textarea rows="15" cols="20" name="message"></textarea><br><br>
<input type="submit" value="提交信息"><br>
</form>
<form action="<%=request.getContextPath()%>/msgpane/messages.jsp">
<input type="submit" value="查看留言板">
</form>
<%-- </body>--%>
</html>
處理用戶請求
我們一般用servlet處理用戶請求,servlet多用於流程控制,也就是我們常說得MVC中C(控制層)。
1.處理表單參數的中文亂碼,可在servlet重寫的請求方法中加入
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
2.application對象在JSP中是內置的,而在servlet中,需要自己去實例化。
ServletContext application = request.getServletContext();
3.application的常用方法,其實底層實現是Map。
application.setAttribute(String key,Object obj); application.getAttribute(String key); //Object,需要類型強轉!
4.session與application常用方法類似,只是作用范圍限於同一用戶,而application是整個應用,用下面方法實例化。
HttpSession session=request.getSession();
MsgPane.java
package servlet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MsgPane extends HttpServlet {
List<String> msgs;
int count;
String objfile="";
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
objfile=request.getServletContext().getRealPath("/")+"msgpane\\Msgpane.obj";
System.out.println(objfile);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
ServletContext application = request.getServletContext();
HttpSession session=request.getSession();
if(application.getAttribute("msgs")!=null){
msgs=(List<String>)application.getAttribute("msgs");
}else{
msgs=new ArrayList();
System.out.println("New");
}
count = msgs.size();
String date = new Date().toLocaleString();
String name = request.getParameter("name");
String title = request.getParameter("title");
String msg = request.getParameter("message");
if (name == null || "".equals(name)) {
name = "guest";
}
if (title == null || "".equals(title)) {
title = "無標題";
}
if (msg == null || "".equals(msg)) {
request.getRequestDispatcher("/msgpane/submit.jsp").forward(request,
response);
} else {
count++;
String tmsg = "<br><br><br>No." + count + " "
+ date + "<br><br>姓名:" + name + "<br>標題:" + title
+ "<br>內容:" + msg;
msgs.add(tmsg);
saveMsgPane(objfile);
application.setAttribute("msgs", msgs);
session.setAttribute("msg", tmsg);
request.getRequestDispatcher("/msgpane/msgpane.jsp").forward(request,
response);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
public void saveMsgPane(String filename) {
try {
saveObject(filename, msgs);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveObject(String filename, Object obj) throws IOException {
File f = new File(filename);
if (!f.exists()) {
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
fos.close();
oos.close();
}
}
初始化應用
在啟動應用時,將留言板內容從文件讀取,存入application對象。
MsgpaneFilter.java
package filter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MsgpaneFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String objfile = request.getServletContext().getRealPath("/")+"msgpane\\Msgpane.obj";
System.out.println(objfile);
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
ServletContext application = request.getServletContext();
if (application.getAttribute("msgs") == null) {
File f = new File(objfile);
if (f.exists()) {
try {
application.setAttribute("msgs", readObject(objfile));
System.out.println("read");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
System.out.println("File not found!");
req.getRequestDispatcher("/msgpane/submit.jsp").forward(req,
resp);
}
}
chain.doFilter(req, resp);
}
@Override
public void destroy() {
}
public Object readObject(String filename) throws IOException,
ClassNotFoundException {
Object obj = null;
File ft = new File(filename);
if (ft.exists()) {
FileInputStream fis = new FileInputStream(ft);
ObjectInputStream ois = new ObjectInputStream(fis);
obj = ois.readObject();
fis.close();
ois.close();
} else {
// do something
}
return obj;
}
}
關於留言展示和查看留言板我就不貼代碼了,非常簡單。這個小例子的代碼我打包好了,下面是鏈接:
