servlet+jsp基础知识三

13年前
1、问题
通过servlet01-02的相应案例可以看出,servlet里面
1、有大量的out.println("<html>")等语句
2、每个 servlet里面有大量的连接访问数据库的代码,代码冗余不利于后期维护
采用jsp可以解决以上问题
2、hey.jsp例子
<%
 for (int i=1;i<=10000;i++){
  out.print("JSP");
 }
%>

3、通过例子来理解JSP、内建对象、JSP引擎
理解:
 实际上 JSP也是servlet,是一路货,是同样的东西
 访问这个JSP实际上也是访问servlet
 当我们用浏览器访问JSP的时候,tomcat服务器要首先要把这个jsp文件读取了,并把它转换成servlet
 实际上我们访问的就是这个转换后的servlet
servlet与Jsp原理是一样的,只是jsp的效率稍微高些
 
 Tomcat服务器是怎么把它转换成servlet的呢?通过jsp引擎来进行转换
 其中 JSP引擎是Tomcat里面的一个小程序,用来将用户写的JSP转换成指定的servlet,然后再输出到浏览器
 
 
 访问一个 html页面和访问一个jsp是不一样的
  访问一个html页面,服务器只是简单做个响应
  访问一个jsp时,首先要将jsp转换成servlet然后在将其输出到浏览器上
   第一次运行比较慢,首先要将jsp转换成servlet。
   下一次运行时不需要转化,直接运行调用即可。
 
 
比如看
D:\tomcat6\work\Catalina\localhost\org.e2learning.servlet.03\org\apache\jsp
2个文件,其中hey_jsp.java就是tomcat将hey.jsp文件转换成hey_jsp.java
 
out内建对象,隐含对象
什么叫内建对象,引擎形成的servlet代码的形成的内容方面已经声明了
SUN相关标准规定:不同服务器的jsp引擎是不一样的,但其生成的的内建对象必须是一样的。
out,response,request
4、如何写一个jsp文件?
 先写不变的部分
 再写jsp部分
----------       -----------
|         |      |  头      |
| jsp     |      |          |      
|         |      |   jsp    |
|         |      |   尾     |
----------       ------------
 

5、什么是 JSP指令?
jsp指令<%@page import ="java.sql.*" %>
      ========这是数据库的类库, 如果再有一个的话,用,隔开
jsp指令是指挥jsp引擎的,要求其在jsp引擎在生成的servlet代码内加些东西。并不在浏览器中显示。

重要技巧:
<%out.writer(rs.getString(1));%> ====>相当于<%=rs.getString(1)%>
<%=表达式%>======〉<%out.writer(表达式);%>
 
即便写一个jsp没有<%%>,也要写成jsp
header.jsp文件-----应用最多的是页面的头部分
foot.jsp文件-----页面的尾部分
<%@include file="header.jsp" %>
jsp引擎将jsp文件转换成servlet的时候,一旦读取到上面这一行,则将读取所指定的文件到此,完毕后继续转换。

<input type="button" class="button" value="Add Emp &raquo;" onclick="location='emp_form.jsp'"/>
                   =================
                   地址栏地址变更为emp_form.jsp
  
6、要注意的问题:
 a、include引入的文件里面定义的变量不能和当前文件定义的变量名相同
 否则会出现 550错误,JSP引擎错误
 b、<%page import="java.sql.*"%>   以下错误信息是由于import后面的java.sql.*没引起来
 org.apache.jasper.JasperException: /emp_list.jsp(1,17) quote symbol expected
 at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
 at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
 at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:88)
 at org.apache.jasper.compiler.Parser.parseAttribute(Parser.java:198)
 at org.apache.jasper.compiler.Parser.parseAttributes(Parser.java:148)
 at org.apache.jasper.compiler.Parser.parseAttributes(Parser.java:160)
 at org.apache.jasper.compiler.ParserController.getPageEncodingForJspSyntax(ParserController.java:490)
 at org.apache.jasper.compiler.ParserController.determineSyntaxAndEncoding(ParserController.java:431)
 at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:207)
 at org.apache.jasper.compiler.ParserController.parseDirectives(ParserController.java:120)
 at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:180)
 c、以下代表单元格内容为空格<td>&nbsp;</td>

7、
<%out.write("<a href='emp_formb.jsp'>addEmp</a>"); %>
<input type="button" class="button" value="add EMP" onclick="location='emp_listb.jsp'"/>

8、cookies理解
                    
cookies
浏览器第一次访问服务器的时候,服务器在响应的时候,让浏览器把一部分小的数据带回去,这部分小的数据就是cookies
比如坐车,坐10次送1次;这个老板应该做什么呢?
方式:
1\服务器卡
2\每人发个卡  cookies
给每人发一个卡,来一次填写一个卡
用servlet和jsp写cookies是一样的。

9、servlet中cookies,通过sniffer抓包分析
servlet中加上有以下代码:
  Cookie cookie=new Cookie("some_cookie","1000");//用来封装cookies信息
  response.addCookie(cookie);//通过响应来添加cookies;response.addCookie()
通过客户端访问servlet时:
 http第一次请求
 http响应
  Set-Cookies:some_cookie=1000
 http第二次请求  会通过请求协议头的方式把这个信息带给服务器
  cookie:some_cookie=1000;
  一次请求可以带n个cookie
  响应的时候多个set-cookie
  
  // 用来封装Cookie的信息
  //名字和值都是字符串
  
  
10、写 cookie:response  
  String value1 = URLEncoder.encode("1+1=2", "utf-8");
  String value2 = URLEncoder.encode("两千", "utf-8");
  Cookie cookie1 = new Cookie("some_cookie", value1);
  Cookie cookie2 = new Cookie("other_cookie", value2);
  // 生成响应头中的set-cookie项
  
  //  0 马上删除
  //  <0 浏览器关闭即删除
  //  >0 秒数
  cookie1.setMaxAge(60);
  
  response.addCookie(cookie1);
  response.addCookie(cookie2);
  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  out.println("<HTML>");
  out.println("<HEAD><TITLE>A Servlet</TITLE></HEAD>");
  out.println("<BODY>");
  out.println("<h1>Add Cookie</h1>");
  out.println("</BODY>");
  out.println("</HTML>");

11、得到cookie    :request
  getcookies
 response.setContentType("text/html;charset=utf-8");
  PrintWriter out = response.getWriter();
  // 如果请求协议头中没有cookie,则返回null
  //由于cookies返回的可能不是一个,所以是以数组
  Cookie[] cookies = request.getCookies();
  if (cookies != null) {
   for (int i = 0; i < cookies.length; i++) {
    Cookie cookie = cookies[i];
    //显示在控制台上看下
     System.out.println();
    
    out.println("<h1>" + cookie.getName() + ": "
      + URLDecoder.decode(cookie.getValue(),"utf-8") + "</h1>");
   }
  }
12、cookies的编码问题
存储cookies的时候,其字符串不能包含 "= ;",尽量不要写太复杂。(主要是协议头里面包含=号和;号)
如果非要在里面加上=;号时,需要进行URLEncode的编码
比如说 
  String value1 = URLEncoder.encode("1+1=2", "utf-8");
  String value2 = URLEncoder.encode("两千", "utf-8");
  Cookie cookie1 = new Cookie("some_cookie", value1);
  Cookie cookie2 = new Cookie("other_cookie", value2);
  通过编码之后再保存 就可以解决以上问题。

    out.println("<h1>" + cookie.getName() + ": "
      + URLDecoder.decode(cookie.getValue(),"utf-8") + "</h1>");

13、假设一个论坛需要登录注册模块
要求:必须是我们数据库里面的用户才能登陆,否则不能登陆
我们用什么办法检测过,这个用户登录过
 避免:只是设置了个门口,而没用设置墙
 if(num==1) {
  -------
  最好加上下面cookies代码
   -------
   response.sendRedirect("emp_list.jsp");
  } else {
   response.sendRedirect("login_form.jsp");
  }
 可以采用这种方式,如果成功登陆了,则会返回一个cookies,当再次访问的时候可以带一个cookies上来。
   cookies代码
   Cookie cookie = new Cookie("user_key",name);
   //cookie.addMaxAge(60);
   response.addCookie(cookie);
  这里严格一下都要进行编码
新建一个validate.jsp页面,通过include导入到其他页面,来进行信息的验证
validate.jsp
<%
 Cookie[] cookies = request.getCookies();
 boolean b = false;
 if (cookies != null) {
  for (int i = 0; i < cookies.length; i++) {
   if ("user_key".equals(cookies[i].getName())
     && cookies[i].getValue() != null
     && cookies[i].getValue().length() > 0) {
    b = true;
    break;
   }
  }
 }
 if (!b) {
  response.sendRedirect("login_form.jsp");
 }
%>
 
需要在登陆之后才能看到的jsp文件前面加上
<%@include file="validate.jsp" %>
14、碰到的问题:
 
 
 web.xml文件中<servlet-name>saveCookie</servlet-name>
 web.xml文件中<servlet-name>savecookie</servlet-name>区别??
 
15、cookie的年龄
cookie默认是有年龄的,一关浏览器就自动删除了。
cookie.setMaxAge(60);//设置cookie年龄为多少秒?
  
  //  0 马上删除
  //  <0 浏览器关闭即删除(默认)
  //  >0 秒数
 
 
 
 
validate.jsp
<%
 Cookie[] cookies = request.getCookies();
 boolean b = false;
 if (cookies != null) {
  for (int i = 0; i < cookies.length; i++) {
   if ("user_key".equals(cookies[i].getName())
     && cookies[i].getValue() != null
     && cookies[i].getValue().length() > 0) {
    b = true;
    break;
   }
  }
 }
 if (!b) {
  response.sendRedirect("login_form.jsp");
 }
%> 
这个代码是有bug的。
只要Cookie:user_key=1000;即可
       =====
原因就是cookie是让人拿回家的,用户如果了解原理就可以修改这个cookie。

登陆安全级别相对来说比较高的话,session比cookie要安全点,但是并不是完美安全
一个cookie不能超过4k
输入法是一个强大的搜索引擎