《遇见狂神说》Javaweb之Servlet技术
Posted 生命是有光的
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《遇见狂神说》Javaweb之Servlet技术相关的知识,希望对你有一定的参考价值。
0.概述
- Servlet笔记,复习回顾使用
- 秦疆老师配套视频直达:Javaweb入门到实战
1.Servlet
1.1Servlet简介
-
Servlet就是sun公司开发动态web的一门技术
-
Sun在API中提供了一个接口:
Servlet
,如果逆向开发一个Servlet程序,只需要完成两个小步骤- 编写一个类,实现
Servlet
接口 - 把开发好的Java类部署到web服务器中
- 编写一个类,实现
-
把实现了
Servlet
接口的Java程序叫做Servlet
1.2HelloServlet
- 构建一个普通的
Maven
项目
-
删掉里面的
Src
目录,这个空的工程就是Maven主工程 -
在
pom.xml
里面添加 servlet,jsp 依赖- 去
Maven Repository
仓库里面搜索 javax-servlet-api 和 javax.servlet.jsp-api
<dependencies> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> </dependencies>
- 去
-
Load Maven changes
-
新建Module
- 父项目的pom.xml文件有
<modules>
<module>servlet-01</module>
</modules>
- 子项目的pom.xml文件有
<parent>
<artifactId>javaweb-02-maven</artifactId>
<groupId>com.kuang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的java子项目可以直接使用,意思其实就是子项目可以不用再次导入jar包,直接可以使用父项目导入的jar包
7.在 main 目录下新建Directory java
,resources
并且右键-Mark Directory as ,分别转换为java目录和资源目录
-
Maven环境优化
-
修改web.xml为最新的
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> </web-app>
-
上面这一大串我们是从哪里来的呢?其实我们是在tomcat\\webapps\\ROOT\\WEB-INF\\web.xml
中与tomcat相对应的版本
- 新建包,新建类
- 写一个Servlet程序,Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
- 编写一个普通类
- 实现Servlet接口,这里我们直接继承HttpServlet
- 重写doGet、doPost方法
- 编写Servlet的映射
为什么需要映射?
- 我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径
2.继承HttpServlet
public class HelloServlet extends HttpServlet {
// get或者post只是请求实现的不同方式,可以互相调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入doGet方法");
// 在这边重写完方法之后就去web.xml里面编写Servlet的映射
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
3.编写Servlet的映射
<!-- 1.注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<!-- servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 配置并启动tomcat
- 请求我们自己映射的
/hello
1.3Mapping问题
- 一个Servlet可以指定一个映射路径
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定多个映射路径
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello2-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello3-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello4-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello5-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用映射路径
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello/****-->
<!-- ****代表任何字母数字均可 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
- 默认请求路径
<!--默认请求路径-->
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/****-->
<!-- ****代表任何字母数字均可 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 指定一些后缀或者前缀等等….
<!--可以自定义后缀实现请求映射-->
<!--注意点,*前面不能加项目映射的路径-->
<!--当我们这样配置映射路径的时候,我们访问的名称为:localhost:8080/s1/hello/****.qinjiang-->
<!-- 例如:localhost:8080/s1/hello/sajdlkajda.qinjiang -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.qinjiang</url-pattern>
</servlet-mapping>
- 优先级问题
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.Error</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
例如当我们配置上方映射时候,我们访问:localhost:8080/s1/hello ,思考此时是访问/*
还是访问/hello
呢?
- 答案是访问
/hello
- 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
2.ServletContext
概念:web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用
白话:代表整个web应用,可以和程序的容器(服务器)来通信
2.1共享数据
- 我们在这个Servlet中保存的数据,可以在另外一个servlet中拿到
- 但是都是通过同一个
ServletContext
对象拿到的context.setAttribute(String name,Object value)
context.getAttribute(String name)
HelloServlet.java
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//数据
String username = "秦疆";
//将一个数据保存在了ServletContext中,名字为:username 。值 username
context.setAttribute("username",username);
}
}
- 编写mapper映射
<!-- 存放username数据 -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
GetServlet.java
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
// 将获取到的数据显示在网页中
resp.getWriter().print("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 编写mapper映射
<!-- 获取username数据-->
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.kuang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
测试访问结果;
- 先输入 : http://localhost:8080/s2/hello 访问
/hello
会存放数据 - 再输入:http://localhost:8080/s2/getc 访问
/getc
会取出数据
2.2获取初始化参数(了解)
我们可以在web.xml
中配置一些web应用初始化参数,在ServletContext
对象中可以拿到它
GetInitParameter.java
/**
* 获取初始化参数
*/
public class GetInitParameter extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
// 将获取到的url打印到网页上
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在web.xml中配置初始化参数和注册servlet映射为 /gp
<!-- 配置初始化参数 参数为url,值为 jdbc:mysql://localhost:3306/mybatis -->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
<!-- 注册servlet映射 -->
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.kuang.servlet.GetInitParameter</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
</web-app>
- 我们访问测试
2.3请求转发
GetRequestDispatcher.java
/**
* 请求转发
*/
public class GetRequestDispatcher extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了GetRequestDispatcher");
ServletContext context = this.getServletContext();
//RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); 转发的请求路径
//requestDispatcher.forward(req,resp); 调用forward实现请求转发;
context.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在web.xml中配置servlet映射为 /gr
<!-- 请求转发 -->
<servlet>
<servlet-name>gr</servlet-name>
<servlet-class>com.kuang.servlet.GetRequestDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gr</servlet-name>
<url-pattern>/gr</url-pattern>
</servlet-mapping>
- 测试访问
原因:我们请求/gr
,但是/gr
通过getRequestDispatcher
转发到另外一个页面,但是我们访问的路径不变,依旧是localhost:8080/s2/gr
请求转发的特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
请求转发:A想要拿到C中的资源,但是A没法与C连接,A只能与B连接,于是A对B说,B你去C里面给我拿,B就与C建立连接,C把资源给B,B再把资源给A
重定向:A连接B说想要拿到C中的资源,B对A说,你去连接C然后拿资源
2.4读取资源文件
- 在resources目录下新建db.properties
db.properties
username=root12312
password=zxczxczxc
PropertiesServlet.java
/**
* 读取资源文件properties
*/
public class PropertiesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// 思路:需要一个文件流
// 这里的路径:
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String password = prop.getProperty("password");
resp.getWriter().print(username +":"+password );
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
- 这里的路径示意图
- 因为java目录和resources目录均被打包至classes目录
- 去web.xml中配置servlet映射
<!-- 获取资源文件properties -->
<servlet>
<servlet-name>pr</servlet-name>
<servlet-class>com.kuang.servlet.PropertiesServlet</servlet-class>
</servlet>
以上是关于《遇见狂神说》Javaweb之Servlet技术的主要内容,如果未能解决你的问题,请参考以下文章