文章目录
Java Web 笔记
1、Maven项目架构管理工具
Maven是一个工具,帮助我们导入jar包,不再需要手动导入。
核心思想:约定大于配置。
有约束,不要去违反。Maven会规定好如何编写java代码,必须按照这个规范来。
web配置
先在command+, 中设置tomcat的位置
然后在具体的项目中 右上角configuration中设置该项目在tomcat中webapp的位置(该位置应设置为为此项目的webapp目录)
Maven环境优化
1.修改web.xml为最新的
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns = "http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
2.将maven的结构搭建完整
Intellij idea 报错:Error : java 不支持发行版本5
https://blog.csdn.net/qq_22076345/article/details/82392236
Vue的一些补充
Vue双向绑定
组件通过插槽slot和前端联系,前端可以调用Vue实例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SuoxGd2c-1625065058248)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201011190951279.png)]
不同颜色的圈其实是不同的参数。相同颜色的圈是相同的参数。
Vue项目创建
cd /Users/shenhangran/Documents/IdeaWorkspace
vue init webpack myvue
# 运行该项目
npm run dev
想要路由,一定要在当前项目中的终端里输入:
npm install vue-router --save-dev
安装element-ui
npm i element-ui -S
安装依赖
npm install
安装SASS加载器(2个)
cnpm install sass-loader node-sass --save-dev
启动测试
npm run dev
2、Servlet
Mapping问题
1.一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
2.一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>
他们都指向了同一个页面(即 com.shen.HelloServlet.java)
3.默认请求路径
默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
4.可以指定一些后缀或者前缀等
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.shen</url-pattern>
</servlet-mapping>
5.优先级问题
指定了固有的映射路径优先级最高,找不到就会走默认的处理请求
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。
·共享数据
我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cvdckcYL-1625065058251)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201018113926334.png)]
获取初始化参数:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
请求转发
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了demo04");
context.getRequestDispatcher("/gp").forward(req,resp);
}
读取资源文件
不管是java目录下还是resources目录下新建db.properties,都发现被打包到了同一个路径下:classes,我们俗称这个路径为classpath
思路:需要一个文件流
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().print(username+":"+password);
HttpServletResponse
响应
web服务器接收到客户端的http请求,会针对这个请求分别创建一个代表请求的HttpServletRequest对象,一个代表响应的HttpServletResponse对象;
·如果要获取客户端请求过来的参数,找HttpServletRequest;
·如果要给客户端响应一些消息,找HttpServletResponse
1、简单分类
负责向浏览器发送数据的方法
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);
响应状态码
200:请求响应成功
3xx:请求重定向
·重定向:你重新到我给你的新位置去
4xx:找不到资源 404
·资源不存在
5xx:服务器代码错误 500 502:网关错误
2、常见应用
1.向浏览器输出消息
2.下载文件
1、要获取下载文件的路径
2、下载的文件名是啥?
3、设置想办法让浏览器能够支持我们下载需要的东西
4、获取下载文件的输入流
5、创建缓冲区
6、获取OutputStream对象
7、将FileOutputStream流写入到buffer缓冲区
8、使用OutputStream将缓冲区的数据输出到客户端
3.验证码功能
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何让浏览器3秒自动刷新一次
resp.setHeader("refresh","3");//js
//在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_BGR);
//得到图片
Graphics2D g = (Graphics2D)bufferedImage.getGraphics(); //笔
//设置图片的颜色
g.setColor(Color.pink);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.cyan);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);//响应头把这个值设置为-1,就不会缓存了
resp.setHeader("Cache-Control","no-cache");//不缓存
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(bufferedImage,"png",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999)+"";//四位数
StringBuffer sb = new StringBuffer();
for (int i=0;i<4-num.length();i++){
sb.append("0");//用0填充 保证四位数
}
num = sb.toString() + num;
return num;
}
4、实现重定向
//重定向 sendRedirect 其实就干了下面这两句话的事情
// resp.setHeader("Location","/servlet02/image");
// resp.setStatus(HttpServletResponse.SC_FOUND);
resp.sendRedirect("/servlet02/image");
重定向与请求转发的区别:
相同点:页面都会跳转
不同点:
请求转发的时候url不会发生变化 307
重定向的时候url会发生变化 302
HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法,获得客户端的所有信息;
1、 获取前端传递的参数与请求转发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XdsV0g9D-1625065058251)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201212163038776.png)]
前端要写死,其中${pageContext.request.contextPath} 代表web项目,以post的方式请求项目里的req页面!
<body>
<h1>登录</h1>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/req" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobby" value="女孩">女孩
<input type="checkbox" name="hobby" value="代码">代码
<input type="checkbox" name="hobby" value="唱歌">唱歌
<input type="checkbox" name="hobby" value="电影">电影
<br>
<input type="submit">
</form>
</div>
</body>
后台接收中文乱码问题
req.setCharacterEncoding("utf-8");//后台接收
resp.setCharacterEncoding("utf-8");//传给浏览器
后期可以将这两句话放到过滤器里,不需要每次都写了。
使用req.getRequestDispatcher会出现的问题
本质就是/代表的是当前项目,而不是一个单纯的/
//req.getContextPath()的输出是"/servlet02"
//但是运行的时候说:找不到/servlet02/servlet02/gp
//原因:tomcat设置里的ContextPath中,'/'本身就代表了当前项目/servlet02
//如果tomcat设置里的ContextPath中的'/'改为'/servlet02,则req.getContextPath()读取出来的就是/servlet02/servlet02/
//req.getRequestDispatcher(req.getContextPath()+"/image").forward(req,resp);
req.getRequestDispatcher("/image").forward(req,resp);
3、Cookie、Session
3.1、会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,称之为有状态会话。
你能怎么证明你是某学校的学生?
1、发票 学校给你发票
2、学校登记 学校标记你来过了
一个网站怎么证明你来过?
客户端 服务端
1、服务端给客户端一个信件,客户端下次访问服务器带上信件就可以了:cookie
2、服务器登记你来过了,下次来的时候我来匹配你:session
3.2、保存会话的两种技术
cookie
·客户端技术(响应、请求)
session
·服务器技术 利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中。
常见:网站登录后,只要不换浏览器,下次不需要再登录了。
Cookie保存用户上一次访问时间
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下次带来,我就知道你来了
//解决中文乱码
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
PrintWriter writer = resp.getWriter();
//Cookie,服务器从客户端获取
Cookie[] cookies = req.getCookies();
//判断Cookie是否存在
if(cookies!=null){
//如果存在则取出我想要的cookie
writer.write("你上一次访问的时间是:");
for(Cookie cookie : cookies){
//获取cookie的名字
if(cookie.getName().equals("lastLoginTime")){
//获取cookie中的值
long lastTimeLogin = Long.parseLong(cookie.getValue());
Date date = new Date(lastTimeLogin);
writer.write(date.toLocaleString());
}
}
}else {
//第一次必然没有cookie
writer.write("这是你第一次访问本站");
}
//每次访问服务器给客户端响应一个cookie,下一次的会覆盖上一次的同一个key的
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
resp.addCookie(cookie);
}
}
但是关掉浏览器以后cookie就没了,我们可以设置cookie的存活时间
//设置cookie有效期为一天
cookie.setMaxAge(24*60*60);
但是这样做很不安全的。
3.3、Cookie
1.从请求中拿到cookie信息
Cookie[] cookies = req.getCookies();//获得cookie们
2.服务器响应客户端cookie
cookie.getName()//获得cookie的key
cookie.getValue()//获得cookie的value
new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie
cookie一般会保存在本地的用户目录下appdata
如何在cookie中设置中文?
编码
//保险起见,应该把中文编码为utf-8,注意,获取的时候,需要解码!!
Cookie cookie = new Cookie("name", URLEncoder.encode("沈航冉", "utf-8"));
解码
//解码
String value = cookie.getValue();
value = URLDecoder.decode(value, "utf-8");
System.out.println("name:" + value);
writer.write(value);
一个网站cookie是否存在上限?聊聊细节问题。
·一个Cookie只能保存一个信息
·一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
·cookie大小有限制:4kb
·300个cookie浏览器上限
删除cookie的方法
·不设置有效期,关闭浏览器,自动失效。
·新建一个同名cookie进行覆盖,有效期设置为0(立马删除)
3.4、Session(重点!)
什么是session:
·服务器会给每一个用户创建一个Session对象;
·一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在;
·用户登录之后,整个网站它都可以访问!–>保存用户的信息;保存购物车的信息
//获得session
HttpSession session = req.getSession();
//给session中存东西
session.setAttribute("name","沈航冉");
//获得session的id
String id = session.getId();
//判断session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功!ID为:"+id);
}else{
resp.getWriter().write("session已经存在");
}
经测验,浏览器一打开,session就被生成了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J4pvOT2t-1625065058253)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201213231403821.png)]
发现session在cookie里,猜想创建session的时候:
//Session创建的时候做了什么事情:
//Cookie cookie = new Cookie("JSESSIONID",id);
//resp.addCookie(cookie);
经测试发现,每次刷新的时候,request头和response的头里的sessionID是不一样的
原理理解:
每次刷新s2页面的时候(s2页面只有一句代码:删除当前session)
·首先,进入该页面,请求头拿着的sessionID还是上一次从响应头里获得的sessionID。
·然后,服务器发现你这个浏览器没有session,于是给你创建了一个session,并用指针指向它,将这个新的sessionID放到响应头里。
·最后,执行程序,将指针指向的session空间清空。注意!此时响应头里的sessionID对应的session空间已经被清空,但是sessionID这个字符串已经存在于响应头了,它将会传递给服务器。当你下次再进入该页面的时候,请求头里的sessionID就是这个已经被清空空间的sessionID。
设置session的失效
1、自动注销
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//1.手动注销
session.invalidate();
}
2、手动注销
<!--设置session的默认失效时间-->
<session-config>
<!--15分钟后session自动失效-->
<session-timeout>15</session-timeout>
</session-config>
Session和Cookie小结
Cookie是浏览器保存的,可以保存多个。
Session是服务器保存的,相当于一个类对象,用于保存重要信息。
使用场景:
·保存一个登录用户的信息;
·购物车信息;
·在整个网站中,经常会使用的数据,我们将它保存在Session中。
4、JSP
Java Server Pages:Java服务端页面,也和servlet一样,用于动态web技术!
最大的特点:
·写JSP就像写HTML
·区别:
·HTML只给用户提供静态数据
·JSP页面可以嵌入Java代码,为用户提供动态数据
4.2、JSP原理
思路:JSP到底怎么执行的!
tomcat中有一个work目录;
IDEA中使用tomcat的会在IDEA的tomcat中生产一个work目录。
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问servlet!
JSP最终也会被转成java类
JSP本质就是Servlet
用jsp生成的java的源码:
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 {
//...
}
在_jspService里有:
1、判断请求
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
2、内置一些对象
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; //writer
final java.lang.Object page = this; //page:当前
javax.servlet.jsp.JspWriter _jspx_out = null; //请求
javax.servlet.jsp.PageContext _jspx_page_context = null; //响应
3、在try-catch里,输出页面前增加的代码:
try {
response.setContentType("text/html;charset=utf-8"); //设置响应的页面类型
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中直接使用
*doller+大括号
*使用方法:${pageContext.forward("/s1")}
*这就叫做EL表达式
*/
//out.write(...);
//...
//out/write(...);
}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);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6z5loeDN-1625065058254)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201214213854570.png)]
在JSP页面中:只要是Java代码就会原封不动的输出
如果是HTML代码,就会被转换为out.write的格式输出到前端
4.3、JSP基础语法
任何语言都有自己的语法。JSP作为Java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可!),Java所有语法都支持!
JSP表达式
<%--JSP表达式
语法:<%= 变量或者表达式%>
作用:用来将程序的输出,输出到客户端
--%>
<%=new java.util.Date()%>
JSP声明
<%--JSP声明--%>
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void fun(){
System.out.println("进入了方法fun!");
}
%>
使用<%! … %>表示JSP声明,里面写的东西会被编译到JSP生成的Java的类中,而其他的东西会被生成到_jspService方法中
JSP的注释
<%JSP的注释不会写在客户端显示,HTML就会%>
4.4 JSP指令
1、定制错误页面
<%--方法1、定制错误页面--%>
<%@ page errorPage="500.jsp" %>
<%--显示的声明这是一个错误页面--%>
<%@page isErrorPage="true" %>
2、web.xml里配置错误页面
<!--方法2:除了定制错误页面以外,也可以在web.xml里直接配置-->
<error-page>
<error-code>404</error-code>
<location>/500.jsp</location>
</error-page>
3、include指令 相当于母版页
这个include会将两个页面合二为一(通过writer.write(…))
比如header里定义了int i
在本页面和footer页面就不能再定义i了,因为已经合二为一了。
<%--include指令,包含头部和底部页面,相当于母版页--%>
<%@include file="common/header.jsp" %>
<h2>我是网页主体</h2>
<%@include file="common/footer.jsp"%>
4、JSP标签
jsp标签里也有include,它和<%@include%>指令是有区别的。
jsp标签里的include是将多个页面拼接为一个,本质上还是多个页面。一般采用这种方式,灵活性更高。
<%--jsp标签--%>
<jsp:include page="common/header.jsp"></jsp:include>
4.5、九大内置对象
·PageContext 存东西
·Request 存东西
·Response
·Session 存东西
·Application 【ServletContext】存东西
·config 【ServletConfig】
·out
·page 不用了解
·exception
<%--内置对象--%>
<%
pageContext.setAttribute("name","沈航冉");//保存的数据只在一个页面中有效
request.setAttribute("age",24);//保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("sname","塞申");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("Aname","ServletContext哦");//保存的数据只在服务器中有效,从打开服务器到关闭服务器。
%>
<%--脚本片段中的代码会被原封不动的生成到_jsp.java中--%>
<%
//必须保证java语法的正确性
//从pageContext取出,我们通过寻找的方式来取出
//取出的时候从上到下按顺序,双亲委派机制的方式去寻找!page->request->session->application
//类比JVM:双亲委派机制 从下往上寻找,但是会用最上面的(越上面优先级越高) 应用->扩展类->RT.jar
String name = (String)pageContext.getAttribute("name");
String age = (String) pageContext.getAttribute("age");
String sname = (String) pageContext.getAttribute("sname");
String aname = (String) pageContext.getAttribute("Aname");
%>
<%--使用EL表达式输出最快 ${} --%>
<h1>取出的值为:</h1>
<h3>${name}</h3>
<h3>${age}</h3>
<h3>${sname}</h3>
<h3>${pppname}</h3>
<%--对于不存在的变量,使用JSP表达式会输出null,使用EL表达式什么都不会输出(会报错??!!)--%>
<h3><%= pppname%></h3>
Request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻!用户看完就没用的!
session:客户端向服务器发送请求,产生的数据,用户用完以后还有用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能用,比如:聊天数据!
4.6、JSP标签、JSTL标签、EL表达式
EL表达式:${ }
·获取数据
·执行运算
·获取web开发的常用对象
4.6.1 JSP标签
<%--jsp:forward标签--%>
<%--设置参数--%>
<jsp:forward page="pageContextTestDemo01.jsp">
<jsp:param name="c1" value="context1"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
<%--取出jsp标签里存的参数--%>
c1:<%=request.getParameter("c1")%>
<%--经测试,这里的age输出的是12,而不是在本页面通过Attribute定义的24--%>
age:<%=request.getParameter("age")%>
4.6.2、JSTL表达式(JSP标准标签库)
JSTL标签库的使用就是为了弥补HTML标签的不足。它自定义许多标签,可以供我们使用。标签的功能和java代码一样!!
核心标签
格式化标签
SQL标签
XML标签
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NUPC9HPh-1625065058255)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20201216132037083.png)]
<%--引入JSTL核心标签库,我们才能使用JSTL标签 c代表core--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL标签库使用方法
·引入对应的taglib
·使用其中的方法
·在Tomcat中也需要引入jstl的包,否则会报错:JSTL解析错误
<%--
Created by IntelliJ IDEA.
User: shenhangran
Date: 2020/12/16
Time: 1:17 下午
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL核心标签库,我们才能使用JSTL标签 c代表core--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>if测试</h4>
<form action="JSTLDemo01.jsp" method="get">
<%--
EL表达式获取表单中的数据
${param.参数名}
--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
<%--判断如果提交的用户是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="管理员欢迎你"></c:out>
</c:if>
</form>
</body>
</html>
反正我觉得这玩意变得更复杂了,不如直接写java
5、JavaBean
实体类
JavaBean有特性的写法:
·必须要有一个无参构造
·属性必须私有化
·必须有对应的set/get方法
一般用来和数据库做映射 ORM
ORM:对象关系映射
·表—>类
·字段—>属性
·行记录—>对象
6、MVC三层架构
什么是MVC: Model、View、Controller 模型(实体类的字段)、视图(JSP页面)、控制器(Servlet)
6.1、早些年的架构
Servlet和Jsp都可以写Java代码;为了易于维护和使用,Servlet专注于处理请求,以及控制视图跳转;JSP专注于显示数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZU8rWBw-1625065058256)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20210323213939719.png)]
用户直接访问控制层,控制层可以直接操作数据库;
servlet -- CRUD -->数据库
弊端:程序十分臃肿,不利于维护 servlet代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
(比如 程序员--JDBC--数据库 ) 这样就加了一层JDBC
6.2、MVC三层架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHewtQcX-1625065058256)(/Users/shenhangran/Desktop/学习笔记/我的/Java Web 笔记.assets/image-20210323214722643.png)]
Model
·业务处理:业务逻辑(Service层)
·数据持久层:CRUD(Dao层)
View
·展示数据
·提供链接发起Servlet请求(a , form ,img …)
Controller
·接收用户的请求:(req:请求参数、Session信息…)
·交给业务层处理对应的代码
·控制视图的跳转
登录 ---> 接收用户的登录请求 ---> 处理用户的请求(获取用户登录的参数,username,password) ---> 交给业务层处理登录业务(判断用户名密码是否正确:[事物回滚是Service层的重要意义]) --->Dao层查询用户名和密码是否正确 ---> 数据库
7、Filter(重点!)
过滤器:用来过滤网站的数据;
·处理中文乱码
·登录验证
·处理垃圾请求
Filter开发步骤
1.导包,必须要导入javax.servlet里的Filter,千万不要导错了!
2.编写过滤器
实现Filter的接口即可
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
//初始化
//web服务器启动的时候,就已经初始化了,随时等待过滤对象出现!
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
//可以在服务器一启动的时候就设置一些属性进去!不过没有人这么做。
filterConfig.getServletContext().setAttribute("serverName","tomcat9.0.31");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//Chain:链
/*
* 1. 过滤中的所有代码,在过滤特定请求的时候都会执行
* 2. 必须要让过滤器继续同行
* chain.doFilter(request,response);
* */
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前...");
chain.doFilter(request,response);//为什么要设置一个链呢?
//因为要让我们的请求继续走,如果不写,程序到这里就截止了。这是被迫写的,要交接给后面一个过滤器!(即.过滤器有多个,像链式法则一样连着)
System.out.println("CharacterEncodingFilter执行后...");
}
//销毁:web服务器关闭的时候,过滤器才会销毁!
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
System.gc();//没啥用
}
}
3.在web.xml中配置Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.shen.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
8、监听器
实现监听器的步骤
1.实现一个监听器的接口;(有N种)
//统计网站在线人数:统计Session
public class OnLineCountListener implements HttpSessionListener {
//创建Session监听:一旦创建一个session,就会触发一次这个事件!
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext servletContext = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onLineCount =(Integer) servletContext.getAttribute("OnLineCount");
//如果没有就先定义
if(onLineCount==null){
onLineCount=new Integer(1);
}else{
int count = onLineCount.intValue();//拆箱
onLineCount = new Integer(count+1);
}
servletContext.setAttribute("OnLineCount",onLineCount);
}
//销毁Session监听:一旦session销毁就会触发一次这个事件
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext servletContext = se.getSession().getServletContext();
Integer onLineCount =(Integer) servletContext.getAttribute("OnLineCount");
//如果没有就先定义
if(onLineCount==null){
onLineCount=new Integer(0);
}else{
int count = onLineCount.intValue();//拆箱
onLineCount = new Integer(count-1);
}
servletContext.setAttribute("OnLineCount",onLineCount);
}
/*
*Session销毁:
* 1.手动销毁
* 2.自动销毁(设置过期时间)
* */
2.web.xml里进行配置监听器
3.看情况是否使用!
9、过滤器&监听器常见应用
监听器在GUI编程中经常使用。
用户登陆之后才能进入主页,用户注销后就不能进入主页了。
步骤如下:
- 用户登录之后,向Session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录 即 权限管理。
10、JDBC
Java连接数据库
回顾数据库基础语句:
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
)
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','zs@qq.com','2000-01-01');
SELECT * FROM users;
导包
<!--mysql的驱动-->
<dependency>
<groupID>mysql</groupID>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
Junit可以用于单元测试
在想执行的方法前面加一个注解@Test就可以直接运行,测试的时候不需要先写一个类。