admin管理员组文章数量:1646247
本文需要结合【HTTP】阅读:
https://blog.csdn/weixin_42915286/article/details/84871898
https://www.bilibili/video/av40697944?from=search&seid=9275670543812089695
说在前面
JavaEE是一个开放的平台,包含的技术很多,主要有13种;
需要强调的是:不是每个技术都要用到,实际上需要有选择地使用;
实际上,把每一种JavaEE技术都精通是不现实的,有人则认为,若能够成为JavaEE程序员,必须掌握的技术是:Java、Servlet、JSP;若这三门没学好就去追求spring等web【框架】,也只是空中楼阁,华而不实的;
—————————————————————————————
Servlet 3.0
Servlet = Java服务器小程序
Applet = Java客户端小程序(严重过时)
Servlet是一个供其他 Java程序(【Servlet引擎】或【Web服务器】或【Tomcat】)调用的Java类,他不能独立运行,它的运行完全由Servlet引擎来控制和调度;
针对客户端的多次Servlet请求,通常情况下,【服务器只会创建一个Servlet实例对象(单例模式)】,也就是说Servlet实例对象一旦创建,也就是说Servlet实例对象一旦创建,他就会潴留在内存中,为后续的其他请求服务,直至Web容器退出或者reload该web应用,Servlet实例对象才会被销毁;
重要部分:页面搜索:Servlet的单例问题
-
提问:为什么会出现Servlet?
需求:请你用现有的JavaEE技术开发一个动态网页,比如让用户留言,其他人可回复交互;
用普通的Java技术完成不了,那么Sun就开发了Servlet技术供程序员使用;
Servlet是JavaEE中出现较早的一项技术,在Struts、Spring出现前,动态网页技术都采用Servlet,在1999-2000大行其道;
Servlet是JSP的基础,是Spring Controller的本质;是JavaWeb的基础,到2019年的今天仍然有重要性; -
提问:Servlet特点?
1.服务器端(直接说Tomcat也没问题)调用和执行的;(非客户端!)
2.Java编写;(Servlet就是一个Java写的类)
3.按照Servlet规范开发的;(规范需要花时间学习下)
4.功能强大,几乎可以完成所有网站功能(很多老程序员仍然喜欢用Servlet写整个网站)
5.Spring Controller的基础;
【Servlet有规范】!
必须放在Tomcat
- webapps
- examples
- ???
- WEB-INF
- classes文件夹
下
因为Servlet说到底是Java程序,Java程序不能直接运行,要编译成classes;
另外,还要部署web.xml
文件,一个Sevlet类对应一个<servlet>
和<servlet-mapping>
(项目中所有Servlet类的配置都写在同一个web.xml
中)
需求:
通过一个用户管理系统来讲解Servlet,单纯用Servlet来实现,是一个很好练习Servlet技术的案例;
操作人员:
管理员;普通用户;
同时还需要完成:
分页、网站计数器、保存用户访问网站的习惯、追踪用户的来源;
Internet上供外接访问的Web资源有:
静态Web资源(HTML):web页面中工人们浏览的数据始终是不变的;
动态Web资源(JSP/Servlet):web页面中工人们浏览的数据是有程序产生的,不同时间点访问web页面看到的内容各不相同;
Java中,动态web资源开发技术统称为JavaWeb;
——————————————
b/s结构和c/s结构的比较
这部分的选择,程序员一般不参与,由项目经理说了算;
b/s
即:browser/server 浏览器 服务器
优势:
1.开发成本低;
2.管理维护简单;(浏览器安装就可以用)
3.产品升级便利;(比如新浪想要新增一个调查功能,开个会加个模块就可以了;但如果微信想要添加一个新模块,需要对全世界的客户端添加该功能)
4.对用户的培训费用低;
5.用户使用方便,出现故障几率小;(比如使用c/s制作了一款软件给珠宝开发商,正式使用时,老板和与员工却发现彼此看不到对方上线的情况,后来开发终于找到原因所在:网管的防火墙只开放了80端口,且不允许开放其他端口,那么开发就努力使用防火墙穿透tunnel技术解决了问题)
不足:
1.安全性不足;(因为浏览器是别人写的;浏览器大多是开源的,可被大众研究)
2.客户端不能随心变化,受到浏览器的限制;
c/s 用tcp/ip协议(socket)
即:client/server 客户端(往往是程序员开发的) 服务器;
b/s和c/s从本质上来说没有区别,只是表现形式不一样:
b/s:客户端用浏览器,是现有的工具,程序员无需自己再包装;
c/s:客户端自己来开发,程序员要自己包装tcp/ip;
——————————————
实现Servlet
- 提问:实现Servlet有几种方式?
三种; - 1.implements
Servlet
接口;(稍微重要,已废弃)
但通过此方式很好理解Servlet生命周期,而Servlet生命周期必须掌握!!! - 2.extends
GenericServlet
类;(高不成低不就,已废弃) - 3.extends
HttpServlet
类;(唯一选择,最重要!!!)
需求:
用实现接口的方式开发一个Servlet,要求该Servlet可以显示HelloWorld,同时显示当前时间;
(用静态文件HTML是做不到的,动态文件可以实现)
如何新建?
页面搜索:TODO
implements Servlet
查阅JavaEE API,可知里面就五个方法:
而既然需要继承一个接口,那么这五个方法就都要实现;
init()
初始化Servlet,就是把该Servlet装载到内存中,只会被调用一次;getServletConfig()
得到ServletConfig对象;(之后会讲)service()
核心;服务函数,写业务逻辑代码,该函数每次都会被调用;getServletInfo()
得到Servlet的配置信息;destroy()
销毁,从内存中清除,只会被调用一次;
(和init()
相对应,都只加载一次)
tips:
若Servlet被访问十次,init()
只会被调用一次,service()
会被调用十次,destroy()
会被调用一次;
——————————————
Servlet01 implements Servlet
package com.yau.Servlet;
import javax.servlet.*;
import java.io.IOException;
import java.util.Date;
public class Servlet01 implements Servlet{
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null; // 为空时肯定编译失败
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello,World!!!" + new Date());
// 浏览器输出 servletResponse.getWriter().println("Hello,World!!!"+new Date());
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
配置web.xml
映射:对已注册的Servlet进行映射;
这么配置只能在IDE的console返回语句;
浏览器访问:http://localhost:8080/Servlet01
IDE可返回语句;(浏览器无返回)
(注意:默认浏览器访问http://localhost:8080
,浏览器返回$END$
;记得注意修改URL,才能正确访问)
没看完:
https://www.bilibili/video/av40697944/?p=10
——————————————
Servlet生命周期(重要)
必须搞得很明白!!!
—————————————————————————————
extends HttpServlet
Servlet 3.0
市面上的公司,90%都是通过HttpServlet
的方式来开发Servlet;
追踪源码,会发现doGet()
和doPost()
都源自于service()
,等于对此方法进行了包装而已;
Servlet3.0开始,配置Servlet支持注解方式,但还是保留了配置web.xml方式;
HttpServlet指能够处理HTTP请求的Servlet,他在原有Servlet接口上添加了一些与HTTP协议进行处理的方法,他比Servlet接口的功能更为强大,因此开发人员在编写Servlet时,通常应该implements这个类,避免直接去实现Servlet接口;
HttpServlet在实现Servlet接口时,Override了service()
,该方法内的代码会自动判断用户的请求方式,若为GET请求,则调用HttpServlet的doGet方法,若为Post请求,则调用doPost方法;
因此客服人员在编写Servlet时,通常只需要Override doGet或者doPost方法,而不需要Override service方法;
配置Servlet的name
和urlPatterns
有两种方式:
1.web.xml文件中配置
2.Servlet类上使用@WebServlet注解进行配置(此方法不用web.xml)
——————————————
@WebServlet常用属性
属性 类型 是否必须 说明
asyncSupported boolean 否 指定Servlet是否支持异步操作模式
displayName String 否 指定Servlet显示名称
initParams WebInitParam[] 否 配置初始化参数
loadOnStartup int 否 标记容器是否在应用启动时就加载这个Servlet
name String 否 指定Servlet名称
urlPatterns/value String[] 否 这两个属性作用相同,指定Servlet处理的url
——————————————
方法1
Servlet02
(注意:此方法我采用的是Web Application模版,非Spring Boot)
public class Servlet02 extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().println("I am httpservlet doGet()");
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().println("I am httpservlet doPost()");
}
}
web.xml
<servlet>
<servlet-name>Servlet02</servlet-name>
<servlet-class>com.yau.Servlet.Servlet02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet02</servlet-name>
<url-pattern>/Servlet02</url-pattern>
</servlet-mapping>
访问:http://localhost:8080/Servlet02
——————————————
方法2
MyServlet
(注意:此方法我采用的是Spring Boot 2.0模版,SB特别之处在于在启动项添加@ServletComponentScan
)
@WebServlet(name="myservlet",urlPatterns = "/myservlet")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
String str = "doGet() here.";
out.println(str);
}
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
String str = "doPost() here.";
out.println(str);
}
}
@SpringBootApplication
@ServletComponentScan("com.yau.sb_servlet.Servlet")
public class ServletApp {
public static void main(String[] args) {
SpringApplication.run(ServletApp.class, args);
}
}
访问:http://localhost:8080/myservlet
——————————————
默认返回doGet方法:
doGet() here.
doGet方法的参数都写在URL中,比如
localhost:8080/myservlet?username=haha
存储在HTTP报文的第一行,且其数据容量一般不能超过1K;
GET / myservlet?username=haha HTTP/1.1
User-Agent Mozilla/5.0 (Macintosh...
Accept text/html...
Accept-Encoding gzip, deflate
Connection:Keep-Alive
这样很明显是不安全的,不建议用doGET方法!!!
——————————————
如何返回doPost方法?
resources
- static
(一定是static文件夹)下新建一个html文件,比如login.html
:
他的form action
要指明Servlet的name,本html才可以指向指定Servlet;
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<form action="myservlet" method="post">
u:<input type="text" name="username"/>
<input type="submit" name="btnLogin" value="Login"/>
</form>
</body>
</html>
访问该html:http://localhost:8080/login.html
返回该Servlet的doPost方法内容:
doPost() here.
doPost方法的请求参数都存储在HTTP请求包中;
GET / myservlet HTTP/1.1
User-Agent Mozilla/5.0 (Macintosh...
Accept text/html...
Accept-Encoding gzip, deflate
Connection:Keep-Alive
username=haha
传送的数据量无限制,POST提交的参数后台更容易解析(即使是中文数据也更容易解决);
对比doGet,建议用doPost;
————————————————————————————
getParameter()
来自:public interface ServletRequest
getParameter(java.lang.String name)
Returns the value of a request parameter as a String, or null if the parameter does not exist.
会以String形式返回request参数,如果属性不存在,会返回null
myservlet:
resp.getWriter().println("the post name = "
+req.getParameter("username"));
html中配置mthod=post
——————————————
总结:
通过HttpServlet去开发Servlet,需要重写doGet和doPost方法,这种方法最为流行;
表单提交get请求和post请求的区别:
1.从安全来看,get<post,get提交的数据会在浏览器的地址栏显示;
2.从提交的内容大小来看,get<post,但是get提交的数据不能大于1K,而post提交的数据理论上不受限制,但是集中建议不要大于64K;
3.请求响应速度来看,get>post,get要求服务器立即处理请求,而post可能形成一个队列请求;
————————————————————————————
Servlet细节(重要)
——————————————
由于客户端是通过URL访问web服务器中的资源,所以Servlet若想被外界访问,必须把Servlet映射到一个URL上,此部分工作在
(1)web.xml
中由<servlet>``<servlet-mapping>
;
或者 (2)@WebServlet(name = "", urlPatterns = "")
来完成;
————————————————————————————
同一个已注册的Servlet可指定多个urlPattern
同一个已注册的Servlet可映射到多个URL上
web.xml
:
@WebServlet
:
web.xml里的urlPattern
在@WebServlet中叫做:urlPatterns
,是复数;
那么可以猜想,这个属性本身就支持填写多个urlPattern???
查看源码,果然,urlPatterns是一个String数组,那么在@WebService写多个URL的格式就很明朗了;
————————————————————————————
映射一个Servlet时可以写多层
比如:
<url-pattern>/one/two.html</url-pattern>
(这里的.html
只是url的一部分,不代表是真的html文件!!)
比如:
@WebServlet(name="myservlet",urlPatterns = {"/myservlet/haha/yoyo"})
————————————————————————————
Servlet映射到的URL中可以使用通配符*
,很有用!!
只能有两种固定格式:
(1).*.扩展名
(2).以/
开头,以/*
结尾
易错:
这两种方式注意区分格式,第一种星点do
前面不能添加斜杠;
通配符的优先级问题总结
——————————————
/*
这里有个很有意思的点:可以直接写/*
,代表所有请求都映射给他;
那么意思是:当用户乱输入URL后缀时,/*
就可以把这个不存在的URL映射到,返回用户我们指定的错误页面,不会返回一个让用户看不懂的报错页面;
但这样又来了一个问题:
如果我们精心配制的urlPa
版权声明:本文标题:【框架】Servlet API 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1729425695a1200856.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论