JavaWeb(Servlet)

475 阅读6分钟

Servlet

Servlet是Java提供的一门动态web资源开发技术。(静态资源比如HTML、CSS、JS这种,所有的用户看到的都是一样的)

常用于:Servlet根据不同的用户权限,匹配出对应的资源页面。

图片.png

Servlet快速入门

我们只是实现Servlet接口,真正创建、执行Servlet对象是靠TomCat服务器

图片.png

这里必须要写<scope>标签,因为Tomcat中也有servlet包,会冲突。

Servlet执行流程

图片.png

这是我们自己书写的,路径为/demo1,然后这个项目被发布到了Tomcat服务器中,最后浏览器通过请求/demo1就可以访问到servlet了。

图片.png

图片.png

Servlet生命周期

对象的生命周期:对象被创建 到 被销毁 的整个过程。

图片.png

@WebServlet(urlPatterns = "/demo",loadOnStartup = 1)

默认值是-1
取值是负整数:第一次被访问时创建Servlet对象
0或正整数:服务器启东时创建Serlvet对象,数字越小优先级越高。

init()方法只会被执行一次;
我请求一次,就会执行一次service()方法
关闭资源时,我们会在此之前调用destory()销毁资源

init()方法;初始化方法

调用时机:默认情况下,servlet被第一次访问时(之后就会创建Servlet对象),调用
调用次数:一次
//修改创建对象,默认是-1
@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
public class ServletDemo implements Servlet{
    public void init(SerlvetConfig config) throws ServletException{
        ...
    }
}

Service()方法

调用时机:每一次Servlet被访问时(页面请求一次),就会被调用
调用次数:调用一次,执行一次
public void service(ServletRequest req,ServletResponse res)throws ServletException,IOException{
    ...
}

destory()方法

调用时机:内存释放 或 服务器关闭,Servlet对象就会被销毁,就会调用destory方法
调用次数:1次

Servlet方法介绍

图片.png ServletConfig方法:获取Config信息
因为我的config信息是在init中的,变量作用域获取不到,因此我要进行改进

图片.png

Servlet体系结构

需要重写Http中的doGet和doPost方法才行。

图片.png

图片.png

doGet:直接在浏览器输出路径,就会调用doGet方法
doPost:需要写一个表单,指定为POST方式,路径是demo路径,请求资源
图片.png

1.HttpServlet中为什么要根据请求方式的不同,调用不同的方法?
get和post的请求方式不一样,我们需要进行分别处理 2.如何调用?
获取请求方式,进行逻辑判断

图片.png

自己定义一个主类,用来实现Serlvet,然后在里面书写doGet和doPost;以后所有的子类全部继承他即可,不用再和他一样实现Serlvet了。

urlPattern配置

图片.png

通过书写的urlPattern,在浏览器地址栏书写对应的url,就可以请求到书写的Serlvet页面了。

图片.png

XML配置Servlet

能用注解就用注解,我们刚刚学的就是注解,这里XML只是了解一下。

图片.png

介绍request和response

serlvet中的service()方法,里面有两个参数=》request和response

图片.png

request继承体系

图片.png

图片.png

request获取请求数据

图片.png

获取请求行

图片.png

请求头里是键值对的形式;

图片.png

请求体:获取url的参数;需要先搞个表单,然后表单通过post方式,来执行到dopost逻辑。
dopost中来获取请求体

图片.png

request通用方式 获取请求参数

不用上方的请求参数,改用这里的请求参数的方法。

图片.png

doGet和doPost中有相同的逻辑代码,在doPost中调用一次doPost,简化代码;
我们将Post和Get获取参数的方法设置为统一的,会大大减少我们的代码逻辑;
我们发现,参数是一种键值对的形式,那我们通过Map来存储键值对,但是会存在键名相同的情况,那我在存储值的时候,变为一个字符串数组即可。\

图片.png

默认方式:通过遍历键,来获取值

图片.png

第二种方式:直接通过具体的键,获取值(数组)

图片.png

第三种方式:通过具体的键,获取(单个)值

图片.png

这个时候doPost代码就不用在写这么多了,直接通过调用doGet即可。

图片.png

通过ideal模板快速生成servlet

配置模板

图片.png

图片.png

图片.png

图片.png

请求参数中文乱码处理

图片.png

解决之 POST,底层是通过getReader()数据流来获取参数数据的
我们将getReader()获取的方式为UTF-8

图片.png

解决之 GET,GET是通过getQueryString字符串,,不是 通过数据流。
因为tomcat收到浏览器传来的参数时,解码并没有通过UTF-8来,所以产生了乱码。\

图片.png

这两步,浏览器和服务器已经帮我们做过了

图片.png

这个是通用的,POST也可以用这个来改变乱码。

图片.png

注意!!!

图片.png

request请求转发

图片.png

demo05:当我执行demo05的时候,也会执行到demo06

图片.png

通过msg键,获取到hello值

图片.png

请求转发的特点

浏览器地址栏路径不变。我虽然是在05中forward到06了,但是我的路径显示仍然是05,只不过能请求到06的资源
只能转发到当前服务器的内部资源,不能瞎写,必须在同一个服务器中
一次请求,可以在转发的资源间使用request共享数据

response对象

图片.png

图片.png

重定向

重定向需要:设置状态码和设置响应头

图片.png

图片.png

重定向的路径需要加上虚拟路径(项目的名)

图片.png

我们发现设置状态码和location是一样的,我们可以修改,减少代码冗余。

图片.png

重定向的特点:和forward相反

浏览器地址栏的路径是会发生变化的
可以重定向到任意位置的资源(服务器内部、外部都可以)
两次请求,不能再多个资源使用request共享数据

路径问题

到底哪些地方需要加虚拟目录,哪些不用加?

浏览器使用:需要加虚拟目录(项目访问路径)
服务器端:不需要加虚拟目录

forward:是在服务器内部,进行转发
重定向:虽然代码在servlet中,但是路径是给浏览器的,浏览器根据路径来切换的。

<a href = ""> 是由浏览器发送请求的,所以要加上虚拟目录
<form action = ''>也需要加虚拟目录
req.getRequestDispatcher('')转发forward是服务器内部,不需要
resp.sendRedirect('')是浏览器跳转,需要加虚拟目录

我重定向到虚拟目录的时候,会在pom.xml中设置虚拟目录,这样就意味着我们写死了,这样会造成耦合性
实际上我们可以通过动态获取虚拟目录
String contextPath = request.getContextPath()
response.sendRedirect(contextPath+"/resp2")

response响应字符数据

响应后展示在页面上
图片.png

告诉浏览器,我其实是想输出html的
图片.png

流,不需要关闭,会随着response对象销毁,会自动释放的
默认write是不支持中文的,因为他默认支持ISO-8859-1,需要我们进行解码。
response.setContentType()不仅可以设置响应头,还能设置编码

response.setContentType("text/html;charset=utf-8")
PrintWriter writer = response.getWrite();
writer.write("你好")

response响应字节数据

字节数据:图片、音频这种

图片.png

图片.png

图片.png

图片.png

案例-用户登录

图片.png

准备环境:

图片.png

mybatis-config.xml

图片.png

UserMapper.xml

图片.png

UserMapper接口:和UserMapper.xml映射

简单的就直接用注解了
//根据用户名和密码查询对象
@Select("select * from tb_user where username=#{username}and password=#{password}")
User select(@Param("username")String username,@Param("password")String password)

login.html表单:访问loginServlet

图片.png

loginServlet
通过request.getParameter("键名")得到值

图片.png

图片.png

案例-用户注册

图片.png

UserMapper接口
null表示自增长
图片.png

register.html

图片.png

RegisterServlet

图片.png

图片.png

案例-SqlSessionFactory抽取

图片.png

图片.png