JSP
一、简介
1.动态网页
- 静态与动态的区别:
是否 随着 时间、地点、用户操作 的 改变而改变
动态网页 需要用到 服务端脚本语言(JSP)
2.架构
CS:Client Server
CS不足:
a.如果软件升级,那么所有软件都需要升级
b.维护麻烦
c.每一台客户都需要安装客户端软件
BS:Broswer Server
网页版:京东,百度
客户端可以通过浏览器直接访问服务端
cs和bs各有优点
3.tomcat解压后目录
bin:可执行文件(startup.bat shutdown.bat)
conf:配置文件(server.xml)
lib:tomcat依赖的jar文件
log:日志文件(出错)
temp:临时文件
webapps:可执行的项目(将我们开发的项目放入该目录)
work:存放由jsp翻译成的java,以及编译成的class文件(jsp -> java -> class)
4.配置tomcat
1)配置jdk(必须配置JAVA_HOME)
2)配置catalina_home
状态码:
404:资源不存在
200:一切正常
403:权限不足
3XX:页码重定向(跳转)
500:服务器内部错误(代码有误)
jsp:在html中嵌套
指定首页:
在项目/WEB-INF/web.xml中
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index2.html</welcome-file>
</welcome-file-list>
依次执行,index.html存在时执行,若不存在,执行index2.html
5.虚拟路径
将web项目配置到webapps以外的目录
- 方式1.
在conf/servlet.xml中
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="D:\study\webapps\jspproject" path="/jspproject"/>
</Host>
docBase="" 实际路径
path="" 虚拟路径(绝对路径、相对路径[相对于webapps])
缺点:配置完需要重启
- 方式2 修改后不用重启
在目录D:\java\apache-tomcat-8.5.51\apache-tomcat-8.5.51\conf\Catalina\localhost下
新建文件 项目名.xml
文件中书写:
<Context docBase="D:\study\webapps\jspproject" path="/jspproject"/>
6.虚拟主机[了解]
将localhost改为www.test.com
1)conf/servlet.xml
<Engine name="Catalina" defaultHost="www.test.com">
<Host appBase="D:\java\jspproject" name="www.test.com">
<Context docBase="D:\java\jspproject" path="/" /> </Host>
</Engine>
2)C:\Windows\System32\drivers\etc\hosts
添加:
127.0.0.1 www.test.com
3)D:\java\apache-tomcat-8.5.51\apache-tomcat-8.5.51\conf\server.xml
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
端口号改为80(默认值)
流程:
www.test.com->host找映射关系->server.xml找Engine的defaultHost->通过“/”映射到"D:\java\jspproject"
7.JSP执行流程
第一次访问:jsp-java(servlet文件)-class
位于D:\java\apache-tomcat-8.5.51\apache-tomcat-8.5.51\work\Catalina\localhost\jspproject\org\apache\jsp
第二次访问:直接访问class文件
(如果服务端代码修改了,将会重新翻译和编译)
java文件和servlet文件可以相互转换
二、使用
1.使用eclipse开发Web项目(JSP)
- 在Eclipse中创建的Web项目:
浏览器可以直接访问WebContent中的文件
无法直接访问WEB-INF中的文件,只能通过请求转发来访问
注意:并不是任何的内部跳转都能访问WEB-INF,原因是跳转有2种方式:请求转发 、重定向
- 配置tomcat运行时的环境
1)将tomcat\lib中的servlet-api.jar加入项目的构建路径
E:\java\apache-tomcat-7.0.100\apache-tomcat-7.0.100\lib中的servlet-api.jar
复制到项目中的java resources\src中
右键点击jar文件,选择Build Path->Add to Build Path
2)右键项目->Bulid Path -> Add library-> Server Runtime
- 部署tomcat
在servers面板中,新建一个tomcat实例,
建议:将eclipse和本地tomact相关联,第一次创建tomcat实例之后,双击该实例,勾选Server Location 的第二项
3.统一字符集编码
1)编码分类:
设置jsp文件的编码(jsp文件中的pageEndcoding属性):jsp->java
设置浏览器读物jsp文件的编码(jsp文件中的content属性)
一般将上述设置成一样的编码, 推荐使用UTF-8
文本编码:
①将整个eclipse中的文件统一编码(推荐)
windows->Preferences->搜索JSP Files->Endcoding->UTF-8
只能设置以后的文件,之前已经存在的文件编码不变
②设置某一个项目中的所有文件
右键项目->Resources
③设置单独文件
右键文件->pro…->Resources
4.JSP页面元素
页面元素:HTML,java代码( Scriptlet),指令,注释
-
脚本 Scriptlet
-
<%
局部变量,java代码
%>
-
<%!
全局变量,定义方法
%>
-
<%=输出表达式%>
可以直接解析html语句
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> hello jsp1!你好 <% int count = 0; out.print("nihao"); %> <%! String name; public void init(){ name = "zhangsan"; } %> <%= "nihao" %> </body> </html>
修改web.xml文件、配置文件、java文件 需要重启,
修改jsp/html/css/js代码,不需要重启服务器
jsp回车:
-
-
指令
page指令
<%@ page …%>
page指令的属性:
language:jsp页面使用的脚本语言
import:导入类
pageEncoding:jsp文件自身编码 jsp->java
contentType:浏览器解析jsp的编码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
- 注释
- html: 浏览器查看源码会看到
- java:/* */
- jsp:<%-- --%>
5.JSP九大内置对象(自带的,不需要new也能使用的对象)
out:输出对象,向客户端输出内容
request:请求对象,存储“客户端向服务器发送的请求信息”
response:响应对象
session:会话
application 全局对象
config:配置对象(服务器配置信息)
pageContext:JSP页面容器
page:当前JSP页面对象(相当于java中的this)
exception:异常对象
### request:请求对象,存储“客户端向服务器发送的请求信息”
String getParameter(String name)
:根据名字取值String[] getParameterValues(String name)
:返回字符串数组(checkbox)void setCharacterEncoding("编码格式utf-8")
:设置请求编码(tomcat7以前默认iso-8859-1,tomcat8以后默认utf-8)getRequestDispatcher("b.jsp").forward(request,response)
:请求转发的方式跳转页面 A->BgetServerContext()
:获取项目的ServletContext对象- 示例:注册 register.jsp show.jsp
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="show.jsp" method="post">
用户名:<input type="text" name="uname"><br/>
密码:<input type="password" name="upwd"><br/>
年龄:<input type="text" name="uage"><br/>
爱好:<br/>
<input type="checkbox" name="uhobbies" value="足球">足球<br/>
<input type="checkbox" name="uhobbies" value="篮球">篮球<br/>
<input type="checkbox" name="uhobbies" value="乒乓球">乒乓球<br/>
<input type="submit" value="注册">
</form>
</body>
</html>
show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("uname");
int age = Integer.parseInt(request.getParameter("uage"));
String password = request.getParameter("upwd");
String[] hobbies = request.getParameterValues("uhobbies");
%>
恭喜你,注册成功,信息如下:<br/>
姓名:<%=name %><br/>
年龄:<%=age %><br/>
密码:<%=password %><br/>
爱好:<br/>
<%
for(String hobby : hobbies){
out.print(hobby+" ");
}
%>
</body>
</html>
文件上传必须是post方式
统一请求的编码:
GET方式:
1)统一每一个变量的编码 new String(旧编码,新编码)
new String(name.getBytes("iso-8859-1"),"utf-8");
2)修改server.xml
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
POST方式:
request.setCharacterEncoding("UTF-8");
response:响应对象
-
void addCookie(Cookie cookie)
:服务端向客户端增加cookie对象void sendRedirect(String location) throws IOException
:页面跳转的一种方式(重定向) -
void setContentType(String type)
:设置服务端响应的编码(设置服务端的contentType类型) -
跳转页面两种方式 示例:登录
- login.jsp->check.jsp->success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="check.jsp">
用户名:<input type="text" name="uname"><br/>
密码:<input type="password" name="upwd"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("uname");
String password = request.getParameter("upwd");
if(name.equals("zs")&& password.equals("abc")){
//登录成功
//方式一:
//response.sendRedirect("success.jsp");//数据丢失
//方式二:保留数据,且地址栏地址不变,仍在当前位置
request.getRequestDispatcher("success.jsp").forward(request, response);
}else{
//登录失败
out.print("用户名或密码错误");
}
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("uname");
out.print("欢迎您:"+name);
%>
</body>
</html>
请求转发 | 重定向 | |
---|---|---|
地址栏是否改变 | 不变(check.jsp) | 改变(success.jsp) |
是否保留第一次请求时的数据 | 保留 | 不保留 |
请求的次数 | 1 | 2 |
跳转发生的位置 | 服务端 | 客户端发出的第二次跳转 |
转发、重定向:
转发:
张三(客户端) -> 【服务窗口A(服务端) -> 服务窗口B】
重定向:
张三(客户端) -> 服务窗口A(服务端) -> 去找B
张三(客户端) -> 服务窗口B
session(服务端):
- Cookie(客户端,不是内置对象) :Cookie是由服务端生成的,在发送给客户端保存
-
相当于本地缓存的作用
-
安全性较差
-
提高访问服务端的效率
-
key=value
-
java.servlet.http.Cookie
-
public Cookie(String name,String value)
-
String getName()
-
String getValue()
-
void setMaxAge(int expiry):设置最大有效期(秒)
-
服务端准备cookie:response.addCookie(Cookie cookie)
-
页面跳转,客户端获取cookie:request.getCookies();
-
1)服务端直接增加cookie:response对象,客户端获取对象:request对象
-
2)不能直接获取某一个单独对象,只能一次性将全部cookie拿到
-
除了自己设置的Cookie对象外,还有一个JSESSIOND的cookie
-
示例
-
requestDemo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% Cookie cookie = new Cookie("name","zs"); Cookie cookie1 = new Cookie("password","abc"); response.addCookie(cookie); response.addCookie(cookie1); request.getRequestDispatcher("result.jsp").forward(request, response); %> </body> </html>
result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% Cookie[] cookies = request.getCookies(); for(Cookie cookie:cookies){ out.print(cookie.getName()+"->"+cookie.getValue()+"<br/>"); } %> </body> </html>
-
经典案例:使用cookie自动记住登录名
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%! String uname; %> <% Cookie[] cookies = request.getCookies(); for(Cookie cookie:cookies) if("cname".equals(cookie.getName())){ uname = cookie.getValue(); } %> <form action="check.jsp"> 用户名:<input type="text" name="uname" value="<%=(uname==null?"":uname)%>"> 密码:<input type="password" name="upwd"> <input type="submit" value="登录"> </form> </body> </html>
check.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% String name = request.getParameter("uname"); String password = request.getParameter("upwd"); Cookie cookie = new Cookie("cname",name); response.addCookie(cookie); out.print("登录成功"); response.sendRedirect("A.jsp"); %> </body> </html>
A.jsp
为空
-
- session:会话
-
例子:
- 浏览网站:开始-关闭
- 购物:浏览、付款、退出
- 电子邮件:浏览、写邮件、退出
-
开始 - 结束
- 机制:
- sessionID复制一份为JSESSIONID,session与sessionID一一对应
- 客户端第一次请求服务端时,服务端会产生一个session对象(用于保存该用户的信息),并且每个session对象都有一个唯一的sessionID(用于区分其他session),服务端会产生一个cookie,并且该cookie的name=JSESSIONID,value=服务端sessionID的值,然后服务端在响应客户端的同时,将该cookie发送给客户端,至此,客户端就有了一个cookie(JSESSIONID)
- session存储在服务端
- session在同一个客户请求时共享
- 实现机制:第一次客户请求时产生一个session并复制给cookie中的JSESSIONID,然后发送给客户端,最终通过sessionID和JSEESIONID实现一一对应关系
- 方法
String getId()
:获取session的IDboolean isNew()
:是否是新用户(第一次访问)
void invalidate()
:使session失效(退出登录,注销)void setAttribute()
:设置属性
Object getAttribute()
:获取属性void setMaxInactiveInterval(秒)
:设置最大有效 非活动时间
int getMaxInactiveInterval()
:获取最大有效非活动时间- 示例:登录
- login.jsp不变
- check.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("uname");
String password = request.getParameter("upwd");
if(name.equals("zs")&& password.equals("abc")){
//登录成功
//方式一:
//response.sendRedirect("success.jsp");//数据丢失
//方式二:保留数据,且地址栏地址不变,仍在当前位置
session.setAttribute("uname", name);
session.setAttribute("upwd", password);
request.getRequestDispatcher("welcome.jsp").forward(request, response);
}else{
//登录失败
out.print("用户名或密码错误");
response.sendRedirect("login.jsp");
}
%>
</body>
</html>
welcome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
欢迎您:
<%
String name = (String)session.getAttribute("uname");
if("null".equals(name)){
request.getRequestDispatcher("login.jsp").forward(request, response);
}
out.print(name);
%>
<a href="invalidate.jsp">注销</a>
</body>
</html>
invalidate.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
session.invalidate();
response.sendRedirect("login.jsp");
%>
</body>
</html>
区别 | session | cookie |
---|---|---|
保存的位置 | 服务端 | 客户端 |
安全性 | 较安全 | 较不安全 |
保存的内容 | Object | String |
客户端在第一次请求服务端时,如果服务端发现没有JSESSIONID,则会创建一个拥有JSESSIONID的cookie并返回客户端
cookie:
1.不是内置对象,要使用必须new
2.但是,服务端会自动new一个name=JSESSIONID的cookie并返回给客户端
application 全局对象
String getContextPath()
:虚拟路径String getRealPath(String contextPath)
:绝对路径
四种范围对象(小->大)
pageContext:JSP页面容器(又名:page对象):当前页面有效
request:请求对象 同一次请求有效 请求转发有效,重定向无效
session:会话对象 同一次会话有效 无论怎么跳转都有效,重开浏览器无效
application:全局对象 全局有效(整个项目有效) 切换浏览器仍然有效 关闭读物、其他项目 无效
->多个项目共享:JNDI
共有方法:
Object getAttribute(String name)
;根据属性名,获取属性值
void setAttribute(String name,Object obj)
;设置属性值(新增,修改)
void setAttribute("a","b")
;//如果a对象之前不存在,则新建一个a对象,如果存在,修改
void removeAttribute(String name)
;根据属性名,删除对象
1.以上四个范围对象,通过getAttribute赋值,通过getAttribute取值
2.尽量使用范围小的范围对象,范围越大,系统开销越大