java selvet_Java之Servlet

Servlet规范了JavaWeb项目的结构

Servlet的规范约束了服务器如何来实现Servlet规范,如何解析JavaWeb项目的结构。

Java就是通过接口来约束

Servlet规范的jar就在tomcat的lib目录下面,文件名:servlet-api.jar,其中还有webSocket-api.jar

创建servlet先只用servlet-api.jar即可。

一、开始使用Servlet规范开发JavaWeb项目:

05a6f69d21736ab6af8ef4c194d737b8.png

然后开始配置:

c19cc143ee4f68440d6964365d02c325.png

注意:里面的资源名称必须要用"/"开头

源码:

1 <?xml version="1.0" encoding="UTF-8"?>

2

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee5 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

6 version="3.1"

7 metadata-complete="true">

8

9

10

11 HelloServlet

12 com.demo.testServlet.HelloServlet

13

14

15

16

17 HelloServlet

18 /helloHeYang

19

20

21

22

另外:

ded4674a0328f71f5259abb8679808c9.png

Servlet中的方法含义:

public void init(ServletConfig config):Servlet的初始化操作方法

public void service(ServletRequest req, ServletResponse res):处理请求和响应的方法

public void destroy():资源回收

public ServletConfig getServletConfig():获取Servlet的配置信息

public String getServletInfo():获取Servlet的相关的信息(作者/版本)

1 @Override2 public void init(ServletConfig config) throwsServletException {3 //TODO Auto-generated method stub

4 System.out.println("init初始化方法");5 }6

7 @Override8 publicServletConfig getServletConfig() {9 //TODO Auto-generated method stub

10 System.out.println("getServletConfig获取Servlet配置信息");11 return null;12 }13

14 @Override15 public voidservice(ServletRequest req, ServletResponse res)16 throwsServletException, IOException {17 //TODO Auto-generated method stub

18 System.out.println("service(ServletRequest req, ServletResponse res)处理请求和响应");19 }20

21 @Override22 publicString getServletInfo() {23 //TODO Auto-generated method stub

24 System.out.println("getServletInfo():获取Servlet的相关的信息(作者/版本)");25 return null;26 }27

28 @Override29 public voiddestroy() {30 //TODO Auto-generated method stub

31 System.out.println("destroy():资源回收");32 }

启动tomcat服务器之后,然后打开浏览器:

c5c86168ebd322999556a401a56f9d91.png

---------------------------------------------------------------------------------------------------------------

Servlet的生命周期方法:

public void init(ServletConfig config):Servlet的初始化操作方法(在被第一次访问的时候执行)

public void service(ServletRequest req, ServletResponse res):处理请求和响应的方法(每次访问都会执行)

public void destroy():资源回收(在服务器正常关闭的时候执行)

----------------------------------------------------------------------------------------------

Servlet的生命周期方法的执行顺序:

Servlet是单例的(在其整个应用中只有一个对象)

执行顺序:

1.调用公共无参数的构造器创建对象(只会在第一次访问的时候执行)

2.执行init方法(只会在第一次访问的时候执行)

3.执行服务方法(每次访问都会执行)

4.执行destroy方法(在服务器被正常关闭的时候执行),不要将关闭资源的操作放到该方法中

注意:在Servlet类中必须保证有一个公共的无参数的构造器(使用反射创建对象,类的Class实例.newInstance())

类中的默认构造器的访问权限和类的访问权限一致

二、Servlet的请求流程:

a5c1e0df2bb32318623d97f8c7d18164.png

1.通过浏览器发送请求

http://localhost:8080/demo/helloHeYang

2.Tomcat解析请求路径

协议:http

主机地址:localhost

端口:8080,确定访问的是该主机上的哪一个程序

上下文的路径:server.xml文件中配置的信息,/demo

资源名称:访问的资源是什么,/helloHeYang,在项目下的web.xml文件中配置的的文本

3.根据上下文的路径去找到server.xml文件中的节点,确定项目的根路径

如果没有找到,返回404错误

反之,执行第4步

4.根据资源名称去项目下的WEB-INF下的web.xml文件中找到文本内容为/hello的节点

可以确定找到Servlet对应的

5.根据找到Servlet 的全限定名

6.使用反射创建对象

Tomcat中的缓存池:

Map cache=new HashMap<>();

Servlet obj = cache.get("类的全限定名");

if(obj==null){

//如果是第一次访问:

Object obj2 = Class.forName("类的全限定名").newInstance();

//将创建好的对象放到缓存池中

cache.put("类的全限定名",obj2);

} else {

//不是第一次访问:

//GOTO 7;

}

7.调用init方法进行初始化操作

创建ServletConfig对象,调用init(config)

8.执行service(ServletRequest req, ServletResponse resp),

执行之前先创建ServletRequest , ServletResponse 两个对象

9.给浏览器一个响应信息

三、Servlet初始化参数

在Servlet类中定义初始化参数,会将代码写死,应该将配置信息放到web.xml文件中

22919e52462be967b3620b7ad2876916.png

问题:如何将配置好的初始化参数获取到?

解决方案:使用ServletConfig来获取

------------------------------------------------------------------------------------

ServletConfig中的常用方法:

public String getServletName():获取Servlet的名称,配置中的文本

public ServletContext getServletContext():获取Servlet的上下文信息

-------------------------------------

获取初始化参数的相关方法:

public String getInitParameter(String name):根据指定的名称获取当前的Servlet中的初始化参数

public Enumeration getInitParameterNames():获取当前Servlet中的所有的初始化参数的名称

Enumeration:迭代器(Iterator)

5bb1059fd84c18b0cb3bd10828aa7f22.png

关键代码:

1 @Override2 public void init(ServletConfig config) throwsServletException {3 //TODO Auto-generated method stub

4 System.out.println("init初始化方法");5

6 //初始化方法的参数

7 System.out.println(config.getServletName());8 System.out.println(config.getInitParameter("encoding"));9 System.out.println("----------------------------------");10 Enumeration inits =config.getInitParameterNames();11 while(inits.hasMoreElements()) {12 String name =inits.nextElement();13 System.out.println("name");14 System.out.println(name+"--->"+config.getInitParameter(name));15 }16

17 }

------------------------------------------------------------

目前的初始化参数只是为当前的Servlet做的配置,如果在多个Servlet中有相同的配置,那么该配置就重复了---解决方案(使用全局的初始化参数)。

四、Servlet继承体系

其实我们实际开发中需要继承HttpServlet这个关键的类,下面我们就来自己实现这个类,然后体会它里面的继承体系,了解它内部的关联性。

首先是自定义一个 HelloServlet,并且实现Servlet,ServletConfig两个接口以及接口的所有的方法。

1 importjava.io.IOException;2 importjava.util.Enumeration;3

4 importjavax.servlet.Servlet;5 importjavax.servlet.ServletConfig;6 importjavax.servlet.ServletContext;7 importjavax.servlet.ServletException;8 importjavax.servlet.ServletRequest;9 importjavax.servlet.ServletResponse;10

11 public class HelloServlet implementsServlet,ServletConfig{12

13 //声明私有的全局变量

14 privateServletConfig config;15

16 public voidinit(){17 //事实上,如果子类没有用super方法,就不会被调用

18 System.out.println("调用了父类的init方法");19 }20

21 @Override22 public void init(ServletConfig config) throwsServletException {23 //TODO Auto-generated method stub

24 System.out.println("HelloServlet:init初始化方法");25 this.config =config;26 init();27 }28 @Override29 publicServletConfig getServletConfig() {30 //TODO Auto-generated method stub

31 System.out.println("HelloServlet:getServletConfig获取Servlet配置信息");32 return config;//在这里直接返回ServletConfig对象

33 }34 @Override35 public voidservice(ServletRequest req, ServletResponse res)36 throwsServletException, IOException {37 //TODO Auto-generated method stub

38 System.out.println("HelloServlet:service(ServletRequest req, ServletResponse res)处理请求和响应");39

40 }41 @Override42 publicString getServletInfo() {43 //TODO Auto-generated method stub

44 System.out.println("getServletInfo():获取Servlet的相关的信息(作者/版本)");45 return null;46 }47 @Override48 public voiddestroy() {49 //TODO Auto-generated method stub

50 System.out.println("HelloServlet:destroy():资源回收");51 }52

53

54 //为什么要实现ServletConfig的接口,为了使用接口里面的方法,方便子类调用

55

56 @Override57 publicString getServletName() {58 //TODO Auto-generated method stub

59 returnconfig.getServletName();60 }61

62 @Override63 publicServletContext getServletContext() {64 //TODO Auto-generated method stub

65 returnconfig.getServletContext();66 }67

68 @Override69 publicString getInitParameter(String name) {70 //TODO Auto-generated method stub

71 returnconfig.getInitParameter(name);72 }73

74 @Override75 public EnumerationgetInitParameterNames() {76 //TODO Auto-generated method stub

77 returnconfig.getInitParameterNames();78 }79

80 }

然后再创建一个MyHttpServlet继承HelloServlet,来处理http请求和响应的类

1 importjava.io.IOException;2

3 importjavax.servlet.ServletException;4 importjavax.servlet.ServletRequest;5 importjavax.servlet.ServletResponse;6 importjavax.servlet.http.HttpServletRequest;7 importjavax.servlet.http.HttpServletResponse;8

9 //单独一个子类处理service方法

10

11 public class MyHttpServlet extendsHelloServlet {12 @Override13 public voidservice(ServletRequest req, ServletResponse res)14 throwsServletException, IOException {15 //TODO Auto-generated method stub16

17

18 //如果要访问http协议的方法,需要强转类型

19 HttpServletRequest request =(HttpServletRequest) req;20 HttpServletResponse response =(HttpServletResponse) res;21 service(req, res);22 }23

24 public voidservice(HttpServletRequest req,HttpServletResponse res){25 //super.service(req, res);

26 }27 }

最后再创建一个子类HelloSubServlet,直接继承自MyHttpServlet,注意不是继承最前面的HelloServlet基类哦。

1 importjava.io.IOException;2

3 importjavax.servlet.ServletException;4 importjavax.servlet.ServletRequest;5 importjavax.servlet.ServletResponse;6 importjavax.servlet.http.HttpServletRequest;7 importjavax.servlet.http.HttpServletResponse;8

9 public class HelloSubServlet extendsMyHttpServlet {10

11 /*

12 @Override13 public void init(ServletConfig config) throws ServletException {14 // TODO Auto-generated method stub15 super.init(config);16 }17 * 由于config已经作为父类中全局变量来处理了,所以以上方法其实是多余了18 * 但是又需要调用父类的初始化servlet方法init(ServletConfig...)方法,19 * 如果子类没有实现,就会去找父类方法,如果子类实现了,而子类中没有用super调用父类方法,父类方法就不会执行20 * 所以就采用在父类中声明一个init空的方法,然后在init(ServletConfig...)调用,然后子类只要重写init()方法即可21 *22 * 但是,前提是:如果子类重写了init(ServletConfig...),就一定要记得要用super调用父类同样的方法23 */

24

25 @Override26 public voidinit() {27 //所有初始化的方法写在这里

28 System.out.println("HelloSubServlet初始化方法");29 }30

31 @Override32 public voidservice(HttpServletRequest req, HttpServletResponse res) {33 super.service(req, res);34

35 //因为子类实现了ServletConfig的接口方法,所以可以直接调用即可。

36 String name = this.getInitParameter("name");37 System.out.println(name);38 }; 40 }

然后仔细体会他们之间的关系。

下面是展示直接开发需要知道的继承体系:

b055182d72f6449ff7ce12408559b356.png

五、HttpServletRequest常用的方法

HttpServletRequest接口:处理基于HTTP协议的请求信息

常用的方法:

String getContextPath()  :获取上下文的路径

String getHeader(String name)  :根据名称获取请求头信息

String getMethod()  :获取请求的类型

String getRequestURI()  :获取请求的资源路径

StringBuffer getRequestURL():获取请求的全路径

String getParameter(String name)  :根据名称获取请求参数的值

String getRemoteAddr()  :获取请求的客户端的地址

---------------------------------------------------------------

ServletConfig中的getInitParameter(String name)

获取web.xml文件中配置的初始化参数的值

HttpServletRequest中的getParameter(String name)

获取用户提交的参数值

六、简单案例

一般情况下,一个表单对应一个Servlet。

在webapp目录下创建一个register.html

1

2

3

4

5

Insert title here

6

7

8

15

16 姓名:

17

18 密码:

19

20

21 性别:22 男23 女24

25 职业:26 Java27 C28 IOS29

30

31

32 城市:33

34 成都

35 上海

36 广州

37

38

39

40

41 评论:42 在这里输入文本。。。

43

44

45

46

47

48

49

50

51

52

53

然后创建一个RegisterServlet.class

1 packagecom.demo.request;2

3 importjava.io.IOException;4 importjava.util.Map;5

6 importjavax.servlet.ServletException;7 importjavax.servlet.http.HttpServlet;8 importjavax.servlet.http.HttpServletRequest;9 importjavax.servlet.http.HttpServletResponse;10

11 public class RegisterServlet extendsHttpServlet {12

13 /**

14 *15 */

16 private static final long serialVersionUID = 1L;17

18

19 @Override20 protected voidservice(HttpServletRequest req, HttpServletResponse resp)21 throwsServletException, IOException {22 //TODO Auto-generated method stub

23

24 System.out.println("开始执行这段代码。");25

26 //1、获取请求参数

27 String name = req.getParameter("name");28 String password = req.getParameter("password");29

30 System.out.println("name"+name+" password"+password);31

32 Map map =req.getParameterMap();33 String name2 = map.get("name")[0];34 System.out.println("name2"+name2);35 //2、调用方法来处理业务逻辑36

37 //3、控制页面跳转

38 }39

40 }

还要在web.xml中写好配置代码:

1

2

3

4 RegisterServlet

5 com.demo.request.RegisterServlet

6

7 encoding

8 UTF-8

9 name

10 hahaha

11

12

13

14

15

16 RegisterServlet

17 /register

18

Toncat中默认处理请求参数的编码方式默认是ISO-8859-1,只有一个字节,所以中文会乱码。

--解决方案:

方式一:

方式二:

Post:

// 将处理请求参数的编码改为UTF-8

req.setCharacterEncoding("UTF-8");

Get:

在service.xml文件中需要设置的配置(可能默认是URIEncoding="ISO-8859-1"):

1

2 connectionTimeout="20000"

3 redirectPort="8443"URIEncoding="UTF-8"/>

另外规定:提交表单只能用POST请求。

HttpServletResponse接口:处理基于HTTP协议的响应信息

常用的方法:

PrintWriter getWriter()  :向页面输出字符流

ServletOutputStream getOutputStream()  :向页面输出字节流,实现文件下载

以上两个方法不能被同时调用

void setCharacterEncoding(String charset)  :设置响应信息的字符编码

向页面输出一个html内容,必须要下面两个设置

resp.setCharacterEncoding("UTF-8");

resp.setContentType("text/html");:MIME的类型

上面两个设置可以合在一行代码中

resp.setContentType("text/html; charset=UTF-8");

//处理响应

resp.setContentType("text/html;charset=UTF-8");

PrintWriter out=resp.getWriter();

out.print("");

out.print("

");

out.print("

");

out.print("你好");

out.print("

");

out.print("");

out.print("

");

out.print("你好,世界");

out.print("");

out.print("

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值