总结:
1、tomcat、servlet、jsp的关系:
tomcat是一个容器,可以运行servlet
jsp就是servlet
2、Servlet就是开发动态web的一门技术
3、servlet原理(重点)
浏览器首次访问web容器,一个servlet类会对应生成一个Servlet对象,容器内部的ServletContext对象由所有的Servlet对象共享
在servlet中可以获取ServletContext对象,也可以给ServletContext对象赋值,
http请求到web容器中会产生两个对象Request、Response
根据request请求路径映射到对应的servlet对象
web容器调用该Servlet对象中的service对Requset对象进行处理,判断Request中是什么请求
如果是get请求则调动doGet方法,手写的doGet方法对Request进行处理,将处理结果赋值给Response对象并返回浏览器
4、转发和重定向
5、cookie 和 session
6、jsp九大内置对象:application、session、pagecontext、request、response、page、out、config、expection
7、MVC架构
8、过滤器
9、监听器
Java web思维导图
1、Web项目目录结构
java 代码目录
resources 资源目录
webapp 项目目录
打包之后,编译器讲main下面的java和resources目录中的文件都加载到webapp目录下的WEB-INF下
java目录和resources目录中的文件都在classes目录中
2、HTTP
响应状态码:
- 200 请求成功
- 3xx 请求重定向,请重新到我给你的新的位置去
- 4xx 找不到资源 404
- 5xx 服务器代码错误 500 502是网关错误
3、Maven
Maven是项目架构管理工具
目的就是方便我们导jar包的
Maven的核心思想:约定大于配置
4、tomcat和servlet、jsp的关系
- tomcat是一个容器,运行servlet的平台
- jsp是servlet的一个变种,你可以认为jsp就是servlet。
总结:tomcat是一能独立运行的程序,他能运行你写的servlet
5、servlet
Servlet就是开发动态web的一门技术
该技术提供了一个Servlet接口 HttpServlet 继承 GenericServlet 继承 Servlet
如果你想开发一个servlet程序,只需要两步:
- 编写一个类,继承servlet接口
- 把开发好的java类部署到web服务器中
编写程序继承Servlet接口
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doget");
PrintWriter pw = resp.getWriter();
pw.println("helloServlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
编写servlet的映射
为什么需要映射:我们写的是java程序,但是需通过浏览器访问,而浏览器需要链接web服务器,所以需要在web服务中注册我们写的servlet,还需要给他一个浏览器能够访问的路径
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_3_0.xsd"
id="WebApp_ID" version="3.0">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kayak.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
访问 http://localhost:8080/hello
servlet原理(重点)
- 浏览器首次访问web容器,一个servlet类会对应生成一个Servlet对象,容器内部的ServletContext对象由所有的Servlet对象共享
- 在servlet中可以获取ServletContext对象,也可以给ServletContext对象赋值,
- http请求到web容器中会产生两个对象Request、Response
- 根据request请求路径映射到对应的servlet对象
- web容器调用该Servlet对象中的service对Requset对象进行处理,判断Request中是什么请求
- 如果是get请求则调动doGet方法,手写的doGet方法对Request进行处理,将处理结果赋值给Response对象并返回浏览器
可以写多个servlet映射
应用场景:美化404页面,下例中如果访问路径找不到对应的资源,则会走默认路径请求,返回美化后的404页面
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kayak.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern> ###指定固有的映射路径优先级最高,如果找不到则会走默认处理请求
</servlet-mapping>
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kayak.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern> ### 默认处理请求
</servlet-mapping>
public class ErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("<h1>我走丢了</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
ServletContext
web容器在启动的时候,会为每个web程序都创建一个ServletContext对象,他代表了当前web应用
1. 共享数据
我在这个servlet中保存数据,可以在另外一个servlet中拿到
赋值
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = req.getParameter("username");
context.setAttribute("username",username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
取值
public class GetServelt 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");
PrintWriter writer = resp.getWriter();
writer.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
2. 获取初始化参数
<!--给ServletContext配置一些初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = (String)context.getInitParameter("url");
PrintWriter writer = resp.getWriter();
writer.println(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
3. 请求转发 RequestDispatcher
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
context.getRequestDispatcher("/get").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
注:转发和重定向的区别
1、转发 路径不变
2、重定向 路径变化
4、读取资源文件
Properties
- 在java目录下新建properties
- 在resources下新建properties
打包后,这两个配置文件被打包到同一个目录classes,统称这个路径为:classpath:
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext()
.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().println(username+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
注:一般情况下在resources下新建properties等配置文件,打包可以被发现
在java下新建properties配置文件,可能会出现打包打不进该配置文件的情况,此时需要配置pom文件
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
HttpServletResponse
简单分类
- 负责想浏览器发送数据的方法
ServletOutputStream getOutputStream();
PrintWriter getWriter()
-
负责向浏览器发送响应头的方法
-
相应状态码
常见应用
- 向浏览器输出消息
- 下载文件
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String filepath= "D:\\projects\\javaweb\\servlet02\\src\\main\\resources\\相机知识.png";
String fileName = filepath.substring(filepath.lastIndexOf("\\") + 1);
FileInputStream inputStream = new FileInputStream(filepath);//读取文件
//设置resp响应头方式为下载
resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"utf-8"));
ServletOutputStream outputStream = resp.getOutputStream();
int len ;
byte[] buffer = new byte[1024];
while ((len=inputStream.read(buffer))>0){
//输出resp数据
outputStream.write(buffer,0,len);
}
inputStream.close();
outputStream.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
- 验证码功能
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器5秒刷新一次
resp.setHeader("refresh", "3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//获取图片
Graphics2D g = (Graphics2D) image.getGraphics();
//设置颜色
g.setColor(Color.BLACK);
//填充
g.fillRect(0, 0, 80, 20);
//设置颜色和字体
g.setColor(Color.BLUE);
g.setFont(new Font(null, Font.BOLD, 20));
//写入数据
g.drawString(getRandomNum(), 0, 20);
//设置以格式响应
resp.setContentType("image/jpg");
//设置缓存不启用
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-control", "no-cache");
resp.setHeader("Pragma", "no-cache");
ImageIO.write(image, "jpg", resp.getOutputStream());
}
private String getRandomNum() {
Random random = new Random();
String s = random.nextInt(999999) + "";
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 6 - s.length(); i++) {
buffer.append("0");
}
return buffer.append(s).toString();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
- 实现重定向(重点)
一个web资源-B收到客户端A请求后,B他会通知客户端A去请求另一个web资源-C,这个过程叫重定向
常见场景:登陆
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* 实现原理
resp.setHeader("location","/index.jsp");
resp.setStatus(302);
*/
resp.sendRedirect("/index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
HttpServletRequest
常见应用
- 获取参数
public class GetServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("*******************");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
req.getRequestDispatcher("/success").forward(req,resp);
}
}
- 请求转发
req.getRequestDispatcher("/success").forward(req,resp);
转发和重定向
相同:
- 都可以实现页面的跳转
不同:
- 转发,url不变,由HttpServletRequest对象的方法转发,可以携带原有的req参数
例如:登陆功能
如果验证成功,则重定向到主页;
如果验证失败,则转发到登陆页面,原有req的参数可以展示到用户名和密码输入栏中; - 重定向,url改变,由HttpServletResponse对象的方法重定向,
Cookie、Session
会话:用户打开一个浏览器,点击很多超链接,访问多个web资源,关闭浏览器,这个过程我们称之为一个会话。
有状态会话:
网站怎么证明你来过?两种方式:
- 服务端给客户端一个信件,客户端下次访问服务端时带上信件就可以访问了 (cookie 保存在客户端)
- 服务端登记你来过了,下次你来我匹配你就可以访问了 (session 保存在服务端)
保存会话的两种技术
-
cookie:客户端技术(响应,请求)
-
session:服务端技术,可以保存用户的会话信息,我们可以把信息或数据放到session中
常见应用:网站登录之后,下次在访问就不用登陆了,第二次访问直接就上去了
Cookie
- 从请求中拿到cookie信息
- 服务器相应给客户端cookie
Cookie[] cookies = req.getCookies();
cookie.getName();
cookie.getValue();
Cookie cookie = new Cookie("", "");
cookie.setMaxAge(0);
resp.addCookie(cookie);
cookie一般保存在客户端本地用户目录下
思考:
一个网站cookie是否存在上限,
- 一个cookie只能保存一条信息
- 一个web站点可以给客户端发送多个cookie,最多存放20个cookie
- cookie大小限制在4kb
- 浏览器上限可以存300个cookie
删除cookie
- 不设置有效期,关闭浏览器,cookie自动失效
- 设置有效期为0
编码解码:
URLEncoder.encode("您是第一次登陆","utf-8")
URLDecoder.decode(cookie.getValue(),"utf-8");
Session(重点)
Session由服务器创建,当一个用户(浏览器)访问服务器时,由服务器创建一个该用户独有的Session对象,并将该Session对象的sessionId保存在cookie中发送给用户,这样该用户独有的sessionId就可以凭借Id访问服务器资源
Session和Cookie的区别:
- Cookie是把用户的数据写给浏览器,浏览器保存(可以保存多个)
- Session把用户的数据写到用户独有的session中,由服务器保存(保存重要信息,减少服务器资源浪费)
- Session对象由服务器创建
使用场景:
- 保存一个登陆用户信息
- 购物车
- 在整个网站中经常使用的数据,我们将他保存在session中
Session中的方法:
HttpSession session = req.getSession();
session.setAttribute("name","wanghan");
session.removeAttribute("name");
String sessionId = session.getId();
//注销 Session注销之后,服务器会为该用户马上创建一个新的Session
session.invalidate();
web.xml中配置Session的失效时间
<session-config>
<!--单位为分钟-->
<session-timeout>1</session-timeout>
</session-config>
servletContext:可以保存多用户的数据,多用户共享(封装为applicationContext)应用服务级别的作用域(所有访问该应用的用户共享)
Session:保存单用户的数据,用户级别作用域
6、JSP
什么是JSP
java server page:
JSP原理
JSP实质上就是一个Servlet,当浏览器首次访问JSP页面时,web容器会便宜JSP页面,生成一个jsp的.java文件和.class文件,即一个Servlet类
该servlet类中内置了几个属性:pageContext、session、application、config、out、page、response、request等属性
public final class success_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext; //pageContext对象
javax.servlet.http.HttpSession session = null; //session对象
final javax.servlet.ServletContext application; //application对象
final javax.servlet.ServletConfig config; //config对象
javax.servlet.jsp.JspWriter out = null; //out对象
final java.lang.Object page = this; //page对象
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>success!</h2>\n");
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在JSP页面中:
只要是java代码就会原封不动的输出
只要是html代码就会转换为:
out.write("<html>\n");
这样的格式输出到浏览器中
JSP基础语法
JSP表达式
<%--JSP表达式
作用:将程序输出到客户端
--%>
<%= new java.util.Date()%>
jsp脚本片段
<%--jsp脚本片段--%>
<%
int a = 0;
for (int i = 0; i < 100; i++) {
a = a + i;
}
%>
jsp脚本片段再实现
<%--jsp脚本片段再实现--%>
<%
int a = 0;
for (int i = 0; i < 100; i++) {
a = a + i;
}
%>
<%
a=1000;
%>
jsp脚本片段嵌入html
<%--jsp脚本片段嵌入html--%>
<%
int a = 0;
for (int i = 0; i < 100; i++) {
a = a + i;
%>
<h1>现在是北京时间:<%= new java.util.Date()%></h1>
<%
}
%>
jsp声明
jsp声明:会被编译到jsp生成的java的类中!其他的语法代码会被编译到java类下的_jspService方法中
<%!
static {
System.out.println("****");
}
private int a = 0;
public void wanghan(){
System.out.println("*************88");
}
定制错误界面
<%@ page errorPage="error.jsp" %>
web.xml定制错误界面
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/index.jsp</location>
</error-page>
导包
<%@ page import="java.util.Date" %>
page下面还有很多的属性
<%--@include是将三个页面编译成一个页面
三个页面中定义相同名称的变量会造成变量名冲突的错误
--%>
<%@include file="header.jsp" %>
<h1>主题</h1>
<%@include file="footer.jsp" %>
<%--jsp标签
将三个页面拼接
三个页面里面定义的java变量互不影响
--%>
<jsp:include page="header.jsp"/>
<h1>主题</h1>
<jsp:include page="footer.jsp"/>
jsp 9大内置对象
- pageContext 存数据
- request 存数据
- reponse
- session 存数据
- application 存数据
- config
- page 几乎不用,了解
- out
- exception
<%
pageContext.setAttribute("a", "1");//保存的数据只在页面上有效
request.setAttribute("b", "2");//保存的数据在一个请求中有效
session.setAttribute("c", "3");//保存的数据在一个浏览器中有效
application.setAttribute("d", "4");//保存的数据在同一个servlet web服务中有效
%>
<%
//从底层到高层作用域:pageContext-request-session-application
String a = (String)pageContext.findAttribute("a");
String b = (String)pageContext.findAttribute("b");
String c = (String)pageContext.findAttribute("c");
String d = (String)pageContext.findAttribute("d");
%>
JSP标签、JSPL标签、EL表达式
EL表达式:
- 获取数据
- 执行运算
- 获取web开发常用对象
JSP标签
<jsp:forward page="a.jsp">
<jsp:param name="aa" value="1"/>
<jsp:param name="bb" value="2"/>
</jsp:forward>
JSTL标签
JSTL标签库的使用是为了弥补HTML标签的不足;他自定义许多标签,可以供我们使用,标签的功能和java代码一样!
- 核心标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- 格式化标签
- sql标签
- xml标签
7、MVC三层架构
什么是MVC :model、view、controller
Model
- 业务处理:业务逻辑(service)
- 数据持久层CRUD(dao)
View
- 展示数据
- 提供链接发起Servlet请求
Controller(Servlet)
- 接收用户请求:(req:请求参数、Session信息)
- 交给业务层对应的代码去处理数据
- resp响应,控制视图的跳转
8、Filter(过滤器)
Filter:用来过滤网站的数据;
- 处理中文乱码
- 拦截垃圾请求
public class FilterTest implements Filter {
//初始化 web服务器启动,就已经初始化了,随时等候过滤对象出现
public void init(FilterConfig filterConfig) throws ServletException {
}
//FilterChain:链
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request,response);//让我们的请求继续往下走,如果不写,程序到这里就被拦截住了
}
//销毁 web服务器关闭时,过滤会被销毁
public void destroy() {
}
}
在web.xml中配置自定义的Fiter
<filter>
<filter-name>b</filter-name>
<filter-class>com.kayak.FilterTest</filter-class>
</filter>
<filter-mapping>
<filter-name>b</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
9、监听器 Listener
实现一个监听器接口;
接口有很多种;
场景:记录在线人数
public class ListenerTest implements HttpSessionListener {
//创建session监听
//一旦创建一个session就会触发一次这个事件
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
HttpSession session = se.getSession();
System.out.println(session.getId());
Integer count = (Integer) context.getAttribute("count");
if(count==null){
count=1;
}else{
count=count+1;
}
context.setAttribute("count",count);
}
//销毁session监听
//一旦销毁session就会触发一次这个事件
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer) context.getAttribute("count");
if(count==null){
count=0;
}else{
count=count-1;
}
context.setAttribute("count",count);
}
}
在web.xml中的配置
<listener>
<listener-class>com.kayak.ListenerTest</listener-class>
</listener>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
应用:监听器在GUI中的使用
public class Test {
public static void main(String[] args) {
Frame frame = new Frame("中秋快乐");
Panel panel = new Panel(null);
frame.setLayout(null);
frame.setBounds(300, 300, 500, 500);
frame.setBackground(Color.red);
panel.setBounds(150, 150, 250, 250);
panel.setBackground(Color.cyan);
frame.add(panel);
frame.setVisible(true);
//监听关闭事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(1);
}
});
}
}
监听windows的关闭事件
10、过滤器、监听器常见应用
- 监听器:在GUI编程中经常使用
- 过滤器:实现登陆权限拦截
思路:
- 登陆的时候在session中set登陆属性
- 注销的时候移除session中的登陆属性
- 自定义拦截器,拦截目标资源,当访问目标资源时,过滤器拦截到请求,在过滤器中获取session,判断session中是否有登陆属性,如果有就放行,如果没有就在resp对象中重定向到登陆页面
- login.jsp logout.jsp 与目标资源分开存放,目标资源存在特定目录中如sys,过滤器在web.xml中设置过滤url如下:
<filter-mapping>
<filter-name>b</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
public class Login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String user = req.getParameter("user");
HttpSession session = req.getSession();
if(user.equals("admin")){
session.setAttribute("author","admin");
resp.sendRedirect("/jsp01_war_exploded/sys/main.jsp");
}else{
resp.sendRedirect("/jsp01_war_exploded/a.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
public class Logout extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().removeAttribute("author");
resp.sendRedirect("login.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
public class FilterTest implements Filter {
//初始化
public void init(FilterConfig filterConfig) throws ServletException {
}
//FilterChain:链
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if(req.getSession().getAttribute("author")==null){
resp.sendRedirect("../login.jsp");
}
chain.doFilter(req,resp);//让我们的请求继续往下走,如果不写,程序到这里就被拦截住了
}
//销毁
public void destroy() {
}
}
JDBC
编译sql
public static void main(String[] args) throws ClassNotFoundException, SQLException {
String url="jdbc:mysql://localhost:3306/jdbc";
String username="wanghan";
String password="123456";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, username, password);
Statement st = con.createStatement();
String sql = "select * from user";
ResultSet rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getInt(1));
System.out.println(rs.getString(2));
System.out.println(rs.getString(3));
System.out.println(rs.getDate(4));
}
rs.close();
st.close();
con.close();
}
预编译sql
可以防止sql注入
public static void main(String[] args) throws ClassNotFoundException, SQLException {
String url = "jdbc:mysql://localhost:3306/jdbc";
String username = "wanghan";
String password = "123456";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, username, password);
String sql = "select * from user where id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, 10);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1));
System.out.println(rs.getString(2));
System.out.println(rs.getString(3));
System.out.println(rs.getDate(4));
}
rs.close();
ps.close();
con.close();
}
JDBC事务
要么都成功,要么都失败
- 开启事务
- 提交事务
- 回滚事务
- 关闭事务
public static void main(String[] args) throws ClassNotFoundException, SQLException {
String url = "jdbc:mysql://localhost:3306/jdbc";
String username = "wanghan";
String password = "123456";
Class.forName("com.mysql.jdbc.Driver");
Connection con = null;
PreparedStatement ps = null;
try {
con = DriverManager.getConnection(url, username, password);
con.setAutoCommit(false);//开启事务
String sql = "delete * from user where id = ?";
ps = con.prepareStatement(sql);
ps.setInt(1, 10);
int i = ps.executeUpdate(sql);//执行第一条sql
ps.setInt(1, 11);
int ii = ps.executeUpdate(sql);//执行第二条sql
con.commit();//提交事务
} catch (Exception e) {
con.rollback();//事务回滚
}finally {
ps.close();
con.close();
}
}
BaseDao
public class BaseDao {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
Properties p = new Properties();
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("properites");
try {
p.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=p.getProperty("driver");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
}
//获取链接
public static Connection myConnection() throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
//编写查询公共类
public static ResultSet execute(Connection connection,PreparedStatement preparedStatement, ResultSet resultSet,String sql,Object[] params) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
resultSet = preparedStatement.executeQuery();
return resultSet;
}
//编写增删改公共类
public static int update(Connection connection,PreparedStatement preparedStatement, String sql,Object[] params) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
int rows = preparedStatement.executeUpdate();
return rows;
}
//关闭链接资源公共类
public static Boolean disConnect(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
Boolean flag= true;
if(resultSet!=null){
try {
resultSet.close();
resultSet=null;
} catch (SQLException e) {
e.printStackTrace();
flag=false;
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
preparedStatement=null;
} catch (SQLException e) {
e.printStackTrace();
flag=false;
}
}
if(connection!=null){
try {
connection.close();
connection=null;
} catch (SQLException e) {
e.printStackTrace();
flag=false;
}
}
return flag;
}
```