Javaweb
1、Tomcat
1.作用:客户端向服务器发送请求,实际上就是发给服务器上安装的Tomcat这样的服务器程序,Tomcat负责监听是否有请求,监听到有请求,Tomcat会负责后续一系列的工作。
2.安装:直接将tomcat压缩包解压到某个位置即可,一般将jdk,idea,tomcat,mysql等相关软件,全都放在一个文件夹中,好管理,比如d:\java。
3.Tomcat目录:
bin:Tomcat应用程序所在目录,比如启动、停止服务的程序(startup.bat shutdow.bat)
conf:保存服务器的配置文件(server.xml)
lib:tomcat依赖的jar文件
log:日志文件(记录出错等信息)
temp:临时文件
webapps:可执行的项目(将我们开发的项目放入目录)
work:存放由jsp翻译成的java,以及编译成的class文件(jsp->java->class)
4.tomcat端口号配置:
8080是tomcat的默认端口号,计算机中运行的程序都有编号叫端口号,计算机系统内部是认端口号的,不认程序名称
conf目录下面server.xml文件中
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改port值即可,注意:修改后要重启tomcat才起作用。
5.访问tomcat:
http://localhost:8080/
Localhost代表你正在使用的机器,也可用127.0.0.1
常见状态码:
200:一切正常
300/301:页面重定向(跳转)
404:资源不存在
403:权限不足(如果访问a目录,但是a目录设置不可见)
500:服务器内部错误(代码有误)
其他编码:积累
6.idea软件部署:将idea开发的项目拷贝到tomcat相应文件夹中,tomcat才能管理执行。
2、JSP
动态网页需要使用到服务端脚本语言(JSP)
1.jsp:在html中嵌套的java代码
在项目/WEB-INF/web.xml中设置默认的初始页面
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
2.jsp执行流程:
(1)jsp-java(servlet文件)-class
(2)jsp和servlet可以相互转换
(3)因为第一次请求服务端会有翻译和编译的过程,因此比较慢;后续访问
可以直接访问class,因此速度较快。但是如果服务端修改了代码,则再
次访问时会重新翻译、编译。
3.jsp的页面元素:HTML、java代码(脚本Scriptlet)、指令、注释
(1)脚本Scriptlet
1)
<%
局部变量、java语句
%>
2)
<%!
全局变量、定义方法
%>
3)
<%=输出表达式%> 注意:1:单独写小脚本 2:语句末尾没有分号
一般而言,修改web.xml、配置文件、java,需要重启tomcat服务
但是如果修改jsp\html\css\js ,不需要重启
注意:out.println()不能换行,要想换行:"<br/>",即out.print() <%=%>可以直接解析html代码
(2)指令
page指令
<%@page...%>
page指令的属性:
language属性:使用的语言,该属性可以不给,jsp默认就是java
import属性:导包,可以单独形成import指令,也可以放到一起,用逗号分隔。
contentType:指定传给客户端的内容格式和编码方式
pageEncoding:jsp内部编码方式(保存当前jsp文件时的编码格式)
(3)注释
html注释<!-- --> 可以被客户通过浏览器查看源码所观察到
java注释// /*...*/
jsp注释<%-- --%>
4.jsp内置九大对象(自带的,不需要new也能使用的对象)
(1)request:请求对象,存储“客户端向服务端发送的请求信息”
request对象的常见方法:
1)String getParameter(String name):根据请求的字段名key,返回字段值value
2)String[] getParameterValues(String hobby):根据请求的字段名key,返回字段值value例如:复选框、下拉列表框等(checkbox)
3)void setCharacterEncoding("编码格式utf-8"):设置请求编码(tomcat7以前默认iso-8859-1,tomcat8以后改为了utf-8)
例如:request.setCharacterEncoding("utf-8"); //只能解决post方式的编码问题
4)getRequestDispatcher().forward(request,response); :请求转发的方式跳转页面 A->B
5)ServletContext getServerContext() :获取项目的ServletContext对象
案例:注册(zhuce)
知识点1:get提交方式:method=”get”和地址栏、超链接(<a href=”xx”>)请求方式默认都属于get提交方式
知识点2:get和post的特点:
(1)get:地址栏能看到数据,相对不安全,不能传大数据,post:相对安全,可传大数据
(2)文件上传操作,必须是post
(3)推荐使用:post
知识点3:Get方式乱码问题(tomcat8以后没有get乱码问题)
method=”post”设置request.setCharacterEncoding("utf-8");可解决,但method=”get”方式依然乱码,解决方法为:
修改Web容器(Tomcat)的配置解决get的乱码问题 (TomCat的conf目录中server.xml文件中更改,添加URIEncoding="UTF-8"即可)
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
(2)response:响应对象,存储“服务端向客户端发送的请求信息”
提供的方法:
1)void addCookie(Cookie cookie) :服务端向客户端增加cookie对象
2)void sendRedirect(String location) throw IOException :重定向(页面跳转的一种方式)
3)void setContentType(String type) :设置服务端响应的编码(设置服务端contentType类型)
案例:登录(denglu-login)
知识点1: 请求转发 重定向
地址栏是否变化 不变 改变
是否保留第一次
请求时的数据 保留 不保留
请求的次数 1 2
跳转发送的位置 服务端 客户端发出第二次跳转
知识点2:重定向和转发
重定向:response.sendRedirect(),作用是让客户端重定向,即客户端重新发送请求,request对象为新的,即原来request中数据丢失,地址栏地址发生变化。
转发:request.getRequestDispatcher("welcome.jsp").forword(request,response);
转发是服务器内部重定向,没有发送新的请求,故request中数据不丢失,由于是服务器内部完成定向,故客户端地址栏不会发生变化
重点:☆☆☆☆☆
重定向产生新的request对象,地址栏变化
转发不产生新的request对象,地址栏不变化
知识点3:什么情况产生新的request?
只要客户端向服务器端发送请求,都会产生新的request
知识点4:发送请求的场合:1:地址栏输入地址后回车,2:表单提交,3:get提交,例如超链接:<a href=”localhost:8080/index.jsp”>超链接</>
知识点5:转发是服务器内部完成的重定向,客户端不知道故地址栏不变,代码是固定写法request.getRequestDispatcher("welcome.jsp").forword(request,response);,只是页面名称发生变化
(3)session(服务端):会话
1)举例:a.浏览网站:开始-关闭
b.购物:浏览、付款、退出
c.电子邮件:浏览、写邮件、退出
开始-结束
2) 一个会话共用一个session
(1) 会话开始:一个用户访问一个网站就会开启一次会话
(2)会话结束:a:用户用一个浏览器访问网站,开始会话,当该浏览器下访问该 网站的页面全部关闭,则会话结束
b:打开一个页面,长时间不操作,会话会自动关闭,默认30分钟自动关闭
c:不同浏览器访问一个网站是不同会话
3)机制:当客户端第一次向服务器发出请求时,服务器根据客户端传来的SessionID判断该客户端是否创建了Session对象,若发现客户端没有SessionID(表明是第一次请求),服务器为该客户端创建一个Session对象(每个session对象都会有一个唯一的sessionId,用于区分其他session),并将与该对象对应的SessionId发回给客户端(服务端会产生一个cookie,并且,该cookie的name=JSESSIONID,value=服务端sessionId的值),保存成客户端cookie(至此,客户端就有了一个包含JSESSIONID的cookie),客户端第二次请求服务器时,会自动将该SessionID发回给服务器,服务器根据该SessionID,找到对应的Session对象供客户端使用。即Session对象保存的数据会话过程共享。(因此,客户端的cookie就可以和服务端的session一一对应,JSESSIONID-sessionId)
4)总结:
(1)session存储在服务端
(2)session是在同一个用户请求时共享
(3)实现机制:第一次客户请求时,产生一个sessionId并复制给cookie的 JSESSIONID,然后发给客户端。最终通过session的sessionId-cookie的JSESSIONID。
5)session常用方法:
(1)String getId() :获取sessionId
(2)boolean isNew() :判断是否是新会话 (第一次访问)
(3)void invalidate() :设置session对象失效(session立刻失效)
(4)void setAttribute(String key,Object value) :以key/value形式将对象保存到session对象中。
(5)Object getAttribute(String key) :根据key返回Session中保存的对象
(6)void setMaxInactiveInterval(int interval) :设置session最大失效时间 单位秒
(7)int getMaxInactiveInterval() :获取session最大失效时间
案例:sessionDemo
(4)out:输出对象,向客户端输出内容
(5)application(全局对象)
1)String getContextPath() 虚拟路径
2)String getRealPath(”String name”) 绝对路径(虚拟路径相对的绝对路径)
(6)pageContext JSP页面容器
(7)config 配置对象(服务器配置信息)
(8)page 当前JSP页面对象(相当于java中的this)
(9)exception 异常对象
5.cookie(客户端,不是内置对象):cookie是由服务端产生的,再发送给客户端保存。
1)相当于本地缓存的作用:客户端(hello.mp4,zs/123)->服务端(hello.mp4,zs/123)
2)作用:提高访问服务端的效率,但是安全性较差。
3)Cookie:key=value
4)Javax.servlet.http.Cookie :
public Cookie(String name,String value)
String getName():获取name
String getValue():获取value
void setMaxAge(int expiry):最大有效期(秒)
5)服务端发送给客户端:
(1)服务端准备cookie
response.addCookie(Cookie cookie)
(2)页面跳转(转发,重定向)””
(3)客户端获取cookie:request.getCookie();
6)总结:
(1)服务端增加cookie:response对象;客户端获取对象:response对象
(2)不能直接获取某一个单独对象,只能一次性将全部的cookie拿到
案例:cookie
(3)通过F12可以发现,除了自己设置的cookie对象外,还有一个name为 JSESSIONID的cookie
(4)建议cookie只保存英文数字,否则需要进行编码、解码
7)使用cookie实现 记住用户名功能(案例:cookieDemo)
8)cookie:(1)不是内置对象,要使用必须new
(2)但是,服务端会自动生成一个(服务端自动new一个cookie)name=JSESSIONID的cookie并返回给客户端。
知识点1: session cookie
保存的位置 服务端 客户端
安全性 较安全 较不安全
保存的内容 Object String
6.四种范围对象(小->大)
pageContext JSP页面容器 当前页面有效
request:请求对象 同一次请求有效
session会话对象 同一次会话有效
application全局对象 全局有效(整个项目有效)
1.以上4个对象共有的方法:
1)Object getAttribute(String name) :根据属性名,获取属性值
2)void setAttribute(String name,Object obj) :设置属性值(新增,修改)
setAttribute(“a”,”b”); //如果a对象之前不存在,则新建一个a对象;
如果a之前已经存在,则将a的值改为b
2)void removeAttribute(String name) :根据属性名,删除对象
a.
pageContext 当前页面有效(页面跳转后无效)
b.
request 同一次请求有效;其他请求无效(请求转发有效;重定向后无效)
c.
session 同一次会话有效(无论怎么跳转都有效;关闭/切换浏览器后无效;从登陆-退出 之间全部有效)
d.
application 全局有效(全局变量;整个项目运行期间都有效;切换浏览器任然有效;关闭服务、其他项目无效)
(多个项目共享、重启后仍然有效:JNDI)
2.总结:
1)以上四个范围对象,通过setAttribute()赋值,通过getAttribute()取值;
2)以上范围对象,尽量使用最小的范围。因为对象的范围越大,造成的性能损耗越大。
3、MVC和Servlet
MVC设计模式:
M:Model,模型:一个功能。用JavaBean实现。
V:View,视图:用于展示、以及与用户交互。使用html js css jsp jquery等前端技术实现
C:Controller,控制器:接受请求,将请求跳转到模型进行处理;模型处理完毕后,再将处理结果返回给请求处。可以用jsp实现,但是一般建议使用servlet实现控制器。
jsp->java(servlet)->jsp
1.引入Servlet
Jsp页面既包含静态部分,也可包含java代码,上面例子中可以看出,control.jsp页面只是充当了服务器端程序执行的功能,并没有返回给客户端结果,即只有java代码没有与显示相关的代码,可将类似这样只有代码的控制页改成servlet实现。
Pom.xml中添加坐标:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
@webServlet(“/controlServlet”) :注意部署路径前面要加/
问题1:什么时候需要使用servlet?
1):只完成java逻辑代码 2):不需要静态代码 3):被其他页面访问(HTML,jsp等)
问题2:什么叫servlet部署?
Servlet是javabeen,本质是java类,可被页面访问,若想被页面访问,必须部署到网站根目录下,
@WebServlet(“/ControlServlet”)就是将某个servlet部署到根目录下,部署后,才能被别的页面访问。
2.Servlet生命周期:
(1)加载
(2)初始化:init(),该方法会在Servlet被加载并实例化的以后执行
(3)服务:service()->doGet() doPost()
(4)销毁:destroy(),Servlet被系统回收时执行
(5)卸载
3.Servlet存放数据有两种:
(1)将数据存入request对象中,然后转发到jsp页面,在JSP页面中用el从requestScope获取数据并显示。
(2)将数据存入session对象中,然后重定向或者转发到jsp页面,在JSP页面中用el 从sessionScope获取数据并显示。(不建议使用,原因:session域占用服务器资源)
4、EL表达式
1.EL:Expression Language,可以替代jsp页面中的java代码。
2.servlet(增加数据) -> jsp(显示数据)
3.传统的在jsp中用Java代码显示数据的弊端:类型转换、需要处理null、代码掺杂 ->EL
4.EL示例:${requestScope.student.address.schoolAddress}
5.EL操作符:
点操作符 . --使用方便
中括号操作符 [] --功能强大:可以包含特殊字符(. 、 -),获取变量值例如存在变量
6.特点:servlet中存入什么数据类型,jsp页面中el取出时会自动转换成存入时的数据类型。
7.作用:在jsp页面中显示数据,即用于显示数据。
8.隐式对象(不需要new就能使用的对象,自带的对象)
(1)作用域访问对象(EL域对象):
pageScope<requestScope<sessionScope<applicationScope
如果不指定域对象,则默认会根据从小到大的顺序,依次取值
(2)参数访问对象:获取表单数据(超链接中传的值${param},地址栏中传的值${paramValues})
(3)jsp隐式对象:pageContext
在jsp中可以通过pageContext获取其他jsp隐式对象
${pageContext.getSession()} --> ${pageContext.session}
${pageContext.getResponse()} --> ${pageContext.response}
可以使用此方法,级联获取方法:
${pageContext.request.serverPort}
${pageContext.方法名去掉()和get并且将首字母小写}
9.语法:
(1)点操作符 ${requestScope.stu.name} stu对象下的name属性
(2)关系运算符
关系操作符 说明 示例 结果
==(或eq) 等于 ${23==5}或${23 eq 5} FALSE
${"a" =="a"}或${"a" eq "a"} TRUE
!=(或ne) 不等于 ${23!=5}或${23 ne 5} TRUE
<(或lt) 小于 ${23<5}或${23 lt 5} FALSE
>(或gt) 大于 ${23>5}或${23 gt 5} TRUE
<=(或le) 小于等于 ${23<=5}或${23 le 5} FALSE
>=(或ge) 大于等于 ${23>=5}或${23 ge 5} ture
(3)逻辑运算符
逻辑操作符 说明 示例
&&(或and) 逻辑与 如果A为true,B为false,则${ A && B } (或${ A and B } ) FALSE
||(或or) 逻辑或 如果A为true,B为false,则${ A || B} (或 ${ A or B } ) TRUE
! (或not) 逻辑非 如果A为true,则${ ! A } ( 或${ not A } ) FALSE
(4)empty操作符
若变量不存在,或者值为null,或长度为零的String,或size为零的集合,empty操作符均返回真
则${ empty a } 返回的结果为true
${ not empty a }或${ ! empty a } 返回的结果为false
(5)参数访问对象
${param.name} 相当于request.getParameter("name");
${paramValues.hobby} 相当于request.getParameterValues("hobby");
//说明:
//getParameter获取表单提前或者get提交的值(例:<a href="a.jsp?para1=a¶2=b">提交</a>为get提交)
//getAttribute获取request.setAttribute("key","值")方式所赋的值
10.Jsp中el不能用的解决办法
(1)方法1:更改web.xml的web-app标签中的命名空间,可改成如下,整个项目只改动一次
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
(2)方法2:在jsp页面开头添加<%@ page isELIgnored="false"%>,每个页面都要加
5、JSTL
1.JSTL:比EL更加强大
2.需要引入2个jar:jstl.jar standard.jar
3.页面上添加JSTL标签引用:(其中prefix="c":前缀)
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
4.核心标签库:通用标签库、条件标签库、迭代标签库
5.通用标签库:<c:set>赋值、<c:out>显示、<c:remove>删除属性
6.条件标签库:
(1)<c:if test="测试条件" scope></c:if>
1)例:
<c:set var="str3" value="hello" scope="request"></c:set>
<c:if test="${requestScope.str3=='hello'}">
判断相等<br />
</c:if>
2)例:三目运算:${str3=='hello'?"相等":"不相等"}
(2)<c:choose> 相当于多分支
例:<c:set var="job" value="班主任" scope="request"></c:set>
<c:choose>
<c:when test="${requestScope.job=='教员'}">
欢迎教学登录,请管理并授课好班级,让学生多学东西
</c:when>
<c:when test="${requestScope.job=='班主任'}">
欢迎班主任登录,请管理好班级,尽量解决学生生活和思想问题
</c:when>
<c:otherwise>
输错了
</c:otherwise>
</c:choose>
7.迭代标签库:(遍历)
<c:forEach items="要遍历的集合" var="遍历变量" begin="开始索引" end="结束索引" step="步长" varStatus="status">
…循环体代码…
</c:forEach>