Servlet与JSP进阶
上一篇:JSP入门
一.请求与响应
1 请求的结构
HTTP请求的结构
请求是浏览器像Tomcat发送的数据包.
注:get请求将数据直接通过url传递,没有请求体这一说.post才有请求体.
可以直接在工程中新建一个Servlet类,并填写相应的类名和映射地址,eclipse会自动生成一个Servlet类 .
例如:
再在webcontent中新建一个html表单页面.使用Tomcat启动项目.
访问这个html地址,输入内容点击提交按钮.可以看到页面成功跳转并显示相应内容.
这时在当前页面F12打开控制台→network,返回表单页面重新提交一次,可以看到这个请求
get请求
点击这个请求,可以看到它的详细信息.
点击view source能够看到请求原始的代码
post请求
请求信息
post请求的数据
请求的源代码格式与get完全相同,只是"请求体"存放的位置不同.
利用请求头开发多端应用
可以通过 控制台左下角的小图标来切换模拟手机上的显示
可以在User-agent中得到使用的设备及浏览器信息
将该Servlet发布到Tomcat中,可以看到网页中打印出了User-agent的内容
切换成手机模式,效果如下:
可以通过判断请求头中User-agent来对不同的设备做出不同的处理
2 响应的结构
HTTP常见状态码:
地址写错的时候会报状态码404
服务器内部错误,状态码500
可以在页面输出的堆栈信息中快速找到可能出错的代码行数.
3 ContentType的作用
作为文件被下载
二.请求转发与重定向
1 请求转发与重定向的使用
之前的项目中我们都是用一个Servlet来处理问题,在实际的软件开发过程中,往往需要多个Servlet组合调用
如:A Servlet和B Servlet之间来回跳转和通信
案例:点击登录,弹出登录页面,用户输入用户名密码后点击登录,程序会对密码进行校验,
如果校验成功则成功登录,页面回到开始页面 ,并且在登录处显示用户信息.
简单模拟实现:
创建两个Servlet
实现请求转发功能
启动Tomcat.地址栏中输入check这个Servlet的地址,可以看到页面已经被重定向到了index上,但是地址栏显示的还是check的地址
原理:从服务器内部将请求从第一个Servlet转发到了第二个Servlet上
实现响应重定向:
启动Tomcat.地址栏中输入check这个Servlet的地址,可以看到页面已经被重定向到了index上,地址栏显示的是index的地址
原理:将请求第一次处理完了以后,由浏览器重新发送一个新的请求发送给index这个Servlet,所以对于响应重定向来说,地址会发生改变
2 请求转发与重定向的原理
请求转发
响应重定向
设置请求自定义属性
启动Tomcat,通过浏览器访问Servlet
如果使用响应重定向的方式,第二个Servlet会找不到username
三.cookie与session
1 cookie
浏览器cookie
当我们在一些网站使用自动登录时,该网站会把我们的用户名和密码保存到本地的cookie中.
谷歌浏览器默认存放cookie的路径
用记事本打开,发现里面是一堆乱码,这是因为cookie一般保存了一些比较敏感的数据,因此对这些数据进行了加密
下面我们用程序来实现自动登录的底层实现.
设置cookie
启动Tomcat,浏览器访问Servlet
如果cookie设置成功,会在控制台中看到,cookies标签,里面存放着保存的cookie数据
在header中也能看到cookie的信息
获取cookie
启动Tomcat,在浏览器访问Servlet,可以在Tomcat控制台看到打印的cookie信息
我们还可以加一些判断让程序更符合逻辑
cookie有效期
如果没有这一步代码判断
如果没有设置有效期,对于一个cookie来说它的有效期就是当前的浏览器窗口,
如果没有这一步代码判断,果我们将浏览器窗口关闭,再次打开并访问时,会报错
说明找不到有效的cookie,当浏览器关闭时,cookie被自动销毁,使用getCookies方法得到的值是null
给cookie设置有效期
这时关闭浏览器cookie不会自动失效,而是等到有效期到了之后才会失效.
2 session
分别打印两个Servlet的sessionid,发现它们是完全相同的,
它们是和我们浏览器窗口绑定的,每个浏览器窗口所对应的session存储空间不同,sessionid也就不同
当访问index时,用户名也没有丢失,因为是访问的同一个session对象,
但是,如果把浏览器关了重新打开访问,就找不到用户名了,因为全新的窗口对应的sessionid不同,获取的session对象也不同
session的原理
cookie会存放sessionid
ServletContext与三大作用域对象
1)servletContext
每个网页都有的部分,特别适合使用servletcontext全局对象
可以通过request对象得到servletcontext对象,通过setAttribute方法可以设置一些固定内容,如果设置了两个相同的属性,下面的会覆盖上面的.
通过getAttribute方法可以获得相应的属性值
要先调用init来完成自定义属性的初始化工作
再调用default来访问默认首页,可以看到我们设置的内容显示到了页面中
这是将当前页面关闭,再重新访问,页面依然能够展现出来.
这就说明servletcontent只要设置了自定义属性 ,就会在应用程序全局生效,无论在什么时候通过getAttribute方法都可以拿到.
2)JavaWeb三大作用域对象
请求对象:生命周期最短,从浏览器发出请求开始创建,用完了就失效了.
用户会话对象:生命周期较长,第一次用户发来请求的时候创建,session默认30分钟没有被访问就会被销毁.(浏览器窗口关闭时销毁这种说法不太准确,浏览器关闭后,只是存放sessionid的cookie失效了)
web应用全局对象:生命周期最长.web应用启动时被创建.web应用重启或被关闭的时候被销毁.
为了避免资源浪费,尽量用小作用域的对象.
四.中文乱码问题
1 解决Post请求中文乱码问题
没有处理前中文部分会显示为?
我们可以在输出前使用new String的方式把默认字符集转换为 utf-8.getBytes中的参数分别是原始的字符集以及想要转换成的字符集.
但是这种方法很麻烦,要给每个字符串转换字符集.
我们还可以使用下面的方法.
注:因为get方法没有请求体,因此该方法对于get方法来说不生效.
2 解决Get请求中文乱码问题
对于Tomcat8.x的版本,默认get请求发送中文就是UTF-8的格式,因此无需转换
但对于早期的版本需要进行一些配置.
tomcat安装目录→conf里面包含了tomcat的所有重要配置文件.其中server.xml描述了tomcat最核心的配置
在server.xml的63行,增加一个字符集的配置项.
以响应方式输出到页面时也会出现乱码,我们也要对字符集进行设置
五.web.xml配置详解
web.xml常用配置
修改web应用默认首页
web应用的默认首页如下
访问web应用时,web.xml会自动从上至下检查是否有该文件,如果找到就会自动加载.
在webcontent中的默认首页是一级默认首页,访问时直接访问工程所在目录即可.
也可以为二级目录设置默认首页,在webcontent下的文件夹中的默认首页是一级默认首页,访问时访问工程目录下二级目录.
Servlet通配符映射及初始化参数
1.Servlet通配符映射
/cookies/为前缀的url都会被该Servlet捕获
然后在web.xml中进行一些配置.
所有以pattern开头的url都会被捕获
控制台输出了捕获到的url
还可以自己加一些判断来实现其他功能
补充:
代码里明明写的是println为什么id和名字之间没有换行?
println()虽然看似是换行,但转成网页显示之后,这种换行会被浏览器解析为空格,所以输出的仍然是一行,用空格分隔。
具体如下:
但右键点击页面查看源代码时,能看出换行起作用了。具体如下:
只是在页面显示时,会被解析为为空格。如果想要在页面上需要换行的话,需要用<br/>。例如:
2.设置初始化全局参数
以往我们在初始化Servlet中通过context.setAttribute()来对一些固定的内容进行设置
这样在Servlet里面写死的参数不太利于我们去修改和维护
实际上,我们也可以在web.xml中来进行这些配置.
Servlet中也做出相应的修改
重新启动Tomcat后,第一步,初始化
访问默认网页
以后内容再有更改的时候,只需在web.xml中修改即可.
设置404,500等状态码默认页面
默认的404,500默认页面上的信息可能会泄露,被别有用心的人获取,很不安全,因此我们有必要对这个默认页面做一些修改.
在webcontent目录下新建一个目录error,分别创建一个404.html和一个500.html,并写好相应的内容.
在web.xml中配置指定的错误页面
保存后重启Tomcat, 访问服务遇到相应的错误时,就会跳转到相应的页面
除了404和500,其他状态码的默认页面也可以用同样的方法来设置.
六.JSP内置对象
内置对象可以在任何有效的java代码块中直接调用,不用先声明对象
在Tomcat安装目录中能够找到Servlet转义后的源代码,可以看到在service方法的参数中,已经预先定义好了request和response对象
代码块中的内容会直接转换为java代码原封不动的放到service方法中,所以我们可以在java代码块中直接调用request和response
如果觉得每次写response.getWriter().println()很麻烦,可以直接使用out.println(),因为out在初始化时预先定义好的,就等价于 response.getWriter()
其他的内置对象也是同样的使用方法
特殊的内置对象-exception
我们可以用上面修改状态码页面的例子来学习exception内置对象
可以将原来的静态HTML页面变成动态的jsp页面
第一步.在HTML代码中最上方增加一行配置代码,将其保存并关闭
第二步.将web.xml中的location修改成.jsp
同时也将500.html这个文件的扩展名变成.jsp
isErrorPage=true 代表当前jsp是专门用来显示错误的页面
可以用exception.getMessage()来获取错误信息
利用out.println()来输出错误信息
重启Tomcat,再次访问出错时,默认页面会显示错误信息
七.web应用程序打包与发布
如何让我们的项目可以脱离eclipse运行环境,进行单独运行呢?
在eclipse菜单栏点击file→export,选择web→war file,点击next
点击finish,可以在保存的路径中找到这个文件,可以用任何解压软件打开,里面有工程全部的文件结构
复制这个文件, 放到Tomcat安装目录的webapps目录中.
在Tomcat安装目录的bin目录下找到启动文件 ,startup.bat,双击运行
回到webapps目录中,可以看到,Tomcat启动后自动将war包解压,生成了相应的目录
在浏览器上直接访问工程路径,可以看到默认首页
此时我们并没有启动eclipse的环境,而是直接启动Tomcat来运行我们的项目
这样还有点小瑕疵,每次访问路径都要加上默认端口8080,很麻烦,也不符合网站发布的规则
而且还要加上上下文路径,默认即工程名称,也很不方便
把Tomcat关闭,使用Tomcat的核心配置文件可以优化这两个问题
在Tomcat安装目录→conf目录→server.xml
在63行可以修改默认端口号,访问时就不用显示的写端口号了
152行可以修改上下文路径,只保留斜杠,默认绑定到根目录上
reloadable表示自动加载,设置为true后,一旦path前面的默认目录有了改动,就可以自动进行重新加载,我们就不需要手动重启了.
都配置好后,重启Tomcat,重新访问
现在只需写localhost/ 即可访问默认首页.其他的页面也可以用同样的方法来进行设置.
下一篇:JSTL与EL表达式