1.tomcat的配置

1.下载

tomcat官网下载

image-20210425192907250

解压到你想要的文件夹

进入\bin文件夹,打开startup.bat

image-20210425193149448

访问http://localhost:8080/

image-20210425193232982

成功看到默认

2.去除乱码

我们看到上面的打印是乱码的

打开\conf\logging.properties

image-20210425193359985

标注的地方修改为GBK即可去除乱码

image-20210425193449206

2.下载maven

maven官网下载

image-20210425193745802

解压

image-20210425193759930

1.配置环境变量

MAVEN_HOME

​ 指向maven的根目录如D:\java_web\apache-maven-3.8.1

M2_HOME

​ 指向maven的根目录下的bin目录如D:\java_web\apache-maven-3.8.1\bin

在Path中增加%MAVEN_HOME%\bin

输入mvn -version

image-20210425194235435

配置完成

2.添加镜像仓库

在conf\settings.xml增加如下配置

image-20210425194341266

1
2
3
4
5
6
7
 <!-- 阿里云中心仓库 -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

3.添加本地仓库

在根目录新建一个maven-repo目录

在conf\settings.xml增加如下配置

image-20210425194504483

3.idea在maven中的操作

项目架构管理工具-maven

Maven: 约定大于配置

有约束不要去违反

Maven会规定你要如何编写我们的代码,必须按照这个规范来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--    在build解决maven资源导出(先了解一下)-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>

1.打开设置

image-20210425195036950

创建新项目

image-20210425195326868

image-20210425195356211

在pom.xml中配置引入jsp的相关jar包

image-20210425195518291

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependencies>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>


</dependencies>

2.配置tomcat

点击右上角

image-20210427104846978

image-20210425195617319

image-20210425195620285

image-20210425195739478

image-20210425195741955

完成

image-20210425195914109

3.手动增加java和resources文件夹

image-20210425200103728

4.Servlet

web.xml

1
2
3
4
5
6
7
8
9
<?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简介

sun公司开发动态web的一门技术

提供一个接口Servlet

实现Servlet的两个类->HttpServlet和GenericServlet

2 Servlet

编写自己的实现Servlet接口类来处理请求信息并返回相应,一般通过继承HttpServlet来重写doGet等方法.

3 Maping问题

​ 可以指定一个,多个,通配符映射路径

指定了固有的映射路径优先级最高,如果找不到就走默认的请求

4 ServletContext对象

  • 共享数据
    • 在这个Servlet中保存的数据,可以在另外一个servlet中拿到
1
2
3
4
5
6
7
8
      ServletContext servletContext = this.getServletContext();
String username = "codelorin";
// 将一个数据保存在Servlet中
servletContext.setAttribute("username", username);

ServletContext servletContext = this.getServletContext();
String username = (String) servletContext.getAttribute("username");
resp.getWriter().print("username" + ":" + username);
  • 获取初始化参数
  • 请求转化
1
2
ServletContext servletContext = this.getServletContext();
servletContext.getRequestDispatcher("/gp").forward(req,resp);
  • properties
1
2
3
4
5
InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

Properties properties = new Properties();
properties.load(resourceAsStream);
String user = properties.getProperty("username");

5 HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建了一个代表请求的HttpServletRequest对象,代表响应一个了一个HttpServletResponse

5.1.简单分类

  • 发送数据的方法
1
2
3
ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

5.2.常见应用

  • 输出消息
  • 下载文件
    • 下载文件的文件名
    • 设置浏览器支持下载的类型
    • 获取下载的输入流
    • 创建缓冲区
    • 获取OutputStream对象
    • 将FileOutputStream流写入buffer缓冲区
    • 使用OutputStream将缓冲区的数据输出到客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//1.获取下载文件的路径
String realPath = "D:\\java\\web-study\\httpres\\src\\main\\resources\\1.jpg";
System.out.println("下载的路径: " + realPath);
//2.下载文件的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3.设置浏览器支持下载的类型
resp.setHeader("Content-disposition", "attachment;filename" + fileName);
//4.获取下载的输入流
FileInputStream fileInputStream = new FileInputStream(realPath);
//5.创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6.获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7.将FileOutputStream流写入buffer缓冲区,输出到客户端
while ((len = fileInputStream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
fileInputStream.close();
out.close();
  • 验证码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setHeader("refresh", "3");

    //创建图片
    BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_BGR);
    //得到图片
    Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();

    //设置图片的背景颜色
    graphics.setColor(Color.WHITE);
    //填充背景颜色
    graphics.fillRect(0, 0, 80, 20);
    //给图片写数据
    graphics.setColor(Color.BLUE);
    graphics.setFont(new Font(null, Font.BOLD, 20));
    graphics.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(bufferedImage, "jpg", 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");
    }
    String s = sb.toString() + num;
    return num;
    }

5.3.实现重定向

1
2
3
4
5
resp.sendRedirect("/image");

//可以分解为以下的代码
resp.setHeader("Location","/image");
resp.setStatus(302);

重定向和转化的区别

相同点

页面会发生跳转

不同点

请求转发的时候,url不会发生变化
重定向时候,url地址栏会发生变化

6 HttpServletRequest

7.cookie和session

  • 保存会话的两种方式

​ cookie

​ 客户端技术(响应,请求)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
req.setCharacterEncoding("utf-8");
//解决乱码
resp.setContentType("text/html;charset=utf-8");

PrintWriter out = resp.getWriter();

//获取cookies
Cookie[] cookies = req.getCookies();

if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
String name = cookie.getName();
if (name.equals("lastLoginTime")) {

long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write("你的最后一次登录时间" + date.toLocaleString());

}


}
} else {
out.write("这是你第一次访问!");
}

Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
resp.addCookie(cookie);

  • session

服务端技术,利用这个技术,可以保存用户的会话信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.codelorin;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;


public class sessionStudy 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("codelorin", 1));

//获取session的id
String id = session.getId();

if (session.isNew()) {
resp.getWriter().write("session创建成功" + id);
return;
}
resp.getWriter().write("session已经在服务器中存在了" + id);

//session创建的时候做了什么事情
Cookie cookie = new Cookie("JSESSIONID", id);
resp.addCookie(cookie);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.codelorin;

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 sessionStudy2 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");

HttpSession session = req.getSession();
Person name = (Person) session.getAttribute("name");
System.out.println(name);
resp.getWriter().write(name.toString());

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}

在web.xml可以设置session过期时间

1
2
3
4
5
6
<session-config>
<!-- 15分钟后过期 -->
<session-timeout>
15
</session-timeout>
</session-config>

5.jsp

1.什么是jsp

Java Server Pages: Java服务端页面,也和Servlet一样用于动态web.

2.最大的特点

  • 写JSP就像是在写HTML
  • 区别
    • HTML只给用户提供动态数据
    • JSP页面可以嵌入JAVA代码,为用户提供动态数据

3.JSP原理

JSP到底怎么执行的

  • 代码层没有任何问题
  • 服务器内部工作
  • 页面转变成java程序

本质是就是Servlet

index_jsp=>HttpJspBase=>HttpServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
//初始化
public void _jspInit(){

}
//销毁
public void _jspDestroy(){

}
//JSPService
public void _jspService(){

}

  • 判断请求
  • 内置了一些对象
1
2
3
4
5
6
7
8
PageContext pageContext;			//页面上下文
HttpSession session; //session
ServletContext application; //applicationContext
ServletConfig config; //config
JspWriter out; //out
Object page = this; //page:当前
HttpServletRequest request, //请求
HttpServletResponse response //相应
  • 以上的对象可以直接在JSP中直接使用

在jsp页面中,java代码原封不动输出,

html代码转化为

1
out.write("<html>\r\n")

这样的格式输出到前端!

4.jsp的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<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>

5.基础语法

  • JSP表达式

    用来将程序的输出到客户端

    格式<%= xxx %>

1
<%= new java.util.Date() %>
  • JSP脚本片段

    格式<% xxx %>

1
2
3
4
5
6
7
8
9
10
<%
int x = 10;
out.println(x);

%>
<p>这是一个JSP文档</p>
<%
int y = 0;
out.println(y);
%>
  • 代码中嵌入HTML元素

    格式<% { %> <%}%>

1
2
3
4
5
6
7
<% for (int i = 0; i < 5; i++) { %>
<h1>by codelorin <%= i %></h1>
<%
}
%>


  • jsp声明

    提高作用域,会被编译到jsp生成的java类中.

    其他情况会被编译到_jspServlet方法中

    格式:<%!%>

1
2
3
4
5
6
7
8
9
<%!
static {
System.out.println("Loading Servlet");
}
public void lorin(){
System.out.println("正在执行方法lorin");
}

%>

jsp的注释不会再客户端显示,html会

6.定制错误页面

  • jsp中配置
1
<%@page errorPage="Error/500.jsp" %>
  • web.xml中配置
1
2
3
4
<error-page>
<error-code>500</error-code>
<location>/Error/500.jsp</location>
</error-page>

7.jsp中导包

1
<%@ page import="java.util.Date" %>

8.提取公共页面

  • 变成一个文件
1
<%@include file="Common/header.jsp"%> 
  • 代码引用
1
<jsp:include page="Common/header.jsp"/> 

9.九大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application [ServletContext] 存东西
  • config [Servlet Config]
  • out
  • page
  • exception

简单demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%
pageContext.setAttribute("name","codelorin1");//保存一个页面中有效
request.setAttribute("name1","codelorin2");//一次请求有效,请求转发有效 新闻
session.setAttribute("name2","codelorin3");//保存的数据在一次会话中有效,从打开浏览器到关闭浏览器 购物车
application.setAttribute("name3","codelorin4");//保存的数据在服务器中有效,从打开服务器到关闭服务器 聊天记录
%>
<%
String name = (String) pageContext.findAttribute("name");
String name1 = (String) pageContext.findAttribute("name");
String name2 = (String) pageContext.findAttribute("name");
String name3 = (String) pageContext.findAttribute("name");
%>
//el表达式取出值
<h1>取出的值为:</h1>
<h3>${name}</h3>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>

<h3><%= name %></h3>
1
pageContext.forward("/index")

10.JSP标签,JSTL标签,EL表达式

需要导入包

EL表达式:

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

JSP标签:

1
2
3
4
<jsp:forward page="index.jsp">
<jsp:param name="name" value="codelorin"/>
<jsp:param name="age" value="18"/>
</jsp:forward>
1
2
3
4

<%--取出参数--%>
<%= request.getParameter("name")%>
<%= request.getParameter("age")%>

JSTL标签库

HTML的扩展

核心标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ 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_study.jsp" method="get">
<input type="text" name="username" value="${param.username}" placeholder="请输入用户名">
<input type="submit" value="登录">
</form>
<c:if test="${param.username == 'admin'}" var="isAdmin">
<c:out value="管理员欢迎你!"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ 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="99"/>
<c:choose>
<c:when test="${score>=90}">
你的成绩为优秀
</c:when>
</c:choose>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%@ 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> people = new ArrayList<>();
people.add(0, "lorin");
people.add(1, "zou");
people.add(2, "jjking");
request.setAttribute("list", people);

%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/> <br/>
</c:forEach>
# 遍历变量
<c:forEach var="people" items="${list}" begin="" end="" step=""></c:forEach>
</body>
</html>

11.JavaBean

实体类

JavaBean有特定的写法:

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

一般用来和数据库的字段做映射 ORM;

ORM: 对象关系映射

  • 表->类
  • 字段->属性
  • 行->对象
id name age address
1 lorin1 3 广州
2 lorin2 5 广州
3 lorin3 7 广州
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.codelorin.pojo;

/**
* @author CodeLorin
* @date 2021/5/11 11:21
*/
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 + '\'' +
'}';
}
}


12.MVC三层架构

MVC: Model view Controller 模型 视图 控制器

image-20210519150632641

用户可以直接访问控制层,控制层可以直接操作数据库

servlet->CURD->数据库

弊端:程序十分臃肿,不利于维护

servlet:处理请求响应,跳转,jdbc,业务逻辑代码

image-20210519151034741

Model

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

View

  • 展示数据
  • 提供链接发起请求 a form

Controller

  • 接受用户请求: (req,session)
  • 交给业务层
  • 控制视图跳转

13.Filter

过滤器,用来过滤网站的数据

  • 处理乱码
  • 登录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.codelorin.filter;

import javax.servlet.*;
import java.io.IOException;

/**
* @author CodeLorin
* @date 2021/5/19 15:47
*/
public class Demo implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("开始");
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8");
System.out.println("执行前");
chain.doFilter(req, resp);//拦截放行
System.out.println("执行后");
}

public void destroy() {
System.out.println("结束");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!--    页面-->
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.codelorin.Show</servlet-class>
</servlet>
<!-- 两个url 对比-->
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.codelorin.filter.Demo</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>

14.监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.codelorin.listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
* @author CodeLorin
* @date 2021/6/5 14:07
*/
public class Listener implements HttpSessionListener {

//创建session监听
public void sessionCreated(HttpSessionEvent se) {

System.out.println(se.getSession().getId());
ServletContext ctx = se.getSession().getServletContext();
Integer count = (Integer) ctx.getAttribute("OnlineCount");
if (count == null) {
count = 1;
} else {

count = count + 1;
}
ctx.setAttribute("OnlineCount", count);
}

//销毁session监听
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer count = (Integer) ctx.getAttribute("OnlineCount");
if (count == null) {
count = 0;
} else {

count = count - 1;
}
ctx.setAttribute("OnlineCount", count);
}
}