Java Web从入门到实践

1. 基本概念

1.1 前言

web开发:

  • web 网页
  • 静态web html、css 提供给所有人看的数据,始终不会发生变化
  • 动态web 提供给所有人看的数据,会发生变化 每个人在不同时间 不同地点看到的信息不同 技术栈:Servlet/JSP/ ASP

在Java中,动态web资源开发技术统称为Java Web

1.2 web应用程序

可以提供浏览器访问的程序

  • a.html、b.html…多个web资源,这些web资源可以被外界访问,对外界提供服务
  • URL
  • 这些所有的web资源都会被放在同一个文件夹下,web应用程序->Tomcat服务器
  • 一个web应用由多部分组成
    • html、css、js
    • jsp、servlet
    • java程序
    • jar包
    • 配置文件

web应用程序编写完毕后,若想提供给外界访问,需要一个服务器统一管理

1.3 静态web

  • *.html 如果服务器上存在这些东西,就可以直接读取
  • 存在缺点:1.web页面无法动态更新,所有用户看到的都是同一个页面 2.无法和数据库交互

1.4 动态web

页面会动态展示

缺点:假如服务器动态资源出现错误,就需要重新编写后台程序
优点:1.可以动态更新,所有用户看到的都不是同一个页面 2.可以于数据库交互(数据持久化)

2. web服务器

ASP:微软 在html中嵌入了VB的脚本
JSP/Servlet:SUN公司主推的B/S架构,基于JAVA语言的 可以承载三高问题
PHP:开发速度快,功能强大,跨平台,代码简单 但是无法承载大访问量

服务器是一种被动操作,用来处理用户的一些请求和给用户一些响应信息
IIS:微软的 ASP程序 windows自带
Tomcat:运行JSP和Servlet

3. Tomcat

3.1 安装Tomcat

1.访问官网

https://tomcat.apache.org/index.html

2.选择相应版本

3.下载压缩包 解压

3.2 Tomcat启动

文件夹内容:

启动Tomcat
打开startup.bat文件,可以访问http://localhost:8080/
打开shutdown.bat文件,关闭

3.3 Tomcat配置

核心配置文件:

可以配置启动的主机:默认主机为localhost->127.0.0.1 默认存放网站的位置为webapps

 <Host name="localhost"  appBase="webapps"unpackWARs="true" autoDeploy="true">

配置启动的端口号:默认为8080

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />

高难度面试题
请你谈谈网站是如何进行访问的?
1.输入一个域名,点击回车
2.检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名的映射
3.如果有,直接返回对应的IP地址 没有的话去DNS(管理全部的域名)服务器上找

3.5 发布一个web网站

将自己的网站放到服务器(Tomcat)指定的web应用的文件夹(webapps)下
使用http://localhost:8080/manager就可以访问具体的

4. Http

4.1什么是Http

超文本传输协议是一个简单的请求和相应协议,通常运行在TCP上。
超文本:图片、音乐、视频…
端口:80
Https:端口:443 安全的

4.2 两个时代

http1.0

  • HTTP/1.0:客户端可以于web服务器连接后,只能获得一个web资源,断开连接
    http2.0:
  • HTTP/1.1:客户端可以于web服务器连接后,可以获得多个web资源

4.3 Http请求

客户端->发请求->服务器
以请求百度为例:

Request URL:https://www.baidu.com/?tn=48021271_8_hao_pg //请求地址
Request Method:GET  //请求方法 get/post
Status Code:200 OK   // 状态码 200
Remote Address:182.61.200.7:443 //远程地址
Accept:text/html
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9
Cache-Control:max-age=0
Connection:keep-alive

请求行

  • 请求行中的请求方式:GET
  • 请求方式:GET、POST、HEAD、DELETE、PUT…
    • get:请求携带的参数较少,大小会限制,会在URL中显示内容,不安全但高效
    • post:请求携带的参数无限制,不会在URL中显示内容,安全但不高效

消息头

Accept:告诉浏览器支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8  GB2312
Accept-Language:告诉浏览器 它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成时是断开还是连接

4.4 Http响应

服务器->响应->客户端
以百度响应为例:

Cache-Control:private   //缓存控制
Connection:keep-alive  //连接
Content-Encoding:gzip //编码
Content-Type:text/html;charset=utf-8 //类型

响应体

Accept:告诉浏览器支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8  GB2312
Accept-Language:告诉浏览器 它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成时是断开还是连接

响应状态码
200:响应成功 200
3××:重定向
4××:资源不存在 404
5××:服务器代码错误 500 502(网关错误)

5. Maven

在JavaWeb开发中,需要使用大量的jar包,需要手动导入

5.1 Maven项目架构管理工具

用来方便导入jar包
核心思想:约定>配置
Maven会规定如何编写Java代码

5.2 下载安装Maven

官网:>https://maven.apache.org/

下载完后解压

5.3 配置环境变量

配置如下:

  • 1.在环境变量中添加 M2_HOME 变量值为maven目录下的bin目录

  • 2.在环境变量中添加 MAVEN_HOME 变量值为maven的主目录

  • 3.在path中添加 %MAVEN_HOME%\bin

  • 4.测试 在cmd中 mvn -version

5.4 阿里云镜像

  • 镜像(mirrors):加速下载
<mirror>    <id>alimaven</id>    <mirrorOf>*</mirrorOf>    <name>aliyun maven</name>    <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>

5.5 本地仓库

5.6 IEDA使用Maven



5.7 普通Maven项目

这个是干净的

这个只有web应用才有

5.8 标记文件夹

5.9 在IDEA中配置Tomcat


解决警告问题 为什么会有该问题? 我们访问一个网站需要指定一个文件夹名字

5.10 pom文件

pom.xml 是maven的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 配置的GAV--><groupId>org.example</groupId><artifactId>Maven</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><!-- Package:项目的打包方式jar:java应用war:JavaWeb应用--><name>Maven Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><!--  配置--><properties><!--项目的默认构建编码--><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!--编码版本--><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target></properties><!--项目依赖--><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies><!--项目构建用的东西--><build><finalName>Maven</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build>
</project>

maven由于他的约定大于配置,有时会遇到自己写的配置文件无法导出或者生效的问题,解决方案:

<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>

6. Servlet

6.1 Servlet简介

Servlet是Sun公司开发动态web的一门技术
Sun在这些API提供一个接口:Servlet,如果开发一个Servlet程序,只需完成以下两步:

  • 编写一个类,实现Servlet接口
  • 把开发好的java类部署到web服务器中

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

6.2 HelloServlet

  1. 构建一个maven的普通项目,删除src,之后建立模块,这个空的工程就是Maven主工程
  2. 关于Maven父子工程的理解:
    在父项目中增加一个
<modules>    <module>Servlet-01</module>
</modules>

父项目的jar包子项目可以使用 继承关系
3. Maven环境优化
将子模块的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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true">
</web-app>
  1. 编写一个Servlet程序
  • 编写一个普通类
  • 实现Servlet接口,Sun公司将Servlet有两个实现类(Servlet->GenericServlet->Http) 这里继承HttpServlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;public class HelloServlet extends HttpServlet {// 由于get/post只是请求实现的方式不同,可以相互调用,业务逻辑一样@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {PrintWriter writer = resp.getWriter();//响应流writer.println("hello,Servlet");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
  1. 编写Servlet的映射

为什么需要映射? 我们写的是Java程序,如果通过浏览器访问,需要浏览器连接web服务器,所以需要在web服务器中注册Servlet,还需要一个浏览器能够访问的路径

在web.xml中编写

     <!-- 注册Servlet--><servlet><servlet-name>hello</servlet-name><servlet-class>HelloServlet</servlet-class></servlet><!--Servlet的请求路径--><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
  1. 配置Tomcat
    注:配置项目发布的路径

  2. 测试

http://localhost:8080/s1/hello

6.3 Servlet原理

Servlet由web服务器,web服务器收到浏览器请求之后,

6.4 Mapping问题

  1. 一个Servlet可以指定一个映射路径
 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
  1. 一个Servlet可以指定多个映射路径
 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello2</url-pattern></servlet-mapping><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello3</url-pattern></servlet-mapping>
  1. 一个Servlet可以指定通用映射路径
 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello/*</url-pattern></servlet-mapping>
  1. 默认请求路径 跳过主页,直接访问该路径
 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>
  1. 自定义后缀 使用http://localhost:8080/index/12246546.abc 访问
 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>*.abc</url-pattern></servlet-mapping>
  1. 优先级问题
    指定了固定的映射路径优先级最高,如果找不到就会走默认的处理请求
    http://localhost:8080/index/hello 输入后会进入hello页面而不是404页面
 <servlet><servlet-name>hello</servlet-name><servlet-class>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>ErrorServlet</servlet-class></servlet><servlet-mapping><servlet-name>error</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>

6.5 ServletContext

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

  • 1.共享数据

放数据

 ServletContext context = this.getServletContext();String username = "张三";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);
  • 2.获取初始化参数
    在web.xml中设置初始化参数
<context-param><param-name>url</param-name><param-value>jdbc:mysql:localhost:3305/MyBatis</param-value>
</context-param>

获取

ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
  • 3.实现请求转发 路径没变
  ServletContext context = this.getServletContext();RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gc"); //转发的请求路径requestDispatcher.forward(req,resp);  //调用forward实现请求转发
  • 4.读取properties文件
    Properties
  • 在java目录下新建properties
  • 在resources目录下新建properties

发现都被打包到了同一个路径下:classes,通常称为类路径(classpath)

db.properties

username=root
password=root

获取代码

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().print(username+":"+password);

6.6 HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的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);

常见应用:
1.向浏览器输出消息
2.下载文件

  • 下载路径
  • 文件名
  • 设置浏览器支持下载我们需要的东西
  • 获取下载文件的输入流
  • 创建缓冲区
  • 获取OutputStream
  • 将FileOutputStream流写入buffer缓冲区
  • 使用OutputStream将缓冲区中的数据输出到客户端
        String s = "D:\\java代码\\Maven\\ServletDemo\\Response\\src\\main\\resources\\头像.jpg";String fileName = s.substring(s.lastIndexOf("\\") + 1);resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"utf-8"));          FileInputStream fis = new FileInputStream(s);int len = 0;byte[] buffer = new byte[1024];ServletOutputStream os = resp.getOutputStream();while((len=fis.read(buffer))!=-1){os.write(buffer,0,len);}os.close();fis.close();

3.验证码功能

  • 前端实现:
  • 后端实现:java图片类
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//让浏览器三秒刷新一次resp.setHeader("refresh","3");//在内存中创建一个图片BufferedImage image = new BufferedImage(80,20, BufferedImage.TYPE_INT_RGB);//得到图片Graphics2D g = (Graphics2D)image.getGraphics(); //笔//设置图片背景颜色g.setColor(Color.WHITE);g.fillRect(0,0,80,20);//给图片写数据g.setColor(Color.GRAY);g.setFont(new Font(null,Font.BOLD,20));g.drawString(makeNum(),0,20);//告诉浏览器,这个请求用图片打开resp.setContentType("image/jpeg");//不让浏览器缓存resp.setDateHeader("expires",-1);resp.setHeader("Cache-Control","no-cache");resp.setHeader("Pragma","no-cache");//把图片写给浏览器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+num;return num;}

4.实现重定向
一个web资源收到客户端请求后,告诉客户端去访问另一个web资源

void sendRedirect(String var1) throws IOException;resp.sendRedirect("image");

面试题:
重定向与转发的区别:
相同点:页面都会跳转
不同点:重定向会改变url 转发不会

<html>
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login" method="get"><span>用户名:</span><input type="text" name="username"><br><span>密码:</span><input type="password" name="password"><br><input type="submit" value="提交">
</form>
</body>
</html>
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class RequestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//处理请求String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username+":"+password);resp.sendRedirect("/index/Success.jsp");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

6.7 HttpServletRequest

获取前端参数,并请求转发

        req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");String username = req.getParameter("username");String password = req.getParameter("password");String[] hobbies = req.getParameterValues("hobbies");System.out.println(username);System.out.println(password);for (String hobby : hobbies) {System.out.println(hobby);}req.getRequestDispatcher("/success.jsp").forward(req,resp); //请求转发 不需要加虚拟路径  /r
//        resp.sendRedirect("/r/success.jsp");   //重定向需要写

7. Cookie、Session

7.1 会话

用户打开浏览器,点击了很多链接,访问了多个web资源,关闭浏览器,这个过程称之为会话
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了 cookie
2.服务器登记来过了,下次来的时候匹配

7.2 保存会话的两种技术

cookie:

  • 客户端技术(请求和响应)

session:

  • 服务器技术,利用这个技术可以保存用户的访问信息
    常见场景:登录网站后,之后就可以不用输账号密码 就直接登录了

7.3 Cookie

1.从请求中拿到Cookie信息
2.服务器响应给客户端Cookie

Cookie[] cookies = req.getCookies(); //获得cookie
cookies[i].getName()// 获得cookie的key
cookies[i].getValue()// 获得cookie的value
new Cookie("LastLoginTime",System.currentTimeMillis()+"") //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie
cookie.setMaxAge(0); //注销cookie
        req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");PrintWriter out = resp.getWriter();Cookie[] cookies = req.getCookies();if(cookies!=null){out.write("您最后一次访问的时间为:");for (int i = 0; i < cookies.length; i++) {if(cookies[i].getName().equals("LastLoginTime")){String value = cookies[i].getValue();long l = Long.parseLong(value);Date date = new Date(l);out.write(date.toLocaleString());}}}Cookie cookie = new Cookie("LastLoginTime",System.currentTimeMillis()+"");resp.addCookie(cookie);

可以解决乱码问题

URLEncoder.encode("张三","utf-8")  //编码
String decode = URLDecoder.decode(name, "utf-8"); //解码

删除cookie

  • 不设置有效期,关闭浏览器(所有页面全部关掉)自动失效
  • 设置有效期时间为0

7.4 Session(重点)

  • 服务器会给每一个用户创建一个Session对象
  • 一个session独占一个浏览器,只要浏览器不关闭,这个session就存在
  • 用户登录之后,整个网站都可访问->保存用户的信息
          req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");HttpSession session = req.getSession();session.setAttribute("name", "李四");String sessionId = session.getId();if(session.isNew()){resp.getWriter().write("该sessionID是新创建的,ID="+sessionId);}else{resp.getWriter().write("服务器中已存在该sessionID,ID="+sessionId);}//只要浏览器打开后就会创建Session,关闭浏览器会消失// Session在创建的时候发生了什么// 1. 创建一个名JSESSIONID 值为SessionID的cookie// 2. 将该cookie响应回去// Cookie cookie = new Cookie("");// resp.addCookie(cookie);

存储、取出session的值

//session存储对象
HttpSession session = req.getSession();
Student s1 = new Student(101,"张三",12); //session可以存对象
session.setAttribute("student", s1);
//从session中取出对象
HttpSession session = req.getSession();
Student s1 = (Student)session.getAttribute("name");
resp.getWriter().write("您好:"+s1.toString());

注销session
1.关闭服务器
2.手动注销

HttpSession session = req.getSession();
session.removeAttribute("student");
//手动注销session
session.invalidate();

3.自动注销 在web.xml中设置

<!--设置Session的自动失效-->
<session-config>    <!--设置session 15分钟后失效-->    <session-timeout>15</session-timeout>
</session-config>

Session和Cookie的区别:
1.cookie是创建于服务器端,保存在浏览器端,通过cookie.setMaxAge(2000)来设置存活时间,如果没有设置,浏览器关闭的时候就消亡了,可以被多个同类型的浏览器共享
2.session创建于服务器端,保存在服务器端,但是sessionid作为一个cookie存放在浏览器端,一个session对象为一个用户浏览器服务

8. JSP

8.1 JSP简介

java server pages: java服务器端页面,跟servlet一样,用于开发动态web
jsp就像是html
区别:

  • html只提供静态数据
  • jsp可嵌入java代码,提供动态数据

8.2 JSP原理

浏览器向服务器发送请求,不管访问什么资源,其实还是在访问Servlet
JSP最终也变会转换为一个Java类

C:\Users\yonghuming\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\ff4cf2a1-32e4-4c9a-8d89-ae9d47eeeeac\work\Catalina\localhost\Session_war\org\apache\jsp

JSP本质就是一个Servlet
index_jsp.java文件中有以下实现

public void _jspInit() { //初始化}public void _jspDestroy() { //销毁}public void _jspService(HttpServletRequest request,HttpServletResponse response) // JSPService
  1. 判断请求
  2. 内置了一些对象
    final javax.servlet.jsp.PageContext pageContext; // 页面 上下文javax.servlet.http.HttpSession session = null; // sessionfinal javax.servlet.ServletContext application; // applicationContextfinal javax.servlet.ServletConfig config;  //configjavax.servlet.jsp.JspWriter out = null; // outfinal java.lang.Object page = this;  // page  当前页HttpServletRequest request  //请求HttpServletResponse response //响应
  1. 输出页面前增加的代码
      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;
  1. 以上的这些对象可以在jsp页面中直接使用

在JSP页面中,只要是Java代码就会原封不动地输出,只要是HTML代码就会被转换为

out.write("<html>\n");

这样的格式,输出到前端

8.3 JSP基础语法

需要的依赖

<dependencies>
<!--        servlet 依赖--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency>
<!--        JSP依赖--><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</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作为java技术的一种应用,拥有一些自己的扩充语法(了解,知道即可

JSP表达式
<%= 变量或者表达式%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%--JSP表达式
用来将程序的输出,输出到客户端
--%>
<%= new java.util.Date()%>
</body>
</html>

JSP脚本片段
<% java代码 %>

<%int sum = 0;for (int i = 1; i <=100 ; i++) {sum+=i;}out.print("<h1>sum="+sum+"</h1>");%>
<%--  在代码中嵌入html语句--%>
<%for (int i = 0; i < 10; i++) {
%><h1>Hello JSP <%= i%></h1>
<%}
%>

JSP声明
<%! %>

<%!static {System.out.println("JSP");}private int num = 0;
%>

JSP声明:会被编译到JSP生成的Java类中,其他的会被生成到jsp_Service方法中

<%%>
<%=%>
<%!%>
<%--JSP注释--%>

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

8.4 JSP指令

page指令
定制错误页面
1.在可能发生错误的jsp头部添加以下语句

<%@ page errorPage="./error/500.jsp" %>

2.修改web.xml文件,添加以下语句

 <error-page><error-code>404</error-code><location>/error/404.jsp</location></error-page><error-page><error-code>500</error-code><location>/error/500.jsp</location></error-page>

include指令

<%--  @include会将三个页面合成一个--%><%@include file="common/header.jsp"%><h1>这里是主体</h1><%@include file="common/footer.jsp"%><%--          jsp标签jsp:include会拼接页面,本质还是三个
--%><jsp:include page="common/header.jsp"/><h1>这里是主体</h1><jsp:include page="common/footer.jsp"/>

8.5 内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application 存东西
  • config
  • out
  • page
<%--内置对象--%>
<%pageContext.setAttribute("name1","张三");  //保存的数据只在一个页面中有效request.setAttribute("name2","李四");  //保存的数据只在一次请求中有效,请求转发会携带这个数据session.setAttribute("name3","王五");  //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器application.setAttribute("name4","陈一"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%// 一般是对象取值 pageContext用pageContext取,request用request取....// 从底层到高层(作用域):page->request->session->applicationString 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表达式取值--%>
取得值为:
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>  <%--el表达式自动过滤空值--%>
<h3><%=name5%></h3>   <%--显示为null--%>

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

需要导包

<!--        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标签

<jsp:include page=""></jsp:include>
页面转发
<jsp:forward page="/index.jsp"></jsp:forward><jsp:forward page="/JSPTag1.jsp"><jsp:param name="username" value="zhangsan"/><jsp:param name="password" value="123"/>
</jsp:forward>另一个页面取
用户名:<%=request.getParameter("username")%>
密码:<%=request.getParameter("password")%>

JSTL表达式
JSTL标签库就是为了弥补HTML标签的不足,自定义了许多标签,标签功能与java代码一样
核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:

<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

JSTL标签库使用步骤:
1.引用对应的taglib
2.使用其中的方法
3.在Tomcat中也需要引入jstl和standard的包,否则会报错

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<form action="JSTL.jsp" >
<%--EL表达式获取表单中的数据${param.参数名}
--%>用户名:<input type="text" name="username" value="${param.username}"><input type="submit" value="提交">
</form>
<c:if test="${param.username=='admin'}" var="isAdmin"><c:out value="管理员欢迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>   <!--isadmin的值为true或者false-->
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<c:set var="score" value="60"></c:set>
<c:choose><c:when test="${score>=90}">你的成绩为优秀</c:when><c:when test="${score>=80}">你的成绩为良好</c:when><c:when test="${score>=70}">你的成绩为中等</c:when><c:when test="${score>=60}">你的成绩为及格</c:when>
</c:choose>
</body>
</html>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<%ArrayList<String> arrayList = new ArrayList<>();arrayList.add("张三");arrayList.add("李四");arrayList.add("王五");arrayList.add("赵六");arrayList.add("田七");request.setAttribute("people",arrayList);
%><c:forEach var="name" items="${people}"><c:out value="${name}"></c:out><br/>
</c:forEach>
<hr>
<c:forEach  var="name" items="${people}" begin="1" end="3" step="1"><c:out value="${name}"></c:out><br/>
</c:forEach>
</body>
</html>

9. JavaBean

实体类
特定的写法:

  • 必须有一个无参构造
  • 属性私有化
  • 必须有对应的get/set方法

一般与数据库的字段做映射 ORM
ORM 对象关系映射 表->类 字段->属性 行记录->对象

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.hua.pojo.People" %>
<html>
<head><title>Title</title>
</head>
<body><jsp:useBean id="people" class="com.hua.pojo.People" scope="page"></jsp:useBean>
<jsp:setProperty name="people" property="id" value="101"></jsp:setProperty>
<jsp:setProperty name="people" property="name" value="张三"></jsp:setProperty>
<jsp:setProperty name="people" property="age" value="18"></jsp:setProperty>
<jsp:setProperty name="people" property="address" value="济南"></jsp:setProperty>ID:<jsp:getProperty name="people" property="id"/><br/>
姓名:<jsp:getProperty name="people" property="name"/><br/>
年龄:<jsp:getProperty name="people" property="age"/><br/>
地址:<jsp:getProperty name="people" property="address"/><br/>
</body>
</html>

10. MVC三层架构

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

10.1 早期

用户直接访问控制层,控制层可以直接操作数据库
Servlet——>CRUD——>数据库
弊端:程序十分臃肿,不利于维护
Servlet代码:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码…
架构:没有什么是加一层解决不了

10.2 MVC三层架构

Model

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

View

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

Controller(Servlet)

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

例子:登录
登录——>接收用户的登录请求——>处理用户的请求(获取用户的参数,username、password)——>交给业务层处理登录业务(判断密码是否正确)——>Dao层查询用户名和密码是否正确——>数据库

11. Filter过滤器(重点)

用来过滤网站的数据

步骤:
1.导包

 <dependencies><!--        servlet 依赖--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency><!--        JSP依赖--><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</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><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies>

2.实现接口Filter 注意是javax.servlet 下的 重写三个方法

package FilterDemo;import javax.servlet.*;
import java.io.IOException;public class FilterTest implements Filter {//初始化:web服务器启动,就已经初始化了@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("CharacterEncodingFilter初始化");}//chain://1. 过滤器的所有代码,在过滤特定请求(需要在web.xml配置)的时候会执行//2. 必须让过滤器通行@Overridepublic 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服务器关闭的时候,过滤会被销毁@Overridepublic void destroy() {System.out.println("CharacterEncodingFilter已销毁");}
}

3.在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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"><servlet><servlet-name>testDemo</servlet-name><servlet-class>test</servlet-class></servlet><servlet-mapping><servlet-name>testDemo</servlet-name><url-pattern>/Servlet/show</url-pattern></servlet-mapping><servlet><servlet-name>testDemo1</servlet-name><servlet-class>test</servlet-class></servlet><servlet-mapping><servlet-name>testDemo1</servlet-name><url-pattern>/show</url-pattern></servlet-mapping><filter><filter-name>Filter</filter-name><filter-class>FilterDemo.FilterTest</filter-class></filter><filter-mapping><filter-name>Filter</filter-name><url-pattern>/Servlet/*</url-pattern></filter-mapping>
</web-app>

例子:实现登录拦截 用户登录之后才能进入主页,用户注销之后就不能进入主页
Login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<form action="/login" method="post">用户名:<input type="text" name="username"><br/><br/>密码:<input type="password" name="password"><br/><br/><input type="submit" value="提交">
</form>
</body>
</html>

sys文件夹下的Success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
欢迎您:
<%= request.getSession().getAttribute("user_session")%>
<a href="/loginOut" style="text-decoration: none">注销</a>
</body>
</html>

LoginServlet

package Servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取前端请求的参数String username = req.getParameter("username");String password = req.getParameter("password");if(username.equals("admin")){HttpSession session = req.getSession();session.setAttribute("user_session",session.getId());resp.sendRedirect("/sys/Success.jsp");}else{resp.sendRedirect("/Error.jsp");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

LoginOutServlet

package Servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;public class LoginOutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();Object user_session = session.getAttribute("user_session");if(user_session!=null){session.removeAttribute("user_session");resp.sendRedirect("/Login.jsp");}else{resp.sendRedirect("/Login.jsp");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}
}

LoginFilter

package FilterDemo;import com.sun.deploy.net.HttpRequest;
import com.sun.deploy.net.HttpResponse;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;public class LoginFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;HttpSession session = request.getSession();Object user_session = session.getAttribute("user_session");if(user_session==null){response.sendRedirect("/Login.jsp");}chain.doFilter(req,resp);}@Overridepublic void destroy() {}
}

12. 监听器

1.实现一个监听器的接口

package listener;import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;public class OnLineListener implements HttpSessionListener {//创建session监听  一旦创建一个session就会触发这个事件@Overridepublic void sessionCreated(HttpSessionEvent se) {ServletContext sc = se.getSession().getServletContext();Integer olineCount = (Integer) sc.getAttribute("count");if(olineCount==null){olineCount =new Integer(1);}else{olineCount =new Integer(olineCount+1);}sc.setAttribute("count",olineCount);}// 销毁session监听,一旦销毁session就会触发一次这个事件@Overridepublic void sessionDestroyed(HttpSessionEvent se) {ServletContext sc = se.getSession().getServletContext();Integer olineCount = (Integer) sc.getAttribute("count");if(olineCount==null){olineCount =new Integer(0);}else{olineCount =new Integer(olineCount-1);}sc.setAttribute("count",olineCount);}
}

2.在web.xml中配置监听器

<listener>    <listener-class>listener.OnLineListener</listener-class>
</listener>

Java Web从入门到实践相关推荐

  1. java web快速入门_Web安全快速入门

    java web快速入门 Web开发人员针对CORS,CSP,HSTS和所有Web安全首字母缩写词的入门知识! (A web developer's primer on CORS, CSP, HSTS ...

  2. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

  3. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

  4. python开发web教学视频_Python快速Web开发入门与实践视频课程

    Python快速Web开发入门与实践欢迎来到KK的<Python快速Web开发入门与实践>捧场!下面请允许我为这套课程做一点介绍. <Python快速Web开发入门与实践>是一 ...

  5. 《Java Web从入门到精通》PDF 百度网盘

    http://www.java1234.com/a/javabook/javaweb/2014/1219/3407.html <Java Web从入门到精通>PDF 下载 <Java ...

  6. Java Web 从入门到精通(明日科技)

    Java Web 从入门到精通(明日科技) 目录结构: 第一章:Java Web 应用开发概述 第二章:html与css网页开发基础 第三章:JavaScript脚本语言 第四章:搭建开发环境 第五章 ...

  7. java web从入门到精通光盘_0基础入门 IT,Web前端、Java、C++和Linux哪种好?

    现在是21世纪,是科学技术大力发展的一个时代,IT行业已经成为现在的一个非常热门的一个行业,许许多多的人都想要往IT方面发展,找IT方面相关的一个工作. 很多想要接触IT行业的初学者伤透了脑筋,我该学 ...

  8. Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

    概述 web 服务器.项目.资源概述 web 服务器:可以被浏览器访问到的服务器 常见的 web 服务器: tomcat:中小型的服务器软件,免费开源,支持 JSP 和 Servlet apache ...

  9. java web 开发入门心得

    从事Java Web开发这一段时间来,对Java 面向对象的思想和MVC开发模式可以说已经熟悉了.我当前参与的项目使用的框架是Spring.SpringMVC.Hibernate.作为刚刚参加工作的入 ...

最新文章

  1. 第二章 数据类型和文件操作
  2. Python DataFrame导出CSV、数据库
  3. php超强后门在任意位置创建文件,php大马:.user.ini文件构成的超强PHP后门
  4. AI、元宇宙技术方兴未艾,软件测试重装上阵
  5. Taglist:Exuberant ctags.......
  6. android代码查找图像,Android平台上利用opencv进行图像的边沿检测
  7. 解决数据倾斜一:RDD执行reduceByKey或则Spark SQL中使用group by语句导致的数据倾斜
  8. 安装mathtype打开word报错 mathtype.Dll cannot be found 解决方式
  9. nfine框架连接oracle,NFine快速开发框架(无后门)
  10. android游戏开发方向初探
  11. 《麦肯锡·卓越工作方法》
  12. SVN迁移IP变更地址修改relocate
  13. (转帖)SpringBoot自定义Starter
  14. linux 在固定网址yum,linux yum介绍
  15. Unity 优化贴图模型
  16. [c++]project reference and link
  17. Python APP自动化测试详解
  18. 2022年连锁酒店行业研究报告
  19. 分账技术赋能农贸市场,重塑交易管理服务效能
  20. JAVA实木商城开发,单品模式

热门文章

  1. 微信小程序import绝对目录问题
  2. 深度学习caffe(4)——caffe配置(GPU)
  3. roslaunch mavros px4.launch fcu_url=xxxx到底做了什么
  4. 02-医院挂号系统源码
  5. Resharper.v7.0.1.Incl.Keymaker-CORE
  6. ChatBot开发思路
  7. 毕业设计-基于微信小程序的词汇学习系统
  8. 江南大学物联网大创项目
  9. 04.极简主义——热情(笔记)
  10. animate.css 官方,Animate中文网