Servlet
文章目录
- Servlet
- 1.概述
- 2.Servlet接口
- 3.Servlet快速入门(掌握)
- 4.Servlet生命周期(熟悉)
- 5.使用便捷类(掌握)
- 6.Servlet的其它操作
- 6.1.Servlet自动加载(了解)
- 6.2.Servlet路径通配符(了解)
- 6.3.默认Servlet(掌握)
- 6.4.Servlet多重映射(了解)
- 6.4.1.方式一:配置多个servlet-mapping
- 7.登陆案例(掌握)
- 8.统计网站访问次数(掌握)
- 9.ServletContext获取资源(了解)
- 4.三层架构&MVC(理解)
- 5.ServletConfig(了解)
1.概述
随着Web应用业务需求的增多,动态Web资源的开发变得越来越重要。目前,很多公司都提供了开发动态Web资源的相关技术,其中比较常见的有ASP、PHP、JSP和 Servlet等。
基于Java的动态Web资源开发,Sun公司提供了 Servlet和JSP两种技术接下来,接下来我们将学习Servlet的使用
2.Servlet接口
针对 Servlet 技术的开发,Sun公司提供了一系列接口和类,其中最重要的是javax.servlet. Servlet接口,Servlet就是一种实现了 Servlet 接口的类,它是由Web容器负责创建并调用,用于接收和响应用户的请求。在 Servlet 接口中定义了5个抽象方法,具体如下:
方法 | 功能 |
---|---|
void init(ServletConfig config) | 创建好Servlet对象后,会调用此方法,负责Servlet初始化工作 |
ServletConfig getServletConfig() | 获取ServletConfig对象 |
String getServletInfo() | 返回Servlet的信息 |
void service() | 当容器接收到客户端的请求时,就会调用此方法,在该方法里,可以使用ServletRequest、ServletResponse,对象处理请求和响应 |
void destroy() | Servlet对象被销毁时,此方法会被调用 |
3.Servlet快速入门(掌握)
3.1.第一步:编写一个类,实现Servlet接口
编写一个类,实现Servlet接口,重写5个方法。并在service() 方法里面添加输出
注意:这里的输出方向有两个了:
1.控制台:System.out.println("Hello Servlet");
2.浏览器:response.getWriter().write("Hello Service!!!");
public class HelloServlet implements Servlet {
@Override
public void destroy() {}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void init(ServletConfig config) throws ServletException {}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
//这是向控制台输出
System.out.println("Hello Servlet");
//向浏览器输出
response.getWriter().write("Hello Service!!!");
}
}
3.2.第二步:配置
在WebContent -> WEB-INF,web.xml
文件下添加配置信息
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 先配置Servlet信息 -->
<servlet>
<!-- 配置Servlet名称,名称必须唯一 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置Servlet的完整类名(包名+类名) -->
<servlet-class>com.jf.weidong.HelloServlet</servlet-class>
</servlet>
<!-- 配置Servlet映射(访问路径) -->
<servlet-mapping>
<!-- 配置Servlet名称,值必须和<servlet-name>标签相同 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置访问该Servlet的虚拟路径,正斜线(/)表示当前Web应用程序根目录 -->
<url-pattern>/helloservlet</url-pattern>
</servlet-mapping>
</web-app>
3.3.访问
访问的路径为:localhost:8080/项目名/servlet名字(url-patten节点配置的名字)
如上面的示例,路径为:http://localhost:8080/HelloServlet/helloservlet
输出结果:
4.Servlet生命周期(熟悉)
在Java中,任何对象都有生命周期,Servlet也不例外
Servlet生命周期图
Servlet生命周期三个阶段
阶段一:初始化阶段(单例设计模式)
Servlet接收到请求后,会先检查内存中是否有该Servlet对象,如果有直接使用该对象,如果没有就创建实例,后调用init()方法,需要注意,在Servlet的整个生命周期内,它的init() 方法只会调用一次。
阶段二:运行阶段
Servlet生命周期中最主要的阶段,该阶段会为这个请求创建ServletRequest
对象和ServletResponse
对象,然后传递给service()方法,在整个Servlet生命周期内,每一次访问请求,都会创建新的ServletRequest
和ServletResponse
对象。并且调用service()方法
阶段三:销毁阶段
Servlet随着Web应用的销毁而销毁,在销毁Servlet之前,Servlet的destroy() 方法会被调用,在该方法里面可以进行资源释放操作,destroy()只会被调用一次,需要注意的是Servlet对象一旦被创建就会驻留在内存中,直到服务器关闭。
示例代码:
public class ServletDemo_life implements Servlet{
/**
* Servlet实例被创建后,调用init方法进行初始化
* Servlet什么时候被创建呢?
* * 不是服务器一启动时,实例被创建,第一次访问的时候,实例才被创建。
* init方法调用几次呢?
* * 只被调用一次。
*/
public void init(ServletConfig config) throws ServletException {
System.out.println("init...");
}
/**
* service调用几次?
* * 有一次请求,调用一次service方法
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
System.out.println("service...");
}
/**
* Servlet实例什么时候被销毁?
* * 服务器关闭,手动移除。
* destroy调用几次
* * 一次
*/
public void destroy() {
System.out.println("destroy...");
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
}
打印
5.使用便捷类(掌握)
由于大多数Web应用都是通过HTTP和客户端进行交互,因此,在 Servlet接口中,提供了一个抽象类javax. servlet.http. HttpServlet,它是 GenericServlet的子类,专门用于创建应用于HTTP的 Servlet
5.1.HttpServlet类
抽象类,专门用于处理HTTP请求的Servlet
主要功能
- 1.根据用户请求方式不同,定义相应的doXxx()方法处理用户请求。
- 2.通过service()方法将HTTP请求和响应分别转为HttpServletRequest和HttpServletResponse类型的对象
使用步骤:
- 1.新建类,基础HttpServlet
- 2.重写doGet、doPost方法
- 3.在web.xml文件中配置
示例:
编写一个类,继承HttpServlet类,演示doGet和doPost方法调用时机
类
public class HttpServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("this is doGet !!!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("this is doPost !!!");
}
}
配置web.xml
<servlet>
<servlet-name>HttpServletDemo</servlet-name>
<servlet-class>com.jf.weidong.HttpServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpServletDemo</servlet-name>
<url-pattern>/HttpServletDemo</url-pattern>
</servlet-mapping>
测试doGet方法
采用GET方式访问HttpServletDemo
,只需要在地址栏输入HttpServletDemo访问地址即可打印this is doGet !!!
测试doPost方法
采用POST就必须使用表单了,创建表单提交html文件,设置提交数据到HttpServletDemo
即可,主要代码如下:
<form action="/HelloServlet/HttpServletDemo" method="post">
姓名:<input type="text" name="name">
</p>
年龄:<input type="text" name="name">
</p>
<input type="submit" value="提交">
</form>
访问效果
6.Servlet的其它操作
6.1.Servlet自动加载(了解)
有时候我们希望某些Servlet可以在Tomcat启动时随即启动,可以通过使用<load-on-startup>
来完成
<load-on-startup>
元素是<servlet>
的一个子元素,用于指定Servlet被加载的时机和顺序。
使用方式
<servlet>
<!-- 配置Servlet名称,名称必须唯一 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置Servlet的完整类名(包名+类名) -->
<servlet-class>com.jf.weidong.HelloServlet</servlet-class>
<load-on-startup><!-- 值是正整数,值越小,越先被加载。 -->1</load-on-startup>
</servlet>
6.2.Servlet路径通配符(了解)
我们希望每个目录下的所有路径都可以访问同一个Servlet,这时,可以在Servlet映射的路径中使用通配符“*”
通配符的格式分为
格式为“ .扩展名 ”,例如“ .c ”匹配以“ .c ”结尾的所有URL地址
格式为“ / ”,例如 “ /abc/ ” 匹配以“ /abc ”开始的所有URL地址
通配符优先级
有如下映射关系
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 .do
当请求URL为/abc/a.html
,“/abc/”和“/”都匹配,Servlet1响应
当请求URL为/abc
时,“/abc/”和“/abc”都匹配,Servlet3响应
当请求URL为/abc/a.do
时,“/abc/”和“.do”都匹配,Servlet1响应
当请求URL为/a.do
时,“/”和“.do”都匹配,Servlet2响应
当请求URL为/xxx/yyy/a.do
时,“/”和“.do”都匹配,Servlet2响应
6.3.默认Servlet(掌握)
如果某个Servlet的映射路径仅仅是一个正斜线(/),那么这个Servlet就是当前Web应用的默认Servlet,默认Servlet用于处理其它Servlet都不处理的访问请求。
如下配置,Servlet服务器在接收访问请求时,如果再web.xml文件中找不到匹配的
<servlet-mapping>元素的URL,就会将访问请求交给默认Servlet处理
<servlet>
<servlet-name>DefaultServlet</servlet-name>
<servlet-class>com.jf.weidong.DefaultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DefaultServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
6.4.Servlet多重映射(了解)
Servlet的多重映射指的是同一个 Servlet可以被映射成多个虚拟路径。也就是说客户端可以通过多个路径实现对同一个 Servlet的访问。配置方式有两种
6.4.1.方式一:配置多个servlet-mapping
如下代码,HttpServletDemo被映射到两个路径中,分别为:httpservletdemo1、httpservletdemo2
<!-- 第一个路径配置 -->
<servlet-mapping>
<servlet-name>HttpServletDemo</servlet-name>
<url-pattern>/httpservletdemo1</url-pattern>
</servlet-mapping>
<!-- 第一个路径配置 -->
<servlet-mapping>
<servlet-name>HttpServletDemo</servlet-name>
<url-pattern>/httpservletdemo2</url-pattern>
</servlet-mapping>
6.4.2.方式二:多个url-mapping
<servlet-mapping>
<servlet-name>HttpServletDemo</servlet-name>
<url-pattern>/httpservletdemo1</url-pattern>
<url-pattern>/httpservletdemo2</url-pattern>
</servlet-mapping>
7.登陆案例(掌握)
在页面上输入用户名和密码,提交到服务器上,服务器拿着用户名和密码去数据库中查找有无此用户
若有用户,则提示登录成功
若无此用户,则提示用户名密码不匹配
技术分析:
- 表单
- servlet
- 请求(request)
- 响应(response)
7.1.登陆-表单
表单主要负责
- 收集用户数据
- 所有的字段要想提交到服务器必须有 name 属性
- 提交的地址:action
- 请求方式:post
7.2.登陆-Servlet
注意:此处用到了Request和Response对象,目前先不要深究这两个对象
编写处理登陆操作的Servlet,在此Servlet里面需要进行如下操作
1.接受参数:参数格式为key=value Sting value=request.getParameter("key")
例如:
http://localhost/day09/hello?username=tom request.getParameter("username")
就可以获取tom值
2.回写内容(给客户端响应)
需要用到response response.getWriter().print("success");
可能会遇到乱码问题,处理中文乱码
resp.setContentType("text/html;charset=utf-8");
//建议大家放在方法中的第一行
7.3.登陆-实现步骤
前期准备:
- 使用数据库存储用户数据
- 使用c3p0链接池,需要给出c3p0的配置文件
- 使用dbutils简化数据库操作
- 以上,所以需要导入三个jar包,将jar包拷贝到WebContent\lib目录下,如下图所示
c3p0配置文件
<c3p0-config>
<!-- 命名的配置 -->
<named-config name="jf">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb1</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
7.3.1.添加数据库和数据
//初始化数据:
-- 用户表(user)
CREATE TABLE user(
id VARCHAR(255) NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR (20) DEFAULT NULL,
password VARCHAR (20) DEFAULT NULL
);
INSERT INTO `user` VALUES ('dkdkd', 'admin', '123456');
7.3.2.创建登陆界面
action:设置表单提交的地址
提交方式为post
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div align="center">
<form action="http://localhost:8080/LoginDemo//login" method="post">
用户名:<input type="text" name="username" /><br /> 密码:
<input type="text" name="password" /><br />
<input type="submit" value="登陆" />
</form>
</div>
</body>
</html>
7.3.3.创建LoginServlet
LoginServlet里面主要处理用户提交过来的数据,以及给出响应
为了方便测试,现需要获取表单提交过来的用户名和密码数据,如下代码(只给出doPost方法代码)
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 设置编码
response.setContentType("text/html;charset=utf-8");
// 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username: " + username);
System.out.println("password: " + password);
}
7.3.4.测试登陆界面和LoginServlet是否工作
访问登陆界面(地址是情况而定)
地址为:http://localhost:8080/LoginDemo/login.html
点击登陆按钮,查看控制台是否有输出
成功取到了提交过来的值
7.3.5.编写查询数据库逻辑
获取到提交过来的数据后,就需要查询数据库,看是否和数据库的数据匹配,并返回对应的结果
此时如果将查询数据库的代码写到LoginServlet类中,那么会造成LoginServlet非常臃肿,而且后期维护起来也非常困难
那有什么比较好的方式呢?
WEB三层架构
三层架构中的包结构
7.3.5.1.User实体类
三层架构一般都是从实体类开始写,在domain包中,新建User实体类,用来封装数据库查询到的数据
/**
* 用户信息类
* @author weidong
*/
public class User {
/*
id varchar(255) primary key auto_increment,
username varchar(20),
password varchar(20),
*/
private String id;
private String username;
private String password;
//为了篇幅,省略get/set方法
}
7.3.5.2.UserDao
编写好User类后,再在dao包下新建UserDao类,并添加查询数据库的方法,方法返回查询到的用户信息,如下代码所示
/**
* 操作用户信息的Dao
* @author weidong
*/
public class UserDao {
/**
* 登录
* @param username 用户名
* @param password 密码
* @return 用户对象
* @throws SQLException
*/
public User getUserByUsernameAndPwd(String username, String password) throws SQLException {
// 创建queryrunner
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
// 编写sql
String sql = "select * from user where name = ? and password = ?";
// 执行sql
User user = qr.query(sql, new BeanHandler<>(User.class), username, password);
return user;
}
}
写好dao后,建议先进行测试(初期开发建议多测试),使用JUnit测试即可,新建测试类,编写测试方法,代码如下:
public class DaoTest {
@Test
public void t1(){
UserDao userDao = new UserDao();
try {
User user = userDao.getUserByUsernameAndPwd("lisi", "123456");
System.out.println(user);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果
7.3.5.3.UserService
编写好UserDao后,再编写业务逻辑层,现阶段登陆不考虑其它业务逻辑,所以不做过多的操作,添加login方法,并返回User对象,创建UserDao的实例,并调用查询的方法,代码如下
/**
* 业务层
* @author weidong
*/
public class UserService {
/**
* 用户登录
* @param username 用户名
* @param password 密码
* @return User 用户
* @throws SQLException
*/
public User login(String username, String password) throws SQLException{
//调用dao
UserDao dao=new UserDao();
return dao.getUserByUsernameAndPwd(username,password);
}
}
7.3.5.4.LoginServlet
编写好UserService类后,接下来就需要改动LoginServlet类了,在该类里面,需要实例化UserService,并调用响应的业务逻辑(login)方法获取到用户对象,并判断
如果用户对象为空,表示登陆失败(没有查询到数据)
如果用户对象不为空,表示登陆成功
关键代码如下:
如果User对象为空,那么直接使用response对象输出数据
User user = null;
try {
user = new UserService().login(username, password);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("网络异常,请稍后再试!");
}
// 3.判断user是否为空
if (user == null) {
// 若为空 写"用户名和密码不匹配"
response.getWriter().print("用户名和密码不匹配");
} else {
// 若不为空 写"xxx:欢迎回来"
response.getWriter().print(user.getUsername()+ ":欢迎回来");
}
完整代码
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置编码
response.setContentType("text/html;charset=utf-8");
// 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username: " + username);
System.out.println("password: " + password);
// 调用userservice 里的login(username,password) 返回值:User user
User user = null;
try {
user = new UserService().login(username, password);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("网络异常,请稍后再试!");
}
// 3.判断user是否为空
if (user == null) {
// 若为空 写"用户名和密码不匹配"
response.getWriter().print("用户名和密码不匹配");
} else {
// 若不为空 写"xxx:欢迎回来"
response.getWriter().print(user.getUsername()+ ":欢迎回来");
}
}
}
测试-登陆成功
测试-登陆失败
7.3.6.添加定时返回功能
登陆失败后,需要添加【5秒后自动跳回登陆界面】的功能,此时就需要用到Refresh响应头
refresh 属性值:刷新与跳转(重定向)页面
refresh用于刷新与跳转(重定向)页面
refresh出现在http-equiv属性中,使用content属性表示刷新或跳转的开始时间与跳转的网址
在登陆失败的代码里面添加此响应头,5为时间值,url=xxx为跳转的地址。
运行效果
8.统计网站访问次数(掌握)
在一个用户登录成功之后,获取之前登录成功总人次,将次数+1,
并提供另外一个Servlet,显示登录成功的总人次
想要在Servlet中存储一些数据,可以使用ServletContext类
8.1.ServletContext
当 Servlet 容器启动时,会为每个 Web 应用创建一个唯一的 ServletContext对象代表当Web 应用,该对象不仅封装了当前 Web 应用的所有信息,而且实现了多个 Servlet 之间数据的共享。
服务器关闭的时候或者项目从服务器中移除 ServletContext 才会被销毁,如果将值保存在ServletContext中,值就有一个作用的范围,所以这个对象被称为”域对象”.
方法说明 | 功能描述 |
---|---|
getAttributeNames() | 获取放在ServletContext中所有的属性名 |
getAttribute(String name) | 根据指定的属性名返回一个与之匹配的与属性值 |
removeAttribute(String name) | 根据指定的域属性名,从ServletContext中删除匹配的域属性 |
setAttribute(String key,String value) | 往ServletContext存入数据 |
8.2.实现步骤
- 1.编写一个Servlet中的init方法,在init方法中初始化一个被登录次数0,将这个值存入到ServletContext域中,配置Servlet的load-on-startup(加载优先级)
- 2.在登录成功代码中获得原来的次数+1,并再次回存到ServletContext域中
- 3.登陆成功,访问CountServlet,从ServletContext域中获得次数,并且显示到页面上
8.3.代码实现
新建LoginServlet类,重写init()方法,在方法中初始化访问次数
public void init(ServletConfig config) throws ServletException {
// 获得ServletContext对象,初始化一个值为0.
ServletContext servletContext = this.getServletContext();
servletContext.setAttribute("count", 0);
}
在登录成功的代码中获得原来的次数并且+1,回存到ServletContext域中。(主要代码)
// 3.判断user是否为空
if (user == null) {
// 若为空 写"用户名和密码不匹配"
response.getWriter().print("用户名和密码不匹配,5秒后自动跳转登陆界面");
response.setHeader("refresh", "5;url=/LoginDemo/login.html");
} else {
// 若不为空 写"xxx:欢迎回来"
response.getWriter().print(user.getUsername() + ":欢迎回来");
// 在登录成功的代码中获得原来的次数并且+1,存回到SErvletContext域中。
// 登录成功的时候 获得原来的次数 + 1
Integer count = (Integer) this.getServletContext().getAttribute("count");
// 存回到ServletContext域中
this.getServletContext().setAttribute("count", ++count);
}
显示登陆人数
public class CountServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置编码
response.setContentType("text/html;charset=utf-8");
// 获取全局管理者
ServletContext context = this.getServletContext();
// 获取登录的次数
Integer count = (Integer) context.getAttribute("count");
// 在页面上打印总次数
response.getWriter().print("登录成功的总次数为:" + count);
}
}
不要忘记配置
<servlet>
<servlet-name>CountServlet</servlet-name>
<servlet-class>com.jf.weidong.web.servlet.CountServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CountServlet</servlet-name>
<url-pattern>/countServlet</url-pattern>
</servlet-mapping>
测试
9.ServletContext获取资源(了解)
有时候希望读取Web应用中的一些资源文件,如配置文件、图片、文本等,在ServletContext接口中定义了一些读取Web资源的方法,这些方法是依靠Servlet容器来实现的。
方法说明 | 功能描述 |
---|---|
Set getResourcePaths(String path) | 返回一个Set集合,集合中包含资源目录中子目录和文件的路径名称参数path必须以正斜线(/)开始,指定匹配资源的部分路径 |
String getRealPath(String path) | 返回资源文件在服务器文件系统上的真实路径(文件的绝对路径)。参数path代表资源文件的虚拟路径,它应该以正斜线(/)开始,“/”表示当前Web(WebContent)应用的根目录,如果 Servlet容器不能将虚拟路径转换为文件系统的真实路径,则返回null |
URL getResource(String path) | 返回映射到某个资源文件的URL对象。参数path必须以正斜线(/)开始,“/”表示当前Web应用的根目录 |
InputStrean getResourceAsStream() | 返回映射到某个资源文件的 InputStrean输入流对象,参数path传递规则和getResource()方法完全一致 |
示例代码
在src目录下创建一个资源文件(c3p0.properties),填入以下内容
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc
c3p0.user=root
c3p0.password=123456
注意:Eclipse/IDEA中 src 目录下创建的资源文件在Tomcat服务器启动时会被复制到WEB-INF/classes目录下
/**
* 默认方式读取
*/
public class ServletContextReadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
ServletContext context = getServletContext();
// 加载配置文件
// InputStream in =
// context.getResourceAsStream("/WEB-INF/classes/c3p0.properties");
// Properties properties = new Properties();
// properties.load(in);
// 写法二:获取文件的路径
String path = context.getRealPath("/WEB-INF/classes/c3p0.properties");
// 加载配置文件
InputStream in = new FileInputStream(path);
Properties properties = new Properties();
properties.load(in);
String s = properties.getProperty("c3p0.driverClass") + " " + properties.getProperty("c3p0.jdbcUrl") + " "
+ properties.getProperty("c3p0.user") + " " + properties.getProperty("c3p0.password");
PrintWriter writer = response.getWriter();
writer.println(s);
}
}
4.三层架构&MVC(理解)
三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为
界面层(User Interface layer)
业务逻辑层(Business Logic Layer)
数据访问层(Data access layer)。
区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。
4.1.三层架构划分
1.数据访问层DAO:主要看数据层里面有没有包含逻辑处理,实际上它的各个函数主要完成各个对数据文件的操作。而不必管其他操作。
2.业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
3.表示层(界面层):主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。
包名一般为:
- dao:数据访问层()
- domain:管理javaBean实体对象(也可称为信息资源层)
- service:业务逻辑层,通过使用dao层来对数据库进行操作
- web:数据显示层
4.2.MVC模式
MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。
这个模式认为,程序不论简单或复杂,从结构上看,都可以分成三层。
视图层(View)
数据层(Model)
控制层(Controller)
MVC并不是Java当中独有的,几乎所有的B/S的架构都采用了MVC框架模式,但是MVC在B/S架构中并没有完全地实现,其实我们根本不需要掌握未实现的部分。
1.控制层Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发;
2.视图层View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等。
3.模型层Model:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受视图数据的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心
在这里插入图片描述
4.3.三层架构和MVC关系
三层架构是引用的体系(分层)结构,描述了整个引用的完整划分
MVC是一个设计模式,通常用于三层架构的展示层构建上。
5.ServletConfig(了解)
在Servlet运行期间,经常需要一些铺助信息,例如:程序的编码格式、用户名和密码等,这些信息可以在web.xml文件中使用 元素进行配置。
使用方法
<init-param>
<!--- 节点参数名称 --->
<param-name>username</param-name>
<!--- 参数值 --->
<param-value>root</param-value>
</init-param>
ServletConfig 常用方法
String getInitParameter(String name)
:通过初始化参数name获取配置文件中初始化参数的value
Enumeration getInitParameterNames()
:获取初始化参数的名称们
String getServletName()
:获取Servlet名称
演示使用ServletConfig获取初始化信息
<servlet>
<servlet-name>ServletInitParam</servlet-name>
<servlet-class>com.jf.weidong.ServletInitParam</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletInitParam</servlet-name>
<url-pattern>/ServletInitParam</url-pattern>
</servlet-mapping>
Servlet
/**
* 演示使用初始化参数
* @author weidong
*/
public class ServletInitParam extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig config = this.getServletConfig();// 获取ServletConfig对象
// 获取参数名字为encoding对呀参数值
String encoding = config.getInitParameter("encoding");
resp.getWriter().write(encoding);
}
}