0%

JSP入门笔记

JSP入门笔记


静态与动态

不要和是否有“动感”混为一谈 是否随着时间、地点、用户操作 的改变而改变 动态网页 需要使用到 服务端脚本语言(JSP)

BS与CS架构

CS:Client Server 客户端与服务端 eg:QQ、微信
不足:

  1. 如果软件升级,那么所有软件都需要升级
  2. 维护麻烦,需要维护每一台客户端软件
  3. 每一台客户端都需要安装客户端软件

BS:Broswer Server 浏览器服务器 eg:网页版京东、百度 客户端可以通过浏览器直接访问浏览器

注:CS与BS各有优劣

tomcat解压后目录

bin:存放可执行文件(startup.bat shutdown.bat...)
conf:存放配置文件(server.xml) lib:存放tomcat依赖jar包 log:存放日志文件(记录出错等信息) temp:存放临时文件 webapps:存放可执行的项目(将我们开发的项目 放入该目录) work:存放由jsp翻译成的java,以及编译成的class文件

配置tomcat

  1. 配置jdk(必须配置JAVA_HOME) JAVA_HOME CLASSPATH PATH
  2. 配置catalina_home(值为根目录)

常见错误:可能与其他服务端口冲突,可关闭冲突服务或修改tomcat端口(在server.xml)

访问tomcat

http://localhost:8080
默认访问root中的index.jsp
可在web.xml中修改

1
2
3
4
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index2.html</welcome-file>
</welcome-file-list>

常见状态码:
200:一切正常
300/301:页面重定向(跳转)
404:资源不存在
403:权限不足(如果访问a目录,但a目录设置不可见)
500:服务器内部错误(代码有误)

jsp:在html中嵌套的Java代码

虚拟路径

方式一:
将web项目配置到webapps以外的目录 在conf/server.xml中的中添加
docBase:实际路径 path:虚拟路径 (绝对路径、相对路径(相对于webapps))

方式二:
在conf/Catalina/中新建.xml(与项目同名),内容也为

虚拟主机(一般不用)

通过www.test.com访问主机

在conf/server.xml中增加一个

1
2
3
<Host appBase="webapps" name="www.test.com">
<Context docBase="webapps" path="/" />
</Host>

修改中的defaultHost="www.test.com"

在hosts文件添加 127.0.0.1 www.test.com

端口改为80

流程:www.test.com->host找映射关系->server.xml找Engine的defaultHost->通过"/"映射到硬盘

JSP执行流程

第一次访问:服务端将JSP翻译成java,再将java编译成class文件(比较慢)

后续访问:直接访问class文件(如果服务端代码修改,将会重新编译)(比较快)

JSP和Servlet可以相互转换

统一字符集编码

  1. 编码分类:

    设置jsp文件的编码(jsp文件中的pageEncoding属性):jsp->java

    设置浏览器读取jsp文件的编码(jsp中的content属性)

    一般将上述设置成一致的编码,推荐使用UTF-8

  2. 文本编码:

    a.将IDE所有文件统一设置(推荐)

    b.设置某一项目

    c.设置单独文件

JSP的页面元素

a.脚本Scriptlet(三种代码)

1
<%	局部变量、java语句	%>
1
<%!	全局变量、定义方法	%>
1
<%= 输出表达式%>

一般而言,修改web.xml、配置文件、java、需要重启tomcat服务,但是如果修改Jsp、html、css、js,不需要重启

注意:out.println()不能回车,要想加回车,必须用

b.指令

page指令:<%@ page ...%>

page指令的属性:

language:jsp页面使用的脚本语言

import:导入类

pageEncoding:jsp文件自身编码 jsp->java

contentType:浏览器解析jsp的编码

  1. 注释

html注释 : 可以被客户通过浏览器查看源码看到

java注释:// / * .... * /

jsp注释:<%-- ....... --%>

JSP九大内置对象(自带的,不需要new也能用的对象)

out:输出对象,向客户端输出内容

request:请求对象;存储”客户端向服务端发送的请求信息“

常见方法:

String getParameter(String name) :根据请求的字段名key(标签的name属性),返回字段值value

String[] getParameterValues(String name):根据请求的字段名key,返回多个字段值value,(checkbox多选按钮)

void setCharacterEncoding("编码格式utf-8..."):设置请求编码 默认tomcat7以前iso-8859-1,tomcat8以后utf-8

getRequestDispatcher("目的页面").forward(request,response):请求转发的方式跳转页面

getServerContext():获取项目的ServletContext对象

示例:注册页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Register</title>
</head>
<body>
<form action="show.jsp">
用户名:<input type="text" name="uname" /><br/>
密码:<input type="password" name="upwd"/><br/>
年龄:<input type="text" name="uage"/><br/>
爱好:
<input type="checkbox" name="uhobbies" value="足球"/>足球
<input type="checkbox" name="uhobbies" value="篮球"/>篮球
<input type="checkbox" name="uhobbies" value="排球"/>排球
<br/>
<input type="submit" value="注册">
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Show</title>
</head>
<body>
<%
//设置编码
request.setCharacterEncoding("utf-8");
//根据name取value
String name=request.getParameter("uname");
int age = Integer.valueOf(request.getParameter("uage"));
String pwd = request.getParameter("upwd");
String[] hobbies = request.getParameterValues("uhobbies");

%>
注册成功,信息如下:<br/>
姓名:<%=name%><br/>
年龄:<%=age%><br/>
密码:<%=pwd%><br/>
爱好:
<%
for (String hobby:hobbies)
out.print(hobby);
%>
</body>
</html>

response:响应对象

常见方法:

void addCookie(Cookie cookie):服务端向客户端增加cookie对象

void sendRedirect(String location):页面跳转的一种方式(重定向)

void setContentType(String type):设置服务端响应编码(设置服务端的contentType类型)

示例:登录 login.jsp->check.jsp->success.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="check.jsp" method="post">
用户名:<input type="text" name="uname"><br/>
密码:<input type="password" name="upwd"><br/>
<input type="submit" value="登陆"><br/>
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Check</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
if(uname.equals("张三")&&upwd.equals("123456")){
// 重定向 会导致数据丢失
//response.sendRedirect("success.jsp");
// 请求转发 可以获取到数据,并且地址栏没有改变(仍然保留转发时的地址)
request.getRequestDispatcher("success.jsp").forward(request,response);
}else{
out.print("用户名或密码有误");
}
%>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Success</title>
</head>
<body>
登陆成功<br/>
欢迎你!<%=request.getParameter("uname")%>
</body>
</html>

请求转发与重定向的区别:

请求转发 重定向
地址栏是否改变 不变(check.jsp) 改变(success.jsp)
是否保留第一次请求时的数据 保留 不保留
请求的次数 1 2
跳转发生的位置 服务端 客户端发出第二次跳转

session(服务端)

Cookie(客户端,不是内置对象):Cookie是由服务端产生的,再发送给客户端保存,相当于本地缓存的作用:客户端->服务端,能提高访问服务端的效率,但是安全性较差

Cookie:key-value

public Cookie(String key,String value):构造方法

String getName():获取name

String getValue():获取value

void setMaxAge(int expiry):设置最大有效期(单位:秒)

服务端准备Cookie:

response.addCookie(Cookie cookie)

页面跳转(转发/重定向)

客户端获取cookie:request.getCookies()

注:服务端增加cookie:response对象;客户端获取对象 :request对象

​ 不能直接获取某一个单独cookie对象,只能一次性将全部的cookie拿到再遍历

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>addCookie</title>
</head>
<body>
<%
//服务端
Cookie cookie = new Cookie("name","张三");
Cookie cookie1 = new Cookie("pwd","123456");
response.addCookie(cookie);
response.addCookie(cookie1);
//页面跳转到客户端(转发、重定向)
response.sendRedirect("result.jsp");
%>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>result</title>
</head>
<body>
<%
//客户端 获取cookies
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies){
out.print(cookie.getName()+"---"+cookie.getValue()+"<br/>");
}
%>
</body>
</html>

通过检查可以发现,除了自己设置的Cookie对象外,还有一个name为JSESSIONID的cookie

建议:cookie只保存 英文和数字,否则需要进行编码、解码

案例:使用Cookie实现记住用户名的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>

<%!
String uname;
%>
<%
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies){
if(cookie.getName().equals("name")){
uname = cookie.getValue();
}
}
%>

<form action="check.jsp" method="post">
用户名:<input type="text" name="uname" value="<%=(uname==null?"":uname)%>"><br/>
密码:<input type="password" name="upwd"><br/>
<input type="submit" value="登陆"><br/>
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Check</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");
//将用户名与密码加入cookie
Cookie cookie = new Cookie("name",name);
//Cookie cookie1 = new Cookie("pwd",pwd);
response.addCookie(cookie);
//服务端将cookie发回给客户端保存 A.jsp属于客户端
response.sendRedirect("A.jsp");
%>
</body>
</html>

session:会话

  1. 浏览网站:从开始到关闭

  2. 购物:浏览、付款、退出

  3. 电子邮件:浏览、写邮件、退出

运行机制:

浏览器客户端第一次请求服务端时,(JSESSIONID与SESSIONID匹配失败)服务端会产生一个session对象(用于保存该客户的信息),并且每个session对象,都会有一个唯一的SESSIONID(用于区分其它session)服务端会产生一个cookie,并且该cookie的name=JSESSIONID,value=服务端SESSIONID的值,然后服务端会在响应客户端的同时,将该cookie发送给客户端,至此,客户端就有了一个cookie(JSESSIONID);因此,客户端的cookie就可以和服务端的SESSIONID一一对应(JSESSIONID-SESSIONID),从而保证每个用户一个session。

客户端第2/n次请求,服务端会先用客户端cookie中的JSESSIONID,去服务端session中匹配SESSIONID,如果匹配成功(cookie JSESSIONID和session SESSIONID),说明此用户不是第一次访问,

session:

  1. session存储在服务端

  2. session是在同一个客户请求时共享的

  3. 实现机制:第一次请求时,产生一个SESSIONID并复制给cookie的JSESSIONID然后发送给客户端。最终通过session的SESSIONID和cookie的JSESSIONID

session方法:

String getId():获取SESSIONID

boolean isNew():判断是否是新用户(第一次访问)

void invalidate():使session失效(退出登录、注销)

setAttribute()

getAttribute()

void setMaxInactiveInterval(秒):设置最大有效非活动时间

int getMaxInactiveInterval():获取最大有效非活动时间

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Check</title>
</head>
<body>
<%
//login.jsp 与之前的相同
request.setCharacterEncoding("utf-8");
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");

if(name.equals("zs")&&pwd.equals("123")){
session.setAttribute("uname",name);
session.setAttribute("upwd",pwd);
//设置最大非活动时间
session.setMaxInactiveInterval(10);
//request数据只在同一次请求有效
//地址栏回车(发出第二次请求)
//如果F5刷新,浏览器提示重新提交表单,相当于重复之前的登录,建立请求
request.getRequestDispatcher("welcome.jsp").forward(request,response);
}else{
response.sendRedirect("login.jsp");
}


%>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>welcome</title>
</head>
<body>
welcome
<%
String name= (String) session.getAttribute("uname");
//如果用户没有登录,而是直接通过地址栏访问welcome.jsp,即name为null,
//则跳转到login.jsp
if(name==null){
response.sendRedirect("login.jsp");
}else{
out.print(name);
}
%>
<a href="invalidate.jsp">注销</a>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>invalidate</title>
</head>
<body>
<%
session.invalidate();//ssesion失效
response.sendRedirect("login.jsp");
%>
</body>
</html>
session cookie
保存的位置 服务端 客户端
安全性 较安全 较不安全
保存的内容 Object String

pageContext:JSP页面容器

application:全局对象

常用方法:

String getContextPath():获取虚拟路径

String getRealPath(“虚拟路径”):获取绝对路径(虚拟路径相对的绝对路径)

用的较少:

config:配置对象(服务器配置信息)

page:当前JSP页面对象(相当于java中的this)

exception:异常对象

四种范围对象(从小到大)

pageContext JSP页面容器 (page对象) 当前页面有效

request 请求对象 同一次请求有效

session 会话对象 同一次会话有效

application 全局对象 全局有效(整个项目有效,即使切换了浏览器)

都有一些共同的方法:

Object getAttribute(String name):根据属性名,获取属性值

void setAttribute(String name,Object obj):设置属性值(新增/修改)

eg:setAttribute("a","b");//如果a对象不存在,则新建,否则将a的值改为b

void removeAttribute(String name):根据属性名,删除对象

以上范围对象使用时,尽量使用最小的范围。因为对象的范围越大,造成的性能损耗越多。