《JSP & Servlet学习笔记》章节试读

当前位置:首页 > 计算机网络 > 程序设计 > JSP & Servlet学习笔记章节试读

出版社:清华大学出版社
出版日期:2012-5
ISBN:9787302283669
作者:【台湾】林信良
页数:463页

《JSP & Servlet学习笔记》的笔记-第195页 - 6.1.5 注释元素

JSP有一个专用的注释,即<%--与--%>。

《JSP & Servlet学习笔记》的笔记-第46页 - 2.5.2 实训题

Login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<form action="http://localhost:8080/FirstServlet/Login" method="post">
用户:<input type="text" name="user"><br />
密码:<input type="password" name="password"><br />
<input type="submit" value="提交" />

</form>
</body>
</html>
Login.javapackage cc.openhome;
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("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;

public Login() {
super();

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

response.getWriter().append("Served at: ").append(request.getContextPath());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String user=request.getParameter("user");
String password= request.getParameter("password");

if(user.equals("caterpillar") && password.equals("123456")){
HTMLUtils.showHTMLPage(response, "登录成功");
}else{
HTMLUtils.showHTMLPage(response, "登录失败","<br/><a href=\"http://localhost:8080/FirstServlet/Login.html\">返回登录界面</a>");
}
}
}
HTMLUtils.javapackage cc.openhome;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
public class HTMLUtils {

public static void showHTMLPage(HttpServletResponse response,String... str) throws IOException{

response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

String showStr="";
for(String s:str){
showStr =showStr + s +" ";
}
out.println("<html>");
out.println("<head>");
out.println("<title>Hello Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1> " + showStr + "</h1>");
out.println("</body>");
out.println("</html>");
out.close();
}
}

《JSP & Servlet学习笔记》的笔记-第196页 - 6.1.6 隐式对象

隐式对象只能在<%与%>之间,或<%=与%>之间使用,因为隐式对象在转译为Servlet后,是_jspService()中的局部变量,无法在<%!与%>之间使用隐式对象(<%!与%>之间声明的变量对应至类变量成员)。

《JSP & Servlet学习笔记》的笔记-第402页 - 10.1.3 容器基本身份验证原理

《JSP & Servlet学习笔记》的笔记-第108页 - 4.2.2 HttpSession会话管理原理

使用HttpSession来进行会话管理时,设定为属性的对象是存储在服务器端,而SessionID默认使用Cookie存放于浏览器端。Web容器存储Session ID的Cookie“默认”为关闭浏览器就失效,所以重新启动浏览器请求应用程序时,通过getSession()取得的是新的HttpSession对象。
每次请求来到应用程序时,容器会根据发送过来的Session ID取得对应的HttpSession。由于HttpSession对象会占用内存空间,所以HttpSession的属性中尽量不要存储耗资源的大型对象,必要时将属性移除,或者不需使用HttpSession时,执行invalidate()让HttpSession失效。

《JSP & Servlet学习笔记》的笔记-第64页 - 3.2.4 getPart()、getParts()取得上传文件

在Tomcat中要在Servlet上设置@MultipartConfig才能取得Part对象,否则getPart()会得到null的结果。
Part有个方便的write()方法,可以直接将上传文件指定文件名写入磁盘中,write()可指定文件名,写入的路径是相对于@MultipartConfig的location设置的路径。
如果有多个文件要上传,可以使用getParts()方法,这会返回一个Collection<Part>,其中是每个上传文件的Part对象。
使用增强式for循环语法,逐一取得Part对象。由于”上传“按钮也会是其中一个Part对象,所以使用if来判断Part的名称是不是以file作开头,可以使用Part的getName()来取得名称。

《JSP & Servlet学习笔记》的笔记-第94页 - 4.1 会话管理基本原理

①使用隐藏域
使用隐藏域的方式,在关掉网页后,显然会遗失先前请求的信息,所以仅适合用于一些简单的状态管理,如在线问卷。由于在查看网页源代码时,就可以看到隐藏域的值,因此这个方法不适合用于保密性较高的数据。
②使用Cookie
例:
Cookie cookie = new Cookie("user","caterpillar");
cookie.setMaxAge(7*24*60*60);//单位是“秒”,所以一星期内有效
response.addCookie(cookie);
可以用getCookies()来取得,这可取得属于该网页所属域(Domain)的所有Cookie,所以返回值是Cookie[]数值。取得Cookie对象后,可以使用Cookie的getName()与getValue()方法,分别取得Cookie的名称与数值。例如:Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
String name = cookie.getName();
String value = cookie.getValue();
...
}
}③使用URL重写
因为URL重写是在超链接之后附加信息的方式,所以必须以GET方式发送请求,再加上GET本身可以携带的请求参数长度有限,因此大量的客户端信息保留,并不适合使用URL重写。

《JSP & Servlet学习笔记》的笔记-第69页 - 2.请求范围属性

在include()或forward()时包括请求参数的做法,仅适用于传递字符串值给另一个Servlet,在调派请求的过程中,如果有必须共享的“对象”,可以设置给请求对象成为属性,称为请求范围属性(Request Scope Attribute)。
例如,有个Servlet会根据某些条件查询数据:List<Book> books = bookDAO.query("ServletJSP");
request.setAttribute("books",books);
request.getRequestDispatcher("result.view").include(request,response);假设result.view这个URL是个负责响应的Servlet实例,则它可以利用HttpServletRequest对象的getAttribute()取得查询结果:List<Book> books = (List<Book>)request.getAttribute("books");由于请求对象仅在此次请求周期内有效,在请求/响应之后,请求对象会被销毁回收,设置在请求对象中的属性自然也就消失了,所以通过setAttribute()设置的属性才称为请求范围属性。

《JSP & Servlet学习笔记》的笔记-第74页 - 3.3.2 使用getWriter()输出字符

PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
有几个方式可以影响HttpServletResponse输出的编码处理:
1.设置Locale
可以使用HttpServletResponse的setLocale()来设置地区(Locale)信息,地区信息就包括了语系与编码信息。语系信息通常通过响应标头Content-Language来设置,而setLocale()也会设置HTTP响应的Content-Language标头。例如:
resq.setLocale(Locale.TAIWAN);
2.使用setCharacterEncoding()或setContentType()
resq.setCharacterEncoding("UTF-8");
或者是在使用HttpServletResponse的setContentType()时,指定charset,charset的值会自动用来调用setCharacterEncoding()。例如,以下不仅设置内容类型为text/html,也会自动调用setCharacterEncoding(),设置编码为UTF-8:
resq.setContentType("text/html;charset=UTF-8");
如果使用了setCharacterEncoding()或setContentType()时指定了charset,则setLocale()就会被忽略。
提示:如果要接收中文请求参数并在响应时通过浏览器正确显示中文,必须同时设置HttpServletRequest的setCharacterEncoding()以及HttpServletResponse的setCharacterEncoding()或setContentType()为正确的编码。

《JSP & Servlet学习笔记》的笔记-第60页 - 3.2.3 getReader()、getInputStream()读取Body内容

窗体发送时,如果<form>标签没有设置enctype属性,则默认值就是application/x-www-form-urlencoded。如果要上传文件,则enctype属性要设为multipart/form-data。

《JSP & Servlet学习笔记》的笔记-第143页 - 5.3.2 实现与设置过滤器

//service()前置处理
chain.doFilter(request,response);
//service()后置处理
只需要知道FilterChain运行后会以堆栈顺序返回即可。在实现Filter接口时,不用理会这个Filter前后是否有其他Filter,应该将之作为一个独立的元件设计。
以下实现一个简单的性能评测过滤器,可用来记录请求与响应间的时间差。
package cc.openhome;
import java.io.IOException;
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;
@WebFilter(filterName="performance", urlPatterns={"/*"})
public class PerformanceFilter implements Filter {
private FilterConfig config;

@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
long begin = System.currentTimeMillis();
chain.doFilter(request, response);
config.getServletContext().log("Request process in " +
(System.currentTimeMillis() - begin) + " milliseconds");
}
@Override
public void destroy() {}
}

《JSP & Servlet学习笔记》的笔记-第36页

《JSP & Servlet学习笔记》的笔记-第104页 - 4.2.1 使用HttpSession

HttpSession上最常用的方法大概就是setAttribute()与getAttribute(),从名称上应该可以猜到,这与HttpServletRequest的setAttribute()与getAttribute()类似,可以让你在对象中设置及取得属性,这是可以存放属性对象的第二个地方(Servlet API中第三个可存放属性的地方是在ServletContext中)。
默认在关闭浏览器前,取得HttpSession都是相同的实例。如果想在此次会话期间,直接让目前的HttpSession失效,可以执行HttpSession的invalidate()方法。一个使用的时机就是实现注销机制。
package cc.openhome;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/user.view")
public class User extends HttpServlet {
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
if (session.getAttribute("login") == null) {
response.sendRedirect("login.html");
}else {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01" +
" Transitional//EN'>");
out.println("<html>");
out.println("<head>");
out.println("<title>欢迎 "
+ session.getAttribute("login") + "</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>用户 " +
session.getAttribute("login") + " 已登录</h1><br><br>");
out.println("<a href='logout.view'>注销</a>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
package cc.openhome;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/logout.view")
public class Logout extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");

HttpSession session = request.getSession();
String user = (String) session.getAttribute("login");
session.invalidate();

PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01" +
" Transitional//EN'>");
out.println("<html>");
out.println("<head>");
out.println("<title>登出</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>使用者 " + user + " 已登出</h1>");
out.println("</body>");
out.println("</html>");
out.close();
}
}

《JSP & Servlet学习笔记》的笔记-第78页 - 3.3.3 使用getOutputStream()输出二进制字符

用户输入正确的密码,取得所提供的PDF电子书package cc.openhome;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Download
*/
@WebServlet("/download.do")
public class Download extends HttpServlet {
private static final long serialVersionUID = 1L;
public Download() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String passwd = request.getParameter("passwd");
if("123456".equals(passwd)){
response.setContentType("application/pdf");
InputStream in =getServletContext().getResourceAsStream("/WEB-INF/jdbc.pdf");
OutputStream out = response.getOutputStream();
writeBytes(in,out);
}
}

private void writeBytes(InputStream in,OutputStream out) throws IOException{
byte[] buffer = new byte[1024];
int length = -1;
while((length = in.read(buffer)) != -1){
out.write(buffer, 0, length);
}
in.close();
out.close();
}
}

《JSP & Servlet学习笔记》的笔记-第10页 - 1.1.5 动态网页与静态网页

服务器会如同处理那些HTML标签一样,将这些JavaScript原封不动地传给浏览器,浏览器收到响应后再处理标签与执行Javascript。
对处理JSP内容的服务器而言,内嵌的Javascript跟静态的HTML标签没有两样。

《JSP & Servlet学习笔记》的笔记-第33页 - 2.2.2 使用@WebServlet

@WebServlet("/hello.view")
public class HelloServlet extends HttpServlet {
只要在Servlet上设置@WebServlet标注,容器就会自动读取当中的信息。上面的@WebServlet告诉容器,如果请求的URL是"/hello.view",则由HelloServlet的实例提供服务。

《JSP & Servlet学习笔记》的笔记-第7页 - 1.1.3 关于HTTP

除了长度过长的请求数据之外,许多请求既可以使用GET也可以使用POST,那么何时该使用GET而何时该使用POST?
从功能上,可以用以下方式来决定该选用GET或POST?
GET 请求跟随在URL之后的请求参数长度是有限的,过长的请求参数,或如文件上传这类的大量数据,就不适合用GET请求,而应该用POST请求。
GET请求的请求参数会出现在地址栏上,敏感性或安全性考虑的请求参数(如信用卡号码、用户名、密码等),就不应该使用GET请求来发送。
POST请求的请求参数不会出现在地址栏上,所以无法加入浏览器的书签(Bookmark)之中,如果有些页面是根据请求参数来作不同的画面呈现(如论坛的文章发表),而你希望可以让用户设定书签,以便日后可以直接点击书签浏览,则应该使用GET请求。
有些浏览器会依网址来缓存(Cache)数据,如果网址是相同的URL,则会直接从浏览器缓存中取出数据,而不会真正发送请求至服务器上查询最新的数据。如果不希望服务器状态改变了,而浏览器仍从缓存中取得旧的资料,则可以改用POST请求(使用GET请求也可以避免缓存,例如在网址上附加时间戳,让每次GET请求的网址都不相同)。
另外,还有一个非功能上的考虑,但其实也是HTTP当初在设计时区分GET与POST的目的之一,就是按请求是否等幂(idempotent)操作来决定使用GET或POST。所谓是否为等幂操作,就是请求的操作是否改变服务器状态,同一个操作重复多次,是否传回同样的结果。
GET 请求应该用于等幂操作。GET请求纯粹取得资源,而不改变服务器上的数据或状态。GET的请求参数,只是用来告知服务器,必须进一步根据请求参数(而不只是URL)来标识要响应的内容(例如查询数据库的数据),同样的GET请求且使用相同的请求参数重复发送多次,都应该传回相同的结果。
POST请求应该用于非等幂(non-idempotent)操作。POST请求发送的数据,可能会影响服务器上的数据或状态,例如修改(增、删、改)数据库的内容,或是在服务器上保存文件。你的请求若会改变服务器的状态,则应该用POST请求。

《JSP & Servlet学习笔记》的笔记-第130页 - 5.2 应用程序事件、监听器

ServletContext事件、监听器
ServletContextListener与ServletContextAttributeListener
HttpSession事件、监听器
HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener与HttpSessionActivationListener
HttpServletRequest事件、监听器
ServletRequestListener、HttpRequestAttributeListener与AsyncListener

《JSP & Servlet学习笔记》的笔记-第127页 - 5.1.3 使用ServletContext

当整个Web应用程序加载Web容器之后,容器会生成一个ServletContext对象作为整个应用程序的代表,并设置给ServletConfig,只要通过ServletConfig的getServletContext()方法就可以取得ServletContext对象。
1.getRequestDispatcher()
用来取得RequestDispatcher实例,使用时路径的指定必须以“/”作为开头,这个斜杠代表应用程序环境根目录(Context Root)。
context.getRequestDispatcher("/pages/some.jsp").forward(request,response);
2.getResourcePaths()
如果想要知道Web应用程序的某个目录中有哪些文件,则可以使用getResourcePaths()方法。
for(String avatar : getServletContext.getResourcePaths("/")){
//显示avatar文字...
}
使用时指定路径必须以"/"作为开头,表示相对于应用程序环境根目录。
3.getResourceAsStream()
读取Web应用程序中某个文件的内容,使用时指定路径必须以"/"作为开头,表示相对于应用程序环境根目录。运行结果会返回InputStream实例,接着就可以运用它来读取文件内容。

《JSP & Servlet学习笔记》的笔记-第56页 - 3.2.2 请求参数编码处理

1.POST请求参数编码处理
如果客户端没有在Content-Type标头中设置字符编码信息(例如浏览器可以设置Content-Type:text/html;charset=UTF-8),此时使用HttpServletRequest的getCharacterEncoding()返回值会是null。在这个情况下,容器若使用的默认编码处理是ISO-8859-1(大部分浏览器默认的字符集),而客户端使用UTF-8发送非ASCII字符的请求参数,Servlet直接使用getParameter()等方法取得该请求参数值,就会得到乱码。
可以用另一种方式,来简略表示出为什么这个过程会出现乱码。假设网页编码是UTF-8,通过窗体使用POST发出“林”这个中文字符,会将“林”作URL编码为%E6%9E%97再送出,也就是浏览器相当于做了这个操作:
String text = java.net.URLEncoder.encode("林","UTF-8");
在Servlet中取得请求参数时,容器若默认使用ISO-8859-1来处理编码,则相当于做了这个操作:
String text = java.net.URLDecoder.decode("%E6%9E%97","ISO-8859-1");
这样显示出来的中文字符就不正确了。
可以使用HttpServletRequest的setCharacterEncoding()方法指定取得Post请求参数时使用的编码。例如,若浏览器以UTF-8来发送请求,则接收时也使用UTF-8编码字符串,则可以在取得任何请求值之前,执行以下语句:
  req.setCharacterEncoding("UTF-8");
这相当于要求容器做这个操作:
String text = java.net.URLDecoder.decode("%E6%9E%97","UTF-8");
一定要在取得任何请求参数前执行setCharacterEncoding()方法才有作用,在取得请求参数之后,再调用setCharacterEncoding()是没有任何作用的。
2.GET请求参数编码处理
在HttpServletRequest的API文件中,对setCharacterEncoding()的说明清楚提到:Overrides the name of the character encoding used in the body of this request.
  也就是说,这个方法对于请求Body中的字符编码才有作用,也就是基本上这个方法只对Post产生作用,当请求是用get发送时,则没有定义这个方法是否会影响Web容器处理编码的方式(究其原因,是因为处理URL的是HTTP服务器,而非Web容器)。
例如,Tomcat在GET时,使用setCharacterEncoding()方法设置编码就不会有作用,取得请求参数时仍会产生乱码。
若使用Tomcat并采用GET,或没有设置setCharacterEncoding(),且已取得一个请求参数字符串,另外一个处理编码的方式,则是通过String的getBytes()指定编码来取得该字符串的字节数组,然后再重新构造为正确编码的字符串。
例如,若浏览器使用UTF-8处理字符,Web容器默认使用ISO-8859-1编码,则正确处理编码的方式为:
  String name = req.getParameter("name");
  String name = new String (name.getBytes("IS0-8859-1"),"UTF-8");
举例来说,在UTF-8的网页中,对“林”这个字符,若使用窗体发送GET请求,浏览器相当于做了这个操作:
String text = java.net.URLEncoder.encode("林","UTF-8");
在Servlet中取得请求参数时,容器若默认使用ISO-8859-1来处理编码,则相当于做了这个操作:
String text = java.net.URLDecoder.decode("%E6%9E%97","ISO-8859-1");
使用getParameter()取得的字符串就是上例text引用的字符串,可以依下面的编码转换得到正确的“林”字符:
text = new String (name.getBytes("IS0-8859-1"),"UTF-8");

《JSP & Servlet学习笔记》的笔记-第111页 - 4.2.3 HttpSession与URL重写

总而言之,当容器尝试取得HttpSession对象时,无法从Cookie中取得Session ID,使用HttpServletResponse上的encodeURL()就会为产生有Session ID的URL,以便于下次单击超链接时再次发送Session ID。另一个HttpServletResponse上的encodeRedirectURL()方法,则可以在要求浏览器重定向时,在URL上显示Session ID。

《JSP & Servlet学习笔记》的笔记-第214页 - 6.3.1 EL简介

使用${与}来包括所要进行处理的表达式,可使用点运算符(.)指定要存取的属性,使用加号( )运算符进行加法运算。param是EL隐式对象之一,表示用户的请求参数,param.a表示取得用户所发出的请求参数a的值。


 JSP & Servlet学习笔记下载 更多精彩书评


 

外国儿童文学,篆刻,百科,生物科学,科普,初中通用,育儿亲子,美容护肤PDF图书下载,。 零度图书网 

零度图书网 @ 2024