
本文共 5583 字,大约阅读时间需要 18 分钟。
Servlet&Tomcat
Servlet
res.setCharacterEncoding("utf-8");//第一句,设置服务器端编码 res.setContentType("text/html;charset=UTF-8");//第二句,设置浏览器端解码
java.lang、java.util、java.sql、javax.servlet
这里java和javax的区别:同属于jdk,java是属于最基础的那套东西,javax是后来扩展的一些东西。
-
客户端没有权限直接访问WEB-INF里面的内容。
-
浏览器不能直接访问 Servlet ⽂件,只能通过映射的⽅式来间接访问 Servlet,映射需要开发者⼿动配置,有两种配置⽅式。
-
基于 XML ⽂件的配置⽅式。
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.southwind.servlet.HelloServlet</servlet-class></servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/demo2</url-pattern></servlet-mapping>
- 基于注解的⽅式。
@WebServlet("/demo2")public class HelloServlet implements Servlet { }
上述两种配置⽅式结果完全⼀致,将 demo2 与 HelloServlet 进⾏映射,即在浏览器地址栏中直接访问demo 就可以映射到 HelloServlet。
Servlet 的⽣命周期
1、当浏览器访问 Servlet 的时候,Tomcat 会查询当前 Servlet 的实例化对象是否存在,如果不存在,则通过反射机制动态创建对象,如果存在,直接执⾏第 3 步
。
2、调⽤ init ⽅法完成初始化操作。
3、调⽤ service ⽅法完成业务逻辑操作。
4、关闭 Tomcat 时,会调⽤ destory ⽅法,释放当前对象所占⽤的资源。
Servlet 的⽣命周期⽅法:⽆参构造函数、init、service、destory
1、⽆参构造函数只调⽤⼀次,用来创建对象。
2、init 只调⽤⼀次,初始化对象。
3、service 调⽤ N 次,执⾏业务⽅法。
4、destory 只调⽤⼀次,卸载对象。
Servlet 的层次结构
Servlet —》GenericServlet —〉HttpServlet
HTTP 请求有很多种类型,常⽤的有四种:
GET 读取 POST 保存 PUT 修改 DELETE 删除
JSP
jsp本质上就是servlet
具体的嵌⼊⽅式有 3 种:
1、JSP 脚本,执⾏ Java 逻辑代码
<% Java代码 %>
2、JSP 声明:定义 Java ⽅法
<%! 声明 Java ⽅法%>
3、JSP 表达式:把 Java 对象直接输出到 HTML ⻚⾯中
<%=Java变量 %>
demo
<%! public String test(){ return "HelloWorld"; }%><%String str = test();%><%=str%>
JSP内置对象 9 个
- 1、request:表示⼀次请求,HttpServletRequest。
- 2、response:表示⼀次响应,HttpServletResponse。
- 3、pageContext:⻚⾯上下⽂,获取⻚⾯信息,PageContext。
- 4、session:表示⼀次会话,保存⽤户信息,HttpSession。
- 5、application:表示当前 Web 应⽤,全局对象,保存所有⽤户共享信息,ServletContext。
- 6、config:当前 JSP 对应的 Servlet 的 ServletConfig 对象,获取当前 Servlet 的信息。
- 7、out:向浏览器输出数据,JspWriter。
- 8、page:当前 JSP 对应的 Servlet 对象,Servlet。
- 9、exception:表示 JSP ⻚⾯发⽣的异常,Exception。
常⽤的是 request、response、session、application、pageContext
req.getParameter():表示冲客户端获取参数 req.getAttribute():表示从后台域获取数据
请求转发和重定向:
转发是将同⼀个请求传给下⼀个⻚⾯,重定向是创建⼀个新的请求传给下⼀个⻚⾯,之前的请求结束⽣命周期。
转发:同⼀个请求在服务器之间传递,地址栏不变,也叫服务器跳转(同一个请求,同一个request
)。
重定向:由客户端发送⼀次新的请求来访问跳转后的⽬标资源,地址栏改变,也叫客户端跳转(两次请求
)。
如果两个⻚⾯之间需要通过 request 来传值,则必须使⽤转发,不能使⽤重定向。
⽤户登录,如果⽤户名和密码正确,则跳转到⾸⻚(转发),并且展示⽤户名,否则重新回到登陆⻚⾯(重定向)
session会话
会话:就是客户端和服务器之间发⽣的⼀系列连续的请求和响应的过程,打开浏览器进⾏操作到关闭浏览器的过程。
Cookie
Cookie 是服务端在 HTTP 响应中附带传给浏览器的⼀个⼩⽂本⽂件,⼀旦浏览器保存了某个 Cookie,在之后的请求和响应过程中,会将此 Cookie 来回传递,这样就可以通过 Cookie 这个载体完成客户端和服务端的数据交互。
服务器停止cookie依然存在
JSP 内置对象作⽤域
4个
page < request < session < application
page 只在当前⻚⾯有效。
request 在⼀次请求内有效。
session 在⼀次会话内有效。
application 对应整个 WEB 应⽤的。
EL 表达式
(只能在jsp页面使用)
Expression Language 表达式语⾔,替代 JSP ⻚⾯中数据访问时的复杂编码,可以⾮常便捷地取出域对象(pageContext、request、session、application)中保存的数据,前提是⼀定要先 setAttribute
,EL 就相当于在简化 getAttribute
1、EL 对于 4 种域对象的默认查找顺序:
pageContext -》request-〉session-》application
按照上述的顺序进⾏查找,找到⽴即返回,在 application 中也⽆法找到,则返回 null
2、指定作⽤域进⾏查找
pageContext:${pageScope.name}
request:${requestScope.name}
session:${sessionScope.name}
application:${applicationScope.name}
hashcode():可以简单地认为是内存地址,但实际不仅仅是内存地址
JSTL
- 实际开发中 EL 和 JSTL 结合起来使⽤,JSTL 侧重于逻辑处理,EL 负责展示数据
JSTL 的使⽤
1、需要导⼊ jar 包(两个 jstl.jar standard.jar)存放的位置 web/WEB-INF
2、在 JSP ⻚⾯开始的地⽅导⼊ JSTL 标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3、在需要的地⽅使⽤
<c:forEach items="${list}" var="user"> <tr> <td>${user.id}</td> <td>${user.name}</td> <td>${user.score}</td> <td>${user.address.value}</td> </tr></c:forEach>
过滤器
init ⽅法:只调⽤⼀次,当 Filter 的实例化对象创建完成之后调⽤
doFilter:调⽤多次,访问 Filter 的业务逻辑都写在 Filter 中(只要某资源被过滤器指定,客户端每次访问都会经过过滤器)
destory:只调⽤⼀次,Tomcat 关闭时调⽤。
servlet注解不能配置初始化参数。
实际开发中 Filter 的使⽤场景: 1、统⼀处理中⽂乱码。 2、屏蔽敏感词。 3、控制资源的访问权限
文件上传下载
Ajax
JDBC
使⽤ Statement 进⾏开发有两个问题:(prepareStatement都可以解决,使用的是占位符的方法)
1、需要频繁拼接 String 字符串,出错率较⾼。
2、存在 SQL 注⼊的⻛险
sql注入:系统对用户输入的数据没有进行充分的检测,用户就可以在我们输入的数据中人为的添加一些非法的sql,最终跟你的模板sql语句拼成一种非法的sql语句
select * from user where username='{随意字符}' or '1'='1' and password='{随意字符}' or '1'='1'
数据库连接池
jdbc开发流程
- 加载驱动(只需要加载一次)
- 建立数据库连接(connection)
- 执行sql(statement)
- resultSet接受结果集(查询)
- 断开连接,释放资源
数据库连接对象是通过DriverManager来获取的,每次获取都需要向数据库申请获取连接,验证用户名和密码
执行完sql语句后断开连接,这样的方式会造成资源的浪费,数据连接资源没有得到很好地重复利用。
可以使用数据库连接池解决这一问题
数据库连接的基本思想就是为数据库连接建立一个缓冲池,预先向缓冲池中放入一定数量的连接对象,当需要获取数据库连接的时候,只需要从缓冲池中取出一个对象,用完之后再放回缓冲池中,供下一次请求使用,做到了资源的重复利用,允许程序重复使用一个现有的数据库连接对象,而不需要重新创建。
当数据库连接池中没有空闲的连接时,新的请求就会进入等待队列,等待其他线程释放连接
数据库连接池实现
JDBC 的数据库连接池使⽤ javax.sql.DataSource 接⼝来完成的,DataSource 是 Java 官⽅提供的接⼝,使⽤的时候开发者并不需要⾃⼰来实现该接⼝,可以使⽤第三⽅的⼯具,C3P0 是⼀个常⽤的第三⽅实现,实际开发中直接使⽤ C3P0 即可完成数据库连接池的操作。
javax是jdk后来扩展的内容,都属于jdk
DriverManager的getConnection是直接创建一个数据库连接对象
DataSource的getConnection是向数据库连接池获取一个数据库连接对象,用完返回到连接池
- 导⼊ jar 包。
- 代码实现
实际开发,将 C3P0 的配置信息定义在 xml ⽂件中,Java 程序只需要加载配置⽂件即可完成数据库连接池的初始化操作。
1、配置⽂件的名字必须是 c3p0-config.xml
2、初始化 ComboPooledDataSource 时,传⼊的参数必须是 c3p0-config.xml 中 named-config 标签的 name 属性值。
DUtils
DBUtils 可以帮助开发者完成数据的封装(结果集到 Java 对象的映射)
1、导⼊ jar 包
2、开始使用
DBUtils只能做单表的查询,不能做级联的查询
JavaWeb工程
图书管理系统
介绍:用户登录、退出登录、session保存/销毁;数据查询分页;借阅(Calendar使用,时间存储,推荐使用包装类);
Class 1:读者登录
Class 2:管理员登录
Class 3:查询所有书籍信息、分页
Class 4:代码优化(用户登陆后跳转到index.jsp和分页查询之后,第一页、第二页之类的部分代码存在耦合),借阅书籍(向数据库存储借阅信息,Calendar用法)
Class 5:订阅后的页面跳转(展示当前用户的所有借阅信息,sql的写法)
Class 6:配置过滤器(解决readerId是null(BookServlet53行),访问index.jsp跳转到login.jsp,主要解决没有登陆就访问其他路径的问题),当前用户所有借阅信息展示、分页
Class 7:管理员登录跳转页面,查询未审核的书籍并分页、管理员通过审核、管理员过滤器、
Class 8:还书管理
复习点:动态sql(BorrowRepositoryImpl104行)、代码之间的耦合度(登录和之后的业务逻辑功能分开)
MVC
是一种开发模式,将程序分层的一种思想
M:Model 业务数据(Service、Repository、Entity)
V:View 视图(JSP、HTML、APP客户端)
C:Controller 控制(Servlet、Handler、Action)
请求进入javaWeb应用后,Controller接收该请求,进行业务逻辑处理,最终将处理的结果再返回给用户(View+Model)
**原则上一个表对应一个repository**
Controller=>Srvice=>Repository—>DB
-DBUtils只能做单表的查询,不能做级联的查询
servlet里面不能运行main方法
节省栈空间