servlet+jsp基础知识三
1、问题
通过servlet01-02的相应案例可以看出,servlet里面
1、有大量的out.println("<html>")等语句
2、每个 servlet里面有大量的连接访问数据库的代码,代码冗余不利于后期维护
采用jsp可以解决以上问题
通过servlet01-02的相应案例可以看出,servlet里面
1、有大量的out.println("<html>")等语句
2、每个 servlet里面有大量的连接访问数据库的代码,代码冗余不利于后期维护
采用jsp可以解决以上问题
2、hey.jsp例子
<%
for (int i=1;i<=10000;i++){
out.print("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然后在将其输出到浏览器上
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
D:\tomcat6\work\Catalina\localhost\org.e2learning.servlet.03\org\apache\jsp
2个文件,其中hey_jsp.java就是tomcat将hey.jsp文件转换成hey_jsp.java
out内建对象,隐含对象
什么叫内建对象,引擎形成的servlet代码的形成的内容方面已经声明了
什么叫内建对象,引擎形成的servlet代码的形成的内容方面已经声明了
SUN相关标准规定:不同服务器的jsp引擎是不一样的,但其生成的的内建对象必须是一样的。
out,response,request
4、如何写一个jsp文件?
先写不变的部分
再写jsp部分
先写不变的部分
再写jsp部分
---------- -----------
| | | 头 |
| jsp | | |
| | | jsp |
| | | 尾 |
---------- ------------
| | | 头 |
| jsp | | |
| | | jsp |
| | | 尾 |
---------- ------------
jsp指令是指挥jsp引擎的,要求其在jsp引擎在生成的servlet代码内加些东西。并不在浏览器中显示。
重要技巧:
<%out.writer(rs.getString(1));%> ====>相当于<%=rs.getString(1)%>
<%=表达式%>======〉<%out.writer(表达式);%>
即便写一个jsp没有<%%>,也要写成jsp
header.jsp文件-----应用最多的是页面的头部分
foot.jsp文件-----页面的尾部分
foot.jsp文件-----页面的尾部分
<%@include file="header.jsp" %>
jsp引擎将jsp文件转换成servlet的时候,一旦读取到上面这一行,则将读取所指定的文件到此,完毕后继续转换。
<input type="button" class="button" value="Add Emp »" onclick="location='emp_form.jsp'"/>
=================
地址栏地址变更为emp_form.jsp
6、要注意的问题:
a、include引入的文件里面定义的变量不能和当前文件定义的变量名相同
否则会出现 550错误,JSP引擎错误
否则会出现 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)
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> </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第一次请求
http响应
Set-Cookies:some_cookie=1000
Set-Cookies:some_cookie=1000
http第二次请求 会通过请求协议头的方式把这个信息带给服务器
cookie:some_cookie=1000;
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);
响应的时候多个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>");
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>");
}
}
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);
通过编码之后再保存 就可以解决以上问题。
如果非要在里面加上=;号时,需要进行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);
这里严格一下都要进行编码
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");
}
%>
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" %>
<%@include file="validate.jsp" %>
14、碰到的问题:
web.xml文件中<servlet-name>saveCookie</servlet-name>
web.xml文件中<servlet-name>savecookie</servlet-name>区别??
15、cookie的年龄
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.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的。
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
输入法是一个强大的搜索引擎