1概念
1.1 servlet概念
servlet:web端小程序,用于服务器接受请求 处理数据 给与响应的一个java模板类
:web三大组件:web项目的三个组成部分:servlet:接受请求 处理数据
fliter(过滤器):处理前的准备(预处理)+响应后的加工
listener(监听器):对域对象的生死和属性进行监控
:javaweb十三种技术规范之一
:动态资源:::需要web应用服务器解析为静态资源后 才会响应给客户端
1.2 十三种技术规范
java大师设计好用解决web开发过程中遇到的常见的问题 提出统一的 规范的 可靠的十三种解决方案
1)JDBC(Java Database Connectivity): JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDCB对数据库的访问也具有平台无关性。
2)JNDI(Java Name and Directory Interface): JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP,本地文件系统,或应用服务器中的对象。
3)EJB(Enterprise JavaBean): J2EE技术之所以赢得某体广泛重视的原因之一就是EJB。它们提供了一个框架来开发和实施分布式商务逻辑,由此很显著地简化了具有可伸缩性和高度复杂的企业级应用的开发。EJB规范定义了EJB组件在何时如何与它们的容器进行交互作用。容器负责提供公用的服务,例如目录服务、事务管理、安全性、资源缓冲池以及容错性。但这里值得注意的是,EJB并不是实现J2EE的唯一途径。正是由于J2EE的开放性,使得有的厂商能够以一种和EJB平行的方式来达到同样的目的。
4)RMI(Remote Method Invoke): 正如其名字所表示的那样,RMI协议调用远程对象上方法。它使用了序列化方式在客户端和服务器端传递数据。RMI是一种被EJB使用的更底层的协议。
5) Java IDL/CORBA: 在Java IDL的支持下,开发人员可以将Java和CORBA集成在一起。他们可以创建Java对象并使之可在CORBA ORB中展开, 或者他们还可以创建Java类并作为和其它ORB一起展开的CORBA对象的客户。后一种方法提供了另外一种途径,通过它Java可以被用于将你的新的应用和旧的系统相集成。
6) JSP(Java Server Pages): JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理,然后将生成的HTML页面返回给客户端的浏览器。
7)Java Servlet: Servlet是一种小型的Java程序,它扩展了Web服务器的功能。作为一种服务器端的应用,当被请求时开始执行,这和CGI Perl脚本很相似。Servlet提供的功能大多与JSP类似,不过实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码,而servlets全部由Java写成并且生成HTML。
8) XML(Extensible Markup Language): XML是一种可以用来定义其它标记语言的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是相互独立的,但是,它和Java具有的相同目标正是平台独立性。通过将Java和XML的组合,您可以得到一个完美的具有平台独立性的解决方案。
9)JMS(Java Message Service): MS是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。
10)JTA(Java Transaction Architecture): JTA定义了一种标准的API,应用系统由此可以访问各种事务监控。
11)JTS(Java Transaction Service): JTS是CORBA OTS事务监控的基本的实现。JTS规定了事务管理器的实现方式。该事务管理器是在高层支持Java Transaction API (JTA)规范,并且在较底层实现OMG OTS specification的Java映像。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。
12)JavaMail: JavaMail是用于存取邮件服务器的API,它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器,也支持IMAP服务器。
13) JMF(JavaBeans Activation Framework): JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成Java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF。
- 总结
1)JDBC(Java Database Connectivity): java连接数据库
2)JNDI(Java Name and Directory Interface):命名服务
3)EJB(Enterprise JavaBean): 业务逻辑分离
4)RMI(Remote Method Invoke): 远程方法调用
5) Java IDL/CORBA: 系统集成
6) JSP(Java Server Pages): 服务器端页面
7)Java Servlet: web服务器小程序
8) XML(Extensible Markup Language):存储有关系数据/配置文件
9)JMS(Java Message Service): 消息中间件
10)JTA(Java Transaction Architecture): 事务监控
11)JTS(Java Transaction Service): 事务服务。
12)JavaMail:邮件服务。
13) JMF(JavaBeans Activation Framework): 邮件附件
2 servlet的创建
注意:创建一个web项目:选中servlet版本是2.5
项目必须引入tomcat的jar
2.1 方式1:实现javax.servlet.Servlet接口
- 步骤1:创建Servlet接口的实现类
package com.zhiyou100_03.servlet;
//2.1 方式1:实现javax.servlet.Servlet接口
public class Day01Demo01 implements Servlet {
public void destroy() {
System.out.println("destroy方法:::Servlet对象的销毁:流的关闭 资源释放等");
}
public ServletConfig getServletConfig() {
System.out.println("getServletConfig方法:::获取Servlet配置信息");
return null;
}
public String getServletInfo() {
System.out.println("getServletInfo方法:::获取Servlet基本:作者 时间 版本");
return null;
}
public void init(ServletConfig arg0) throws ServletException {
System.out.println("init方法:初始化方法 servlet对象创建时要执行的代码");
}
public void service(ServletRequest requset, ServletResponse response) throws ServletException, IOException {
System.out.println("service方法:servlet的业务核心代码:接受请求 处理数据 给与响应的代码");
//接受请求参数
int a=Integer.parseInt(requset.getParameter("a"));
int b=Integer.parseInt(requset.getParameter("b"));
//设置响应体
response.getOutputStream().print("<font color='red' size='7'>"+a+"+"+b+"="+(a+b)+"</font>");
}
}
- 步骤2:在web的核心配置文件web.xml中配置此servlet的请求路径(url)
<!-- 配置Day01Demo01.java:servlet的请求路径: -->
<servlet>
<servlet-name>Day01Demo01</servlet-name> <!-- 指定当前servlet的昵称:唯一即可/实现servlet和servlet-mapper的关联 -->
<servlet-class>com.zhiyou100_03.servlet.Day01Demo01</servlet-class><!-- 指定servlet类的完整路径 -->
</servlet>
<servlet-mapping>
<servlet-name>Day01Demo01</servlet-name>
<url-pattern>/day01/d1.do</url-pattern> <!-- 指定servlet的请求路径 -->
</servlet-mapping>
- 步骤3:发布项目 浏览器请求
2.2 方式2:继承javax.servlet.GenericServlet抽象类
- 只有步骤1不同
//2.2 方式2:继承javax.servlet.GenericServlet抽象类
public class Day01Demo02 extends GenericServlet {
//根据需求重写其他方法:
//public void destroy();
//public void init(ServletConfig arg0);
//唯一需要重写的方法
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("service方法:servlet的业务核心代码:接受请求 处理数据 给与响应的代码");
//接受请求参数
int a=Integer.parseInt(request.getParameter("a"));
int b=Integer.parseInt(request.getParameter("b"));
//设置响应体
response.getOutputStream().print("<font color='red' size='7'>"+a+"+"+b+"="+(a+b)+"</font>");
}
}
2.3方式2:继承javax.servlet.http.HttpServlet类
- 只有步骤1不同
//2.3方式2:继承javax.servlet.http.HttpServlet类
public class Day01Demo03 extends HttpServlet {
//重写doget方法:接受get请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HttpServlet:service方法:servlet的业务核心代码:接受请求 处理数据 给与响应的代码");
//接受请求参数
int a=Integer.parseInt(req.getParameter("a"));
int b=Integer.parseInt(req.getParameter("b"));
//设置响应体
resp.getOutputStream().print("<font color='red' size='7'>HttpServlet:"+a+"+"+b+"="+(a+b)+"</font>");
}
//重写dopost方法:接受post请求
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.4 这三种类的关系
javax.servlet.GenericServlet是javax.servlet.Servlet接口的实现类:是抽象的
javax.servlet.http.HttpServlet是javax.servlet.GenericServlet子类:是非抽象类
javax.servlet.http.HttpServlet用于指定接受http协议的请求:::提供更多http协议相关的方法:::首选
//模拟Servlet接口、GenericServlet类、HttpServlet类的关系
interface MyServletConfig{}
interface MyServletRequest{}
interface MyServletResponse{}
//模拟Servlet接口
interface MyServlet{
public void init(MyServletConfig msc);
public void destroy();
public void service(MyServletRequest req,MyServletResponse resp);
public MyServletConfig getServletConfig();
public String getServletInfo();
}
//模拟GenericServlet类
abstract class MyGenericServlet implements MyServlet{
public void init(MyServletConfig msc){
System.out.println("init 初始化方法!");
}
public void destroy(){
System.out.println("destroy 销毁方法!");
}
public MyServletConfig getServletConfig(){
System.out.println("init 初始化方法!");
return null;
}
//service依然是抽象的
public String getServletInfo(){
System.out.println("init 初始化方法!");
return null;
}
}
interface MyHttpServletRequest extends MyServletRequest{
public String getMethod();
}
interface MyHttpServletResponse extends MyServletResponse{}
//模拟HttpServlet类
class MyHttpServlet extends MyGenericServlet{
//实现父类的抽象方法
public void service(MyServletRequest req,MyServletResponse resp){
MyHttpServletRequest httpReq=(MyHttpServletRequest)req;
MyHttpServletResponse httpResp=(MyHttpServletResponse)resp;
service(httpReq,httpResp);
}
//特有方法
public void service(MyHttpServletRequest req,MyHttpServletResponse resp){
if(req.getMethod().equalsIgnoreCase("get")){
doGet(req, resp);
}
if(req.getMethod().equalsIgnoreCase("post")){
doGet(req, resp);
}
}
//特有方法
public void doGet(MyHttpServletRequest req,MyHttpServletResponse resp){}
//特有方法
public void doPost(MyHttpServletRequest req,MyHttpServletResponse resp){}
}
3 Servlet的生命周期
生命周期:servlet对象的创建到销毁的整个过程
3.1 准备工作
public class Day02Demo02LifeCycle implements Servlet {
//构造代码块:每创建一个对象 构造代码块执行一次
{
System.out.println("构造代码块!!!");
}
public void destroy() {
System.out.println(this+"destroy方法:::Servlet对象的销毁:流的关闭 资源释放等");
}
public ServletConfig getServletConfig() {
System.out.println(this+"getServletConfig方法:::获取Servlet配置信息");
return null;
}
public String getServletInfo() {
System.out.println(this+"getServletInfo方法:::获取Servlet基本:作者 时间 版本");
return null;
}
public void init(ServletConfig arg0) throws ServletException {
System.out.println(this+"init方法:初始化方法 servlet对象创建时要执行的代码");
}
public void service(ServletRequest requset, ServletResponse response) throws ServletException, IOException {
System.out.println(this+"service方法:servlet的业务核心代码:接受请求 处理数据 给与响应的代码");
}
}
<!-- 配置Day02Demo02LifeCycle.java:servlet的请求路径: -->
<servlet>
<servlet-name>Day022</servlet-name> <!-- 指定当前servlet的昵称:唯一即可/实现servlet和servlet-mapper的关联 -->
<servlet-class>com.zhiyou100_03.servlet.Day02Demo02LifeCycle</servlet-class><!-- 指定servlet类的完整路径 -->
<!-- load-on-startup指定servlet对象在tomcat启动时创建:文本是创建顺序 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Day022</servlet-name>
<url-pattern>/day02/s2.do</url-pattern> <!-- 指定servlet的请求路径:必须以/开头 -->
</servlet-mapping>
-
没有设置load-on-startup:对象在第一次请求时才创建
-
设置了load-on-start:对象在tomcat启动时就创建了
3.2 第一步:对象创建
默认情况下,tomcat第一次接收到对servlet的请求时 会自动创建servlet的单例对象
如果在servlet配置了load-on-startup,tomcat启动时会创建此servlet对象
3.3 第二步:对象初始化:init
servlet对象一创建 tomcat就会立刻调用servlet对象的init方法 对对象进行初始化 读取配置文件中的信息
3.4 第三步:处理请求(服务):service
servlet对象每被请求一次:
tomcat会为本次请求创建一个ServletRequest对象和ServletResponse对象来分别装本次服务请求相关的信息和响应相关的信息
tomcat就会调用此servlet的service方法,并传递请求对象和响应对象:来接受请求 处理数据 给与响应
3.5 第四步:对象销毁:destroy
tomcat在关闭前 会调用servlet的destroy方法 来销毁对象 释放资源
注意
servlet是单例 不建议定义实例变量
4 真实开发流程
4.1 可行性分析
* 成本分析
* 时间分析
* 人力分析
* 技术分析
4.2 需求分析
* 通过与客户的交流:把客户的需求和整个业务流程 摸清楚 写成文档
4.3 页面模型
ui和h5联合 实现页面:功能+假数据
4.4 数据库设计
表关系的设计:关系项目性能和开发效率
4.5 框架搭建
集中式/分布式:
技术选型:
模块划分:关联强度比较高的几个功能 分成一个模块 交给同一个组进行开发
4.6 功能开发
逐个功能实现+单元测试
4.7 整体测试
模块整合
模拟生成环境
bug测试:::测试
4.8 项目交付
要求客户提供服务器/云服务器 进行环境搭建 项目部署:::运维
4.9 项目维护和扩展
5 servlet实现登录业务
5.1 创建数据库
DROP DATABASE db_3;
CREATE DATABASE db_3 CHARSET='utf8';
USE db_3;
CREATE TABLE USER(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(11) UNIQUE,
upwd VARCHAR(10) DEFAULT '123456',
usex CHAR(1),
uscore INT
);
INSERT INTO USER VALUES(
NULL,
SUBSTRING(REPLACE(UUID(),'-',''),3,10),
'123456',
IF(RAND()>0.5,'男','女'),
TRUNCATE(RAND()*100,0)
);
SELECT * FROM USER;
ALTER TABLE USER ADD ucome DATETIME;
UPDATE USER SET ucome=NOW();
5.2 创建项目 搭建框架
创建web项目
引入tomcat
5.3 分包
5.4 创建实体类
public class User implements Serializable{
private Integer uid;
private String uname;
private String upwd;
private String usex;
private Integer uscore;
private Date ucome;
...
}
5.5 工具类
package com.zhiyou100.util;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
private static final String PATTERN="yyyy年MM月dd号 HH:mm:ss";
private static SimpleDateFormat sdf=new SimpleDateFormat(PATTERN);
public static String date2Str(Date date){
return sdf.format(date);
}
public static Date str2Date(String str){
try {
return sdf.parse(str);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public class JdbcUtil {
private static String driver,user,pwd,url;
static{
driver="com.mysql.jdbc.Driver";
url="jdbc:mysql://localhost:3306/db_3?characterEncoding=utf-8";
user="root";
pwd="root";
}
static{
try {
Class.forName(driver);
} catch (Exception e) {
throw new RuntimeException(driver);
}
}
public static Connection getCon(){
try {
return DriverManager.getConnection(url, user, pwd);
} catch (Exception e) {
throw new RuntimeException(driver);
}
}
public static void close(Connection con,Statement sta,ResultSet set){
try {
if(set!=null)set.close();
if(sta!=null)sta.close();
if(con!=null)con.close();
} catch (Exception e) {
throw new RuntimeException(driver);
}
}
}
5.6 dao开发
package com.zhiyou100.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.zhiyou100.entity.User;
import com.zhiyou100.util.JdbcUtil;
public class UserDao {
public User getOneByUname(String uname){
Connection con=JdbcUtil.getCon();//获取连接
PreparedStatement pre=null;
ResultSet set=null;
User user=null;
try {
pre=con.prepareStatement("select * from user where uname=?");//创建预编译对象 关联sql模板
pre.setString(1, uname);//占位符赋值
set=pre.executeQuery();//执行sql
if(set.next()){//解析结果集
user=new User(
set.getInt("uid"),
set.getString("uname"),
set.getString("upwd"),
set.getString("usex"),
set.getInt("uscore"),
set.getTimestamp("ucome"));
}
} catch (Exception e) {
JdbcUtil.close(con, pre, set);
}
return user;
}
}
5.7 action
package com.zhiyou100.action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhiyou100.dao.UserDao;
import com.zhiyou100.entity.User;
public class UserLoginAction extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1 设置请求编码集
req.setCharacterEncoding("utf-8");
//2 获取请求参数
String uname=req.getParameter("uname");
String upwd=req.getParameter("upwd");
//3 访问数据库 处理数据
UserDao dao=new UserDao();
User dbUser=dao.getOneByUname(uname);
//4 设置响应体
String message="";
if(dbUser==null){
message="用户名错误!";
}else if(!(dbUser.getUpwd().equals(upwd))){
message="密码错误!";
}else{
message="登录成功!"+dbUser;
}
//拼凑页面
resp.setCharacterEncoding("utf-8");//设置响应编码集
resp.setContentType("text/html;charset=utf-8");
message=message.contains("错误")?("<font color='red' size='7'>"+message+"</font>"):("<font color='blue' size='7'>"+message+"</font>");
resp.getWriter().print(message);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>user_login</servlet-name>
<servlet-class>com.zhiyou100.action.UserLoginAction</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>user_login</servlet-name>
<url-pattern>/user/login.action</url-pattern>
</servlet-mapping>
5.8 创建页面:
- 页面:/html/user_login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="../css/user_login.css"/>
<link type="text/css" rel="stylesheet" href="http://localhost:8080/java43_project_servlet_01/css/user_login.css"/>
</head>
<body>
<form action="http://localhost:8080/java43_project_servlet_01/user/login.action" method="get">
<table>
<tr>
<th>用户:</th>
<td><input type="text" name="uname"/></td>
</tr>
<tr>
<th>密码:</th>
<td><input type="text" name="upwd"/></td>
</tr>
<tr>
<th colspan="2">
<input type="reset" value="重填"/> |
<input type="submit" value="登录"/>
</th>
</tr>
</table>
</form>
</body>
</html>
- css:/css/user_login.css
table{
border:1px solid blue;
border-collapse: collapse;
width:800px;
margin:100px auto;
}
td,th{
border:1px solid blue;
padding:10px;
}