JavaWebWeb服务器技术讲解Web服务器TomcatHttpMavenpom.xmlServletHelloServletServlet原理MappingServletContextHttpServletResponse下载文件验证码功能实现重定向HttpServletRequestCookie, SessionCookieSessionJSP什么是JSPjsp原理JSP基础语法定制错误页面JSP指令九大内置对象四大作用域JSP标签,JSTL标签,EL表达式JavaBeanMVC三层架构过滤器监听器过滤器,监听器常见应用JDBC事务JavaWeb静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变。动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。静态web资源开发技术:HTML、CSS、JavaScript。动态web资源开发技术:JSP/Servlet、ASP、PHP等。在Java中,动态web资源开发技术统称为Java Web。Web服务器技术讲解ASP:微软,国内最早流行的是ASP,在HTML中嵌入了VB的脚本,ASP+COM,维护成本高。PHP:开发速度很快,功能很强大,跨平台,代码简单,但是无法承载大访问量的情况(局限性)。JSP/Servlet:sun公司主推的B/S架构,基于java语言,可以承载三高问题(高并发,高可用,高性能)。B/S:浏览器和服务器;C/S:客户端和服务器。Web服务器服务器用来处理用户的一些请求,响应给用户一些数据。IIS:微软的,主要用于ASP,Windows中自带的服务器。Tomcat:Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个JavWeb初学者来说,是最好的选择。Tomcat 实际上运行JSP 页面和Servlet。Tomcat安装Tomcat:官网下载(http://tomcat.apache.org/)压缩包,解压至指定目录(可选:配置环境变量)。在bin目录下点击startup.bat启动,在浏览器网址栏输入localhost:8080测试。网站是如何进行访问的:输入用户名,回车检查本机的C:\Windows\System32\drivers\etc\hosts配置文件有没有这个域名的映射 有就直接返回对应的ip地址没有就去DNS(全世界的域名管理)服务器上寻找,找到就返回HttpHttp(超文本传输协议):http是一个简单的请求-响应协议,它通常运行在TCP之上。(默认端口:80)Https:443Http1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接。Http1.1:客户端可以与web服务器连接后,可以获得多个web资源。Http请求客户端----发请求----服务器百度为例:Request URL: https://www.baidu.com/ 请求地址
Request Method: GET 请求方法
Status Code: 200 OK 状态码
Remote Address: 180.101.49.11:443 远程地址
Referrer Policy: no-referrer-when-downgrade
Http响应服务器----发请求----客户端百度响应:Cache-Control: private 缓存控制
Connection: keep-alive 保持连接
Content-Encoding: gzip 编码
Content-Type: text/html;charset=utf-8 类型
请求方式:get:请求能够携带的参数比较少,大小有限制,会在浏览器地址栏显示参数的内容,不安全,但是高效。post:请求能够携带的参数没有限制,大小没有限制,不会再浏览器地址栏显示参数的内容,安全,但不高效。响应状态码:200:请求响应成功3**:请求重定向404:找不到资源500:服务器代码错误,502:网关错误MavenMaven:项目架构管理工具,自动导入jar包(约定大于配置)。下载Maven后解压,配置环境变量,将bin目录的路径配置到path中,在cmd中输入mvn-version,查看是否配置成功在conf目录下setting的 下配置本地仓库D:\Environments\apache-maven-3.6.3\maven-repo在conf目录下setting的 中配置阿里云的镜像
alimaven
central
aliyun maven
https://maven.aliyun.com/repository/public/
pom.xmlpom.xml:maven的核心配置文件由于maven的约定大于配置,我们之后写的配置文件可能无法导出或者无法生效,就需要在maven配置下面配置resouce。Servletservlet就是sun公司开发动态web的一门技术,sun公司在API中提供了一个接口叫Servlet,如果需要开发一个Servlet程序,需要编写一个类去实现Servlet接口,再把开发好的java类部署到web服务器中。HelloServletsun公司有两个Servlet接口的默认实现类:HttpServlet和GenericServlet构建一个maven项目,删除里面的src项目,以后就直接新建model,这个空的工程就是Maven的主工程。关于Maven父子工程的理解:父项目中会有
servlet-01
子项目中有
javaweb-02-servlet
com.zr
1.0-SNAPSHOT
Maven环境优化:修改web.xml为最新的,将Maven的结构搭建完整。编写一个普通类,实现Servlet接口,继承HttpServlet。public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter(); //响应流
writer.println(“Hello Servlet”);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
编写Servlet的映射:我们写的是java程序,但是要通过浏览器访问,而浏览器要连接web服务器,所以我们要在web服务器注册我们写的Servlet,还需要给它一个浏览器能够访问的路径。
hello
com.zr.servlet.HelloServlet
默认请求
hello
/
一个Servlet可以指定一些后缀或者前缀映射路径
hello
.zzr
优先级问题:指定了固有的映射路径,优先级最高,找不到就会走默认的处理请求。处理404页面
error
com.zr.servlet.ErrorServlet
error
/*
ServletContextweb容器在启动的时候,它会为每一个web程序都创建一个ServletContext对象,它代表了当前的 web应用。共享数据我在这个Servle中保存的数据可以在另外一个Servle中拿到public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“hello”);
//this.getInitParameter(); 初始化参数
//this.getServletConfig(); Servlet的配置
//this.getServletContext(); Servlet上下文
ServletContext context = this.getServletContext();
String username = "周周";
context.setAttribute("username",username);//将一个数据保存在ServletContext中
}
}
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.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.getWriter().println("名字:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
hello
com.zr.servlet.HelloServlet
hello
/hello
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
请求转发public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
requestDispatcher.forward(req,resp);//转发
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
sd4
com.zr.servlet.ServletDemo04
sd4
/sd4
读取资源文件properties在Java目录下新建propreties(需要在pom.xml下配置resources)在resources目录下新建properties发现都被打包到了target下的class目录下,我们称这个路径为类路径classpath。public class ServletDemo05 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:”+username);
resp.getWriter().println(“password:”+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
sd5
com.zr.servlet.ServletDemo05
sd5
/sd5
src/main/resources
/*.properties
/.xml
true
src/main/java
**/.properties
**/*.xml
true
//文件 db.properties
username=root
password=123456
HttpServletResponseweb服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应一个HttpServletResponse。如果要获取客户端请求过来的参数:HttpServletRequest如果要给客户端响应一些信息:HttpServletResponse简单分类负责向浏览器发送数据的方法ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
响应的状态码int SC_OK = 200;
…
int SC_MULTIPLE_CHOICES = 300;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
…
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;
下载文件向浏览器输出消息下载文件获取下载文件的路径下载的文件名让浏览器支持下载我们需要的东西获取下载文件的输入流创建缓冲区获得OutputStream对象将FileOutputStream流写入到buffer缓冲区将OutputStream缓冲区中的对象输出到客户端public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取下载文件的路径
String realPath = “D:\IDEACode\javaweb-02-servlet\response\src\main\resources\1.PNG”;
System.out.println(“下载文件的路径:”+realPath);
//2. 下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);
//3. 让浏览器支持下载我们需要的东西
resp.setHeader(“Content-Disposition”,“attachment;filename=”+fileName);
//4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6. 获得OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓冲区 将OutputStream缓冲区中的对象输出到客户端
while ((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
验证码功能如何生成验证码:前端后端:需要用Java的图片类,生成一个图片public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器5秒刷新一次
resp.setHeader(“refresh”,“5”);
//创建图片
BufferedImage image = new BufferedImage(300,60,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics g = image.getGraphics(); //笔
//设置图片的背景颜色
g.setColor(Color.green);
g.fillRect(0,0,300,60);
//给图片写数据
g.setColor(Color.magenta);
g.setFont(new Font(null,Font.BOLD,70));
g.drawString(makeNum(),0,60);
//浏览器以图片的形式打开
resp.setContentType(“image/png”);
//网站存在缓存。不让浏览器缓存
resp.setDateHeader(“expires”,-1);
resp.setHeader(“Cache-Control”,“no-cache”);
resp.setHeader(“Pragma”,“no-cache”);
//把图片显示出来
boolean write = ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
num = sb.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
image com.zr.servlet.ImageServlet image /image 实现重定向void sendRedirect(String var1) throws IOException;//重定向 public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* resp.setHeader("Location","/r/image"); resp.setStatus(302); */ resp.sendRedirect("/r/image");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml测试重定向和转发的区别:相同点:页面都会发生跳转不同点:请求转发的时候,url不会改变 307重定向的时候,url地址栏会发生变化 302index.jsp<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
Hello World!
<%--提交的路径需要寻找到当前项目的路径--%> 用户名:密码 :
success.jsp<%@ page contentType="text/html;charset=UTF-8" language="java" %>
success
public class RequestTest extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入这个请求了");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username:"+username);
System.out.println("password:"+password);
resp.sendRedirect("/r/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
test com.zr.servlet.RequestTest test /login HttpServletRequestHttpServletRequest代表客户端的请求,用户通过http协议访问服务器,http请求中的所有的信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); }@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
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));
//请求转发
//这里的/代表当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
index.jsp<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
登录
密码:
爱好: 唱歌 女孩 写字 代码
登录成功
web.xml LoginServlet com.zr.servlet.LoginServlet LoginServlet /login Cookie, Sessioncookie客户端技术(响应,请求)session服务器技术,可以保存用户的会话信息,我们可以把信息或数据放在session中常见应用:网站登录一次后,下次可以直接进入。Cookie从请求中拿到cookie信息服务器响应给客户端cookie//保存用户上一次访问的时间 public class CookieDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决中文乱码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); PrintWriter out= resp.getWriter();
//cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//返回数组,cookie可能存在多个
//判断cookie是否存在
if (cookies!=null){
//如果存在
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastlogintime")){
//获取cookie中的值
long lastlogintime = Long.parseLong(cookie.getValue());
Date date = new Date(lastlogintime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是你第一次访问本站!");
}
//服务器给客户端发一个cookie
Cookie cookie = new Cookie("lastlogintime", System.currentTimeMillis()+"");
//有效期为1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
CookieDemo01
com.zr.servlet.CookieDemo01
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
req.setCharacterEncoding(“utf-8”);
resp.setCharacterEncoding(“utf-8”);
resp.setContentType(“text/html;charset=utf-8”);
//得到session
HttpSession session = req.getSession();
//给session存东西
session.setAttribute("name",new Person("周周",1));
//获得session的id
String id = session.getId();
//判断session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功,ID:"+ id);
}else {
resp.getWriter().write("session已经存在,ID:"+ id);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
req.setCharacterEncoding(“utf-8”);
resp.setCharacterEncoding(“utf-8”);
resp.setContentType(“text/html;charset=utf-8”);
//得到session的数据
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person);
}
@Overridejava
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
SessionDemo01
com.zr.servlet.SessionDemo01
SessionDemo01
/s1
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
session自动注销
1
JSP什么是JSPjsp:java server pages,Java服务器端界面,和servlet一样,用于开发动态web技术。特点写jsp就像写html区别 html只给用户提供静态的数据jsp页面可以嵌入Java代码,为用户提供动态数据jsp原理在服务器内部,tomcat中有一个work目录,jsp最终被转化成了Java类, jsp本质就是一个servlet。index_jsp.java源码//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//jspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
判断请求内置的一些对象 final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page 当前页
HttpServletRequest request //请求
HttpServletResponse respons //响应
输出页面前增加的代码 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;
以上的对象可以在jsp中直接使用在jsp页面中,java代码会原封不动的输出,如果是html代码就会被转化为out.write("…");JSP基础语法任何语言都有自己的语法 ,jsp作为Java技术的一种运用,它拥有一些自己扩充的语法(了解)。Java语法它都支持。jsp表达式<%–JSP表达式 输出时间到客户端–%>
<%= new java.util.Date()%>
jsp脚本片段<%–jsp脚本片段–%>
<%
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
out.println(“
sum=”+sum+"
");%>
脚本片段的再实现<%
int x=10;
out.print(x);
%>
这是一个jsp文档
<% int y=20; out.print(y); %><%–在代码中嵌入html元素–%>
<%
for (int i = 0; i < 5; i++) {
%>
helloworld<%=i%>
<% } %> jsp声明<%! static { System.out.println("loding..."); } private int globalvar=0; public void jspInit(){ System.out.println("进入了方法"); } %> JSP声明:会被编译到jsp生成的Java类中。其它的会被生成到jspServer方法中。JSP的注释不会在客户端源码显示,HTML的注释会在哭护短源码显示。定制错误页面 404 /error/404.jsp 500 /error/500.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %><%–会将页面合二为一–%>
<%@include file=“common/header.jsp”%>
主体
<%@include file="common/footer.jsp"%><%--jsp标签 拼接页面--%>
主体
九大内置对象PageContext 存东西Request 存东西ResponseSession 存东西Application 【ServletContext】存东西config 【ServletConfig】outpageexception四大作用域<%--内置对象--%> <% pageContext.setAttribute("name1","周1");//保存的数据只在一个页面内有效 request.setAttribute("name2","周2");//保存的数据只在一次请求中有效,请求转发会携带 session.setAttribute("name3","周3");//保存的数据只在一次会话中有效,打开浏览器到关闭浏览器 application.setAttribute("name4","周4");//保存的数据在服务器中有效,打开服务器到关闭服务器 %> <%--通过pageContext取值--%> <% //通过寻找的方式 String name1 = (String) pageContext.findAttribute("name1"); String name2 = (String) pageContext.findAttribute("name2"); String name3 = (String) pageContext.findAttribute("name3"); String name4 = (String) pageContext.findAttribute("name4"); String name5 = (String) pageContext.findAttribute("name5");//不存在 %><%–使用EL表达式输出 ${}–%>
取出的值为:
${name1}
${name2}
${name3}
${name4}
${name5}
<hr>
<%=name5%>
request:客户端向服务器发送数据,产生的数据,用户看完就没用了,比如:新闻session:客户端向服务器发送数据,产生的数据,用户用完一会还会用,比如:购物车application:客户端向服务器发送数据,产生的数据,一个用户使用完了,其它用户可能还用,比如:聊天记录JSP标签,JSTL标签,EL表达式
javax.servlet.jsp.jstl
jstl-api
1.2
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${}获取数据执行运算获取web开发的常用对象JSP标签:<%–jsp:include–%>
<%–转发时候携带参数–%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name=“name” value=“zr”/>
<jsp:param name=“age” value=“22”/>
</jsp:forward>
JSTL表达式JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义了许多的标签,可以供我们使用,标签的功能和Java代码一样。核心标签(掌握),格式化标签,SQL标签,XML标签<%–引入JSTL核心标签库–%>
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
JSTL标签使用步骤引入对应的taglib使用其中的方法tomcat中需要引入JSTL的包,否则会报JSTL解析错误c:if
if测试
<%-- EL表达式获取表单中的数据 ${param.参数名} --%>
<%-- 判断如果提交的用户是管理员,则登录成功–%>
<c:if test="
p
a
r
a
m
.
u
s
e
r
n
a
m
e
=
=
′
a
d
m
i
n
′
"
v
a
r
=
"
i
s
a
d
m
i
n
"
>
<
c
:
o
u
t
v
a
l
u
e
=
"
管
理
员
欢
迎
你
!
"
/
>
<
/
c
:
i
f
>
<
c
:
o
u
t
v
a
l
u
e
=
"
{param.username=='admin'}" var="isadmin"> <c:out value="管理员欢迎你!"/> </c:if> <c:out value="
param.username==′admin′"var="isadmin"><c:outvalue="管理员欢迎你!"/></c:if><c:outvalue="{isadmin}"/>
<%--开始 结束 步长--%>
JavaBean实体类JavaBean有特定的写法:必须要有一个无参构造属性必须私有化必须有对应的get/set方法一般用来和数据库的字段做映射 ORM;ORM对象关系映射表--->类字段--->属性行记录--->对象people表idnameageaddress1周118武汉2周222广州3周3100佛山建立数据库相应的字段后创建java实体类package com.zr.pojo; //实体类 一般是和数据库中的表结构一一对应的 public class People { private int id; private String name; private int age; private String address;
public People() {
}
public People(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
<%@ page import=“com.zr.pojo.People” %><%–
Created by IntelliJ IDEA.
User: zr
Date: 2020/10/11
Time: 22:08
To change this template use File | Settings | File Templates.
–%>
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
姓名:<jsp:getProperty name=“people” property=“name”/>
id:<jsp:getProperty name=“people” property=“id”/>
年龄:<jsp:getProperty name=“people” property=“age”/>
地址:<jsp:getProperty name=“people” property=“address”/>
System.out.println("CharacterEncodingFilter执行前....");
chain.doFilter(request,response);//让我们的请求继续走 如果不写,程序被拦截停止
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁 web服务器关闭的时候,过滤器销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
servlet显示乱码public class ShowServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//resp.setCharacterEncoding(“utf-8”);
//resp.setContentType(“text/html”);
resp.getWriter().write(“你好世界”);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml
showServlet
com.zr.servlet.ShowServlet
showServlet
/servlet/show
showServlet
/show
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁Session监听
//一旦销毁一个Session就会触发一次这个事件
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
}
/*
Session销毁
1.手动销毁 se.getSession().invalidate();
2.自动销毁 xml中配置
*/
显示在线人数<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
当前有<%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%>人在线
配置web.xml com.zr.listener.OnlineCountListener 过滤器,监听器常见应用监听器GUI编程中经常使用GUI应用public class TestPanel { 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(new Color(0,0,255)); //背景颜色 panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,255));
frame.add(panel);
frame.setVisible(true);
//监听事件,监听关闭事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
用户登录后才能进入主页,注销后不能进入主页1.用户登录之后向session中放入用户的数据2.进入主页的时候判断用户是否登录,要求在过滤器中实现login.jsplogin.jsp(web包下)
登录
success.jsp(web/sys包下)主页
注销 error.jsp(web包下)错误
用户名错误
返回登录页面 Loginpublic class login extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取前端请求的参数 String username = req.getParameter("username"); if (username.equals("admin")){ req.getSession().setAttribute("USER_SESSION",req.getSession().getId()); resp.sendRedirect("/sys/success.jsp"); }else { resp.sendRedirect("/error.jsp"); } }@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
LoginOutpublic class LoginOut extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute(“USER_SESSION”);
if (user_session!=null){
req.getSession().removeAttribute(“USER_SESSION”);
resp.sendRedirect("/login.jsp");
}else {
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
SysFilter:过滤器public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
filterChain.doFilter(request, response);
if (req.getSession().getAttribute("USER_SESSION")==null){
resp.sendRedirect("/error.jsp");
}
}
public void destroy() {
}
}
web.xml
login
com.zr.servlet.login
login
/servlet/login
<servlet>
<servlet-name>loginOut</servlet-name>
<servlet-class>com.zr.servlet.LoginOut</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginOut</servlet-name>
<url-pattern>/servlet/loginout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>com.zr.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<!--只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.zr.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<!--只要是/sys的任何请求,都会经过这个过滤器-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
JDBCJava连接数据库,导入JDBC依赖mysql-connector-java,IDEA中连接数据库public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url = “jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8”;
String username = “root”;
String password = “123456”;
//加载驱动
Class.forName(“com.mysql.jdbc.Driver”);
//连接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//向数据库发送sql的对象
Statement statement = connection.createStatement();
//编写sql
String sql = “select * from users”;
//执行查询sql,返回一个结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
//关闭连接
rs.close();
statement.close();
connection.commit();
}
}
预编译sqlpublic class TestJdbc2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url = “jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8”;
String username = “root”;
String password = “123456”;
//加载驱动
Class.forName(“com.mysql.jdbc.Driver”);
//连接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//向数据库发送sql的对象
Statement statement = connection.createStatement();
String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,4);
preparedStatement.setString(2,"周七");
preparedStatement.setString(3,"888888");
preparedStatement.setString(4,"666@qwq.com");
preparedStatement.setString(5, String.valueOf(new Date(new java.util.Date().getTime())));
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
//关闭连接
statement.close();
connection.commit();
}
}
事务要么都成功,要么都失败 !ACID原则,保证数据的安全。开启事务事务提交 commi ()事务回滚 rollback ()关闭事务Junit单元测试依赖
junit
junit
4.12
test
简单使用@Test注解只在方法上有效,只要加了这个注解的方法,就可以直接运行。public class TestJdbc3 {
@Test
public void test(){
System.out.println("Hello");
}
}
转账事务(创建account表,字段id,name,money),使用单元测试public class TestJdbc3 {
@Test
public void test() {
//配置信息
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
String username = "root";
String password = "123456";
Connection connection=null;
//加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//连接数据库
connection = DriverManager.getConnection(url, username, password);
//通知数据库开启事务
connection.setAutoCommit(false);
String sql1 = "update account set money=money-100 where name='A'";
connection.prepareStatement(sql1).executeUpdate();
//制造错误
int i=1/0;
String sql2 = "update account set money=money+100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上sql都执行成功才提交
System.out.println("提交成功!");
} catch (Exception e) {
try {
//如果出现异常,就回滚事务
connection.rollback();
System.out.println("转账失败!");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}