JavaWeb学习笔记1

1. 基本概念

  • 静态web:
    • HTML、CSS
    • 提供给所有人的数据始终不会变化
    • 轮播图,伪动态
    • 缺点:无法和数据库交互,数据无法持久化,用户无法交互
  • 动态web:
    • 技术栈:Servlet/JSP、ASP、PHP
    • 每个人在不同的时间、地点看到的信息各不相同
    • 缺点:动态web资源出现错误,需要重新编写后台程序
  • web应用程序——Tomcat服务器:
    • 组成部分:HTML、CSS、JS;JSP、Servlet;Java程序;jar包;配置文件(properties)

2. Web服务器

2.1 技术讲解

B/S:浏览和服务器;C/S:客户端和服务器

  • ASP:
    • 微软,国内最早流行,在HTML中嵌入了VB的脚本,ASP+COM
    • 基本一个页面都有几千行的业务代码,维护成本高
    • C#
    • IIS
  • PHP:
    • 开发速度很快,功能很强大,跨平台,代码很简单
    • 无法承载大访问量的情况(局限)
  • JSP/Servlet:
    • Sun公司主推的B/S架构
    • 基于Java语言
    • 可以承载三高问题带来的影响
    • 语法像ASP

2.2 Web服务器

服务器是一种被动的操作,用来处理用户的请求并返回响应。

  • IIS:
    • 微软,ASP,Windows中自带的
  • Tomcat

默认端口号:Tomcat/8080;MySQL/3306;http/80;https/443

面试:网站是如何进行访问的?

  • 输入一个域名;
  • 客户端查询本机的C:\Windows\System32\drivers\etc\hosts配置文件有没有这个域名的映射:有则直接返回对应的IP地址;没有则通过交换机去DNS服务器找(不在本机);

2.3 Web网站发布

  • webapps:
    • ROOT
    • test:网站的目录名
      • WEB-INF
        • classes:Java程序
        • lib:web应用依赖的jar包
        • web.xml:网站配置文件
      • index.html/index.jsp:默认的首页
      • static
        • css
        • js
        • img
        • ……

3. HTTP

超文本传输协议
请求行:
请求方式——
GET:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效;
POST:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全但不高效。
消息头:
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:编码格式:GBK、UTF-8、GB2312、ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成时断开还是保持连接
响应状态码:
3XX:重定向304
4XX:找不到资源404
5XX:服务器代码错误500;网关错误502
面试:当你的浏览器地址栏输入地址并回车的一瞬间到页面能够展示,经历了什么?

4. Maven详解

Maven的高级之处在于它会帮你导入这个jar包依赖的其他jar包。

Maven由于约定大于配置,可能存在的问题是自己写的配置文件无法被导出或者生效,解决方案:在build中配置resources防止资源导出失败。

#POM.xml
<!--Package:项目的打包方式:
jar:java应用
war:Javaweb应用
-->
    <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>

5. Servlet详解

Servlet就是sun公司开发动态web的一门技术。Sun在这些API中提供一个接口叫做Servlet,如果你想开发一个Servlet程序,只需要完成两个步骤:

  1. 编写一个类实现Servlet接口;
  2. 把开发好的Java类部署到web服务器中。

把实现了Servlet接口的Java程序叫做Servlet。

Servlet是由web服务器调用,web服务器收到浏览器请求后会调用Servlet的Service方法,该方法由我们自己编写的实现类重写,即接收并处理请求后给出响应信息,然后web容器(Tomcat)读取响应信息。

5.1 HelloServlet

  1. 构建一个普通的Maven项目,删掉src目录,后续在该项目里建立Module,这个空的工程就是Maven主工程;
  2. 导入依赖至主工程POM;
  3. 关于Maven父子工程的理解:父项目中会有module,子项目中会有parent;父项目中的jar包,子项目可以直接使用,反之则不能。
  4. Maven环境优化:修改web.xml为最新的;将maven的结构搭建完整。
<?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">
</web-app>
  1. 编写一个servlet程序:编写一个普通类;实现servlet接口继承HttpServlet;

Servlet接口Sun公司有两个默认的实现类:HttpServlet、

  1. 编写Servlet的映射。为什么需要映射:所写Java程序需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的servlet,还需要给他一个浏览器能够访问。
<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.servlet.servlet01.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
  1. 配置tomcat,配置项目发布的路径。

5.2 Mapping问题

  1. 一个Servlet可以指定一个映射路径;
  2. 一个Servlet可以指定多个映射路径;
  3. 一个Servlet可以指定通用映射路径;
  4. 默认请求路径/*;
  5. 可以自定义前缀、后缀实现请求映射,注意:*前面不能加项目映射的路径;
  6. 优先级问题,指定了固有的映射路径优先级最高,如果找不到才会走默认的处理请求。

5.3 ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

5.3.1 共享数据

我在这个Servlet中保存的数据,可以在另一个Servlet中共享

//.....
ServletContext context = this.getServletContext();
String username = "xx";
context.setAttribute("username",username);
//.....
ServletContext context = this.getServletContext();
String username = (String)context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字:"+username);
//配置XML

5.3.2 获取初始化参数及请求转发

<!--配置一些web应用初始化参数-->
<context-param>
	<param-name>url</param-name>
	<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
//......获取初始化参数
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
//......请求转发
ServletContext context = this.getServletContext();
context.getRequestDispatcher("/gp").forward(req,resp);

转发路径不会变;重定向路径会变。

5.3.3 读取资源文件

Properties类,以往使用绝对路径,但在web服务器只能使用相对路径。
在java、resources目录下新建properties文件,打包后统一在target的classes目录下,俗称该路径为classpath;需要一个文件流。

username=root
password=123456
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String password = prop.getProperty("password");

5.4 HttpServletResponse

响应:Web服务器接收到客户端的HTTP请求,会针对这个请求分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;如果要获取客户端请求过来的参数找HttpServletRequest,如果要给客户端响应一些信息找HttpServletResponse。

5.4.1 简单分类

负责向浏览器发送数据的方法:

ServletOutputStream getOutputStream() throws IOException;//
PrintWriter getWriter() throws IOException;//中文

负责向浏览器发送响应头的方法:

void setCharacterEncoding(String varl);
void setStatus(int varl);
//……

响应的状态码:
200、300、404、500等

5.4.2 常见应用

  1. 向浏览器输出消息——resp.getWriter().print();
  2. 下载文件——
    1. 获取下载文件的路径;
    2. 下载的文件名是啥;
    3. 想办法让浏览器能够支持下载我们需要的东西;
    4. 获取下载文件的输入流;
    5. 创建缓冲区;
    6. 获取OutputStream对象;
    7. 将FileOutputStream流写入到buffer缓冲区;
    8. 使用OutputStream将缓冲区中的数据输出到客户端。
  3. 验证码功能——
    • 前端实现;
    • 后端实现,需要用到Java的图片类,生成一个图片:
      1. 如何让浏览器5秒自动刷新一次;
      2. 在内存中创建一个图片;
      3. 得到图片;
      4. 设置图片的背景颜色;
      5. 给图片写数据;
      6. 告诉浏览器,这个请求用图片的方式打开;
      7. 网站存在缓存,不让浏览器缓存;
      8. 把图片写给浏览器。
  4. 实现重定向—— 一个web资源收到客户端请求后,它会通知客户端去访问另外一个web资源,常见场景:用户登录成功
/*resp.setHeader("Location","/response/img");
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);*/
void sendRedirect(String varl) throws IOException;

面试题:请聊聊重定向和转发的区别?
相同点:实现页面跳转
不同点:请求转发的时候,url不会变化,307;重定向会变化,302。

5.5 HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过HTTP协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。

  • 获取前端传递的参数——req.getParameter();req.getParameterValues();
  • 请求转发——
req.setCharacterEncoding("utf-8");//处理后台接收中文乱码问题
resp.setCharacterEncoding("utf-8");req.getRequestDispatcher("/success.jsp").forward(req,resp);
//这里的/代表当前的web应用

6. Cookie、Session

6.1 会话

会话: 用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;
有状态会话: 服务端给客户端一个信件,客户端下次访问服务端带上信件即可(cookie);服务器登记你来过了,下次来会自动匹配(session)。

6.2 保存会话的两种技术

cookie
——客户端技术(响应,请求)
session
——服务器技术,利用这个技术可以保存用户的会话信息,我们可以把信息或者数据放在session中
常见场景
网站登录后,第二次访问直接进入;

6.3 Cookie

  • 从请求中获得cookie信息;
  • 服务器响应给客户端cookie;
//Cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie中的Value
new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
//Cookie有效期为一天
cookie.setMaxAge(24*60*60);//设置Cookie有效期
resp.addCookie(cookie);

cookie一般会保存在本地的用户目录下appdata;

一个网站cookie是否存在上限?

  1. 一个Cookie只能保存一个信息;
  2. 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
  3. Cookie大小有限制4kb;
  4. 300个cookie浏览器上限。

删除Cookie:

  • 不设置有效期,关闭浏览器,自动失效;
  • 设置有效期时间为0。

传递中文字符:

URLEncoder.encode("你好","utf-8");//编码
URLDecoder.decode(cookie.getValue(),"utf-8");//解码

6.4 Session(重点)

服务器会给每一个**用户(浏览器)**创建一个Session对象,一个Session独占一个浏览器,只要浏览器没关,这个Session就存在。用户登录之后,整个网站都可以访问。——>保存用户的信息;保存购物车的信息。

Cookie和Session的异同:
Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个);
Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费);
Session对象由服务创建;
Session建议保存一个登录用户的信息;购物车信息;在整个网站中经常会使用的数据。
cookie存本地;session存服务器;servletcontext存全局。

HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();//手动注销session
<!--设置session默认的失效时间-->
<session-config>
	<!--15分钟后session自动失效,以分钟为单位-->
	<session-timeout>15</session-timeout>
</session-config>

7. JSP

7.1 JSP原理剖析

Java Server Pages:Java服务器端页面,也和servlet一样,用于动态web技术。
HTML只提供静态数据,JSP可以嵌入Java代码,为用户提供动态数据。
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet,JSP最终也会被转换成为一个Java类。
JSP本质上就是一个Servlet。
JAVA代码原封不动输出到前端,HTML代码则用out.write()输出。

	<dependencies>
        <!--Servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!--JSP依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <!--JSTL表达式的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>

JSP声明<%!%>会被编译到JSP生成Java的类中。其他的<%=%>和<%%>会被生成到_jspService方法中。

JSP的注释不会在客户端显示,HTML则会。

<!--我是HTML的注释-->
<%--我是JSP的注释--%>

<%@JSP指令%>

<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>

<%--jsp标签:拼接页面,本质还是三个,不会报错--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>

注意:
项目中新建文件夹放在web目录下,static:css、img、js、plugins等;
WEB-INF对用户不可见。

7.2 九大内置对象

  • PageContext 存东西
  • Request 存东西;
    • 客户端向服务器发送请求,产生的数据,用户看完就没用了,比如新闻,看完没用
  • Response
  • Session 存东西;
    • 客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如购物车
  • Application 【ServletContext】存东西;
    • 客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如聊天数据
  • config 【ServletConfig】
  • out
  • page 几乎不用
  • exception
<%
//作用域从底层到高层:page->request->session->application
//类似JVM:双亲委派机制
	pageContext.setAttribute("name","zz");//保存数据只在一个页面有效
	request.setAttribute("name","zz");//保存数据在一次请求中有效,请求转发会携带这个数据
	session.setAttribute("name","zz");//保存数据只在一次会话中有效,从打开浏览器到关闭浏览器
	application.setAttribute("name","zz");//保存数据只在服务器中有效,从打开服务器到关闭服务器
%>

双亲委派机制

<%
	//请求转发
	pageContext.forward("/index.jsp");//前端
	request.getRequestDispatcher("/index.jsp").forward(request,response);//后端
	
%>

7.3 JSP标签、JSTL标签、EL表达式

在Tomcat中也需要引入JSTL的包,否则会报错:JSTL解析错误。

<!--JSTL表达式的依赖-->
<dependency>
	<groupId>javax.servlet.jsp.jstl</groupId>
	<artifactId>jstl-api</artifactId>
	<version>1.2</version>
</dependency>
<!--standard标签库-->
<dependency>
	<groupId>taglibs</groupId>
	<artifactId>standard</artifactId>
	<version>1.1.2</version>
</dependency>

EL表达式:${}

  • 获取数据;
  • 执行运算;
  • 获取web开发的常用对象。

JSP标签:

<%--
等同于
http://localhost:8080/jsptag.jsp?name=kk&age=12
--%>
<jsp:forward page="/jsptag2.jsp">
	<jsp:param name="name" value="kk"></jsp:param>
	<jsp:param name="age" value="12"></jsp:param>
</jsp:forward>

JSTL标签:
JSTL标签库的使用就是为了弥补HTML标签的不足,它自定义了许多标签可供使用,标签的功能和Java代码一样。

  • 核心标签
  • 格式化标签
  • SQL标签
  • XML标签

8. JavaBean

JavaBean是实体类,有特定的写法:

  • 必须要有一个无参构造;
  • 属性必须私有化;
  • 必须有对应的get/set方法;
  • 一般用于和数据库的字段做映射。

实体类:一般和数据库中的表结构一一对应。
ORM:对象关系映射

  • 表–>类
  • 字段–>属性
  • 行记录–>对象

9. MVC三层架构

Model模型、View视图、Controller控制器

9.1 早年

JSP
Servlet
JDBC
用户
View:视图
Controller:控制器
专注于处理请求及控制视图跳转
专注于显示数据
JavaBean:pojo:entity
数据库

弊端:程序臃肿,不利于维护;servlet的代码中要处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

9.2 MVC

操作
转发或重定向
Model
select
JDBC
用户
View:JSP展示数据模型及提供操作
Controller:Servlet接收请求及视图跳转
service:login:logout:查询全部用户
JavaBean:pojo:entity
数据库

Model模型:

  • 业务处理:业务逻辑(service)
  • 数据持久层:CRUD(Dao)

View视图:

  • 展示数据;
  • 提供链接发起Servlet请求(a,form,img…)

Controller控制器(Servlet):

  • 接收用户的请求:(req:请求参数,Session信息…)
  • 交给业务层处理对应的代码
  • 控制视图的跳转

10. Filter

过滤器,用来过滤网站的数据:处理中文乱码;登录验证……

import javax.servlet.*;
import java.io.IOException;
public class ff implements Filter {
    //初始化
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
	//chain链:过滤中的所有代码,在过滤特定请求的时候都会执行;必须要让过滤器继续运行chain.doFilter(request,response);
    @Override
    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服务器关闭的时候,过滤器会销毁
    @Override
    public void destroy() {
    }
}
<!--web.xml中配置-->
<filter>
	<filter-name>CharacterEncodingFilter</filter-name>
	<filter-class>com.example.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>CharacterEncodingFilter</filter-name>
	<!--只要是/servlet的任何请求,都会经过这个过滤器-->
	<url-pattren>/servlet/*</url-pattern>
</filter-mapping>

11. 监听器

实现一个监听器的接口(有N种):
统计网站在线人数:统计session——HttpSessionListener

public class OnlineCountListener implements HttpSessionListener{
	public void sessionCreated(HttpSessionEvent se){
		ServletContext ctx = se.getSession().getServletContext();
		Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
		if(onlineCount==null){
			onlineCount = new Integer(1);
		}else {
			int count = onlineCount.intValue();
			onlineCount = new Integer(count+1);
		}
		ctx.setAttribute("OnlineCount",OnlineCount);
	}
	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);
	}
}
<!--web.xml中配置-->
<listener>
	<listener-class>com.example.OnlineCountListener</listener-class>
</listener>

session销毁:1.手动销毁 getSession().invalidate();2.自动销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值