JavaEE
概述
Java EE 是在 Java SE 的基础上构建的,它提供Web 服务等,是企业级应用程序版本
能够帮助我们开发和部署可移植、健壮、可伸缩且安全的服务器端Java应用程序
web开发
概述
web开发是指从网页向后端程序发送请求,与后端进行交互。
web服务器
Web服务器是指驻留于因特网上某种类型计算机的程序.
可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界 浏览;
它是一个容器,是一个连接用户与程序之间的中间件
常用的由Tomcat、WebSphere 、 WebLogic、Jboss等
搭建web环境
下载
这里我们使用Tomcat搭建
环境
设置JAVA_HOME环境变量
测试
双击 bin 目录下的 startup.bat 文件
输入http://localhost:端口号、http:127.0.0.1:端口号、局域网ip:端口号
Servlet
概述
Servlet是java用来编写服务器端代码的程序
运行在web服务器中,负责通信和调用方法
作用
1、负责接收前端发送的请求
2、调用Java程序处理请求
3、根据处理结果,对前端做出响应
Servlet创建和使用-Servlet配置
java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
创建servlet时需要继承HttpServlet类
再根据请求重写doget后dopost方法
然后再
在web.xml文件配置资源路径
*/
public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("测试成功");
}
}
Web.xml文件为web应用的配置文件,它必须放在web应用目录WEB-INF目录下。
Web.xml文件用于对web应用下的web资源进行配置,服务器在启动时会读取web.xml文件中的内容
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">
<!--
配置Servlet程序
把开发的Servlet程序注册到服务器,由服务器启动时加载
-->
<servlet>
<!-- 定义对象名 -->
<servlet-name>demo</servlet-name>
<!-- 注册Servlet程序 -->
<servlet-class>com.ffyc.dormServer.web.DemoServlet</servlet-class>
</servlet>
<!--
为Servlet程序配置一个访问地址
-->
<servlet-mapping>
<!-- 为指定name的Servlet程序配置访问地址 -->
<servlet-name>demo</servlet-name>
<!-- 配置以供外部访问的地址 以/开头 -->
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
Servler对象生命周期
创建
在第一次访问Servlet程序时,由服务器创建执行
初始化
init(),在构造方法执行完成后立即调用执行,完成Servlet程序的初始化只执行一次
服务
service() ,接收前端请求,为前端提供服务在每次前端发送请求时,都会被调用一次
销毁
destroy() ,在服务器关闭时,仅调用一次
java
package com.ffyc.dormServer.web;
import javax.servlet.ServletConfig;
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 DemoServlet extends HttpServlet {
/*
创建一个类让它继承HttpServlet
在web.xml文件配置,向外部提供一个访问地址,就可以在浏览器中访问
*/
/*
无参构造方法,默认存在,初始化创建的对象
在第一次访问Servlet程序由服务器创建执行
且只被调用一次
*/
public DemoServlet(){
System.out.println("无参构造");
}
/*
init() 初始化
在构造方法执行完成后立即调用执行,完成Servlet程序的初始化
只执行一次
*/
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init");
}
/*
service() 接收前端请求,为前端提供服务
在每次前端发送请求时,都会被调用一次
HttpServletRequest req:表示请求对象(前端提交过来的所有数据都封装在该对象中)
HttpServletResponse resp:表示响应对象
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service");
}
/*
destroy() 销毁
在服务器关闭时,仅调用一次
*/
@Override
public void destroy() {
System.out.println("destroy");
}
}
作用
接收前端请求数据->调用其他java程序->向前端做出响应
HTTP协议
概述
HTTP 是一种用作获取诸如 HTML 文档这类资源的协议。它是 Web 上进行任何数据交换的基础,同时,也是一种客户端---服务器(client-server)协议,也就是说,请求是由接受方------通常是浏览器------发起的。
http请求
除了上面两种请求外还有http请求,其主要应用于Servlet中
用HttpServletRequest来表示接收到的请求:
在其中封装了请求里的信息,可通过getParameter(name) 获得请求中任何信息--- String 通过name获得值
java
getMethod() //得到客户机请求方式
getScheme() //请求协议
getRemoteAddr() //返回发出请求的客户机的IP地址
getServerName() //服务器名(ip或域名)
getServerPort() //服务器端口
HTTP响应
一个http响应中包括了服务器向客户端回送的数据,并且会对每个客户端请求新建一个HttpServletResponse对象
一个http响应包括了:
请求行
请求方式、资源名称、http版本
请求头
客户的环境信息,这些信息由浏览器自动发送,以键值对形式传输
请求体
以表单post方式向后端发送的请求数据
GET请求和POST请求的区别
get请求:
主要是从后端获取信息,向后端传递少量信息,并获取大量信息 请求数据在请求地址中直接拼接,传输的数据量有限,且敏感数据不安全
post请求:
主要用于向后端发送大量数据 请求数据在请求体中可以穿输大量数据,不会在地址中显示,相对安全
Get请求
java
//接收请求行和请求头数据
System.out.println(req.getMethod());//获得请求方式
System.out.println(req.getProtocol());//获得请求协议
System.out.println(req.getServerName());//获得服务名
System.out.println(req.getServerPort());//获得服务器端口
System.out.println("------------------------------------");
System.out.println(req.getRemoteAddr());//获得客户端ip
System.out.println(req.getRemotePort());//获得客户端端口
//接收请求头数据
System.out.println(req.getHeader("User-Agent"));//获得客户机信息
System.out.println(req.getHeader("Accept-Language"));
Post请求
java
//设置请求解码格式
req.setCharacterEncoding("utf-8");
String account = req.getParameter("account");
String password = req.getParameter("password");
System.out.println(account);
System.out.println(password);
//调用JDBC
//响应
//设置响应解码格式
resp.setHeader("content-type", "text/html;charset=utf-8");//法一
resp.setContentType("text/html;charset=utf-8");//法二
//获得打印字符流
PrintWriter printWriter = resp.getWriter();
printWriter.write("成功");
过滤器
在请求时,有时会编写多次同一代码(即解码格式、响应格式)。所以在请求到达servlet前,先进入到过滤器中进行统一拦截处理,处理完成后再到达目标servlet。若配置了多个过滤器,则进入下一个过滤器。
使用场景
1、统一编码过滤
2、权限验证
3、跨域过滤
...
作用
1、减少代码冗余,提高可维护性
2、一个资源可以配置多个过滤器
3、一个过滤器也可以配置给多个资源
创建
java
import javax.servlet.*;
import java.io.IOException;
/*
创建一个类实现Filter接口
重写doFilter方法
*/
public class EncodFilter implements Filter {
//执行过滤
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器");
}
}
配置过滤器
XML
<!-- 在web.xml中进行配置 -->
<!-- 过滤器 -->
<filter>
<filter-name>过滤器名称</filter-name>
<filter-class>过滤器地址</filter-class>
</filter>
<!-- 配置哪些请求地址可以进入过滤器 -->
<filter-mapping>
<filter-name>过滤器名称</filter-name>
<url-pattern>/资源名称</url-pattern>
<url-pattern>/*</url-pattern><!-- 让所以servlet都进入过滤器 -->
</filter-mapping>
跨域
跨域是指从域名网页去请求另一个域名网页的资源。它是浏览器对javascript施加的完全限制,其严格的定义为:协议、域名、端口任意不同则视为跨域。
作用
跨域的一个重要作用就是保护用户数据安全。
解决
当需要访问其他域名网站的资源,此时就需要跨域。
1、前端:跨域资源共享、node.js中间件...
2、后端:创建过滤器
java
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CorsFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
//允许携带Cookie时不能设置为* 否则前端报错
httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域
httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等
httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie
filterChain.doFilter(servletRequest, servletResponse);
}
}
axios-同步-异步
在先前经常会使用同步请求,但是它会影响下一步操作,现在一般使用异步请求。
html
<script>
function checkAccount(account){
//同步请求 form表单 超链接
//后端请求会覆盖页面
//location.href = "http://127.0.0.1:8088/dormServer/reg?account="+account;
//法一:
//异步请求,使用js
var httpobj = new XMLHttpRequest();
//封装请求地址和数据
httpobj.open("get","http://127.0.0.1:8088/dormServer/reg?account="+account,true);
//发送请求
httpobj.send();
//接收响应
httpobj.onreadystatechange = function(){
document.getElementById("msgid").innerHTML = httpobj.responseText;
}
}
</script>
而原生的异步请求写起来比较麻烦,所以在此引入axios。
axios将请求地址和数据封装一起,符合面向对象的思想,更易理解。
html
<script>
//法二:
function checkAccount(account){
axios.get("http://127.0.0.1:8088/dormServer/reg?account="+account).then((resp)=>{
// console.log(resp);
document.getElementById("msgid").innerHTML = resp.data;
});
}
</script>
特点
-
从浏览器创建XMLHttpRequests
-
从 node.js 创建 http 请求
-
支持 Promise API
-
拦截请求和响应
-
转换请求和响应数据
-
取消请求
-
自动转换JSON数据
-
客户端支持防御XSRF
json
json(javaScript Object Notation)即:javaScript 对象表示法。
是两种不同语言间进行数据交互的一种对象表示方法。
其格式为:{键:值,键:值},集合为:[{键:值,键:值},{键:值,键:值}]
背景
后端向前端响应更多数据,一般将数据封装进对象中,但javaScript 不认识对象。
此时为了让javaScript 方便操作,将java的对象转为json格式的字符串传给前端。
目前json已成为公认的前后端数据交互的标准格式。
配置
XML
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
使用
java
PrintWriter writer = resp.getWriter();
Result result = null;
/*
为result对象进行一系列赋值操作
*/
//,将result对象作为参数向后端做出响应
writer.write(new ObjectMapper().writeValueAsString(result));
//--------------------------------------------------------
ObjectMapper objectMapper = new ObjectMapper();
//将java对象转为json格式的字符串
String jsonstr = objectMapper.writeValueAsString(result);
路由导航守卫
在前端每一次进行路由跳转时,触发监听
java
// 配置路由导航守卫,每当进行一次组件路由时,自动执行
//
rout.beforeEach((to,from,next)=>{
// alert(to.path);
if(to.path=='/login'){ //to.path 访问的路由地址
return next();//继续正常访问目标地址
}else{
var account = sessionStorage.getItem("account");//获取到浏览器中存储的管理员信息
if(account==null){ //如果信息为空,说明没有登录
return next("/login");
}else{//说明已经登录,可以正常访问
return next();
}
}
})
web会话跟踪-Token
会话:每次前端向后端请求,后端做出响应的流程称为一次会话。
由于http请求是无状态的,一次会话结束后。再次请求时,服务器无法得知是那个用户进行访问。
此时就需要进行会话跟踪。使用JWT组件结合用户信息为用户生成安全密钥,即一个token字符串,将其在浏览器储存起来,之后的每次请求都把token加入请求头中发送给服务器进行验证。
XML
<!-- 导入jwtjar包 -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>
Token
Token是服务器生成的一串字符串,以作客户端请求的一个令牌,每当第一次时就会生成一个token,并在发送请求时一并传给服务器,已验证用户。
特点
Token具有时效性,进行了加密,保证了数据的安全性。
并且减轻了服务器的压力,使服务器更健壮
使用
java
package com.xhz.dorm.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xhz.dorm.model.Admin;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* JWT工具类
*/
public class JWTUtil {
/**
* 根据用户id,账号生成token
* @param admin
* @return
*/
public static String getToken(Admin admin) {
String token = "";
try {
//过期时间 为1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
Date expireDate = new Date(new Date().getTime() + 10000*1000);
//秘钥及加密算法
Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
//设置头部信息
Map<String,Object> header = new HashMap<>();
header.put("typ","JWT");
header.put("alg","HS256");
//携带id,账号信息,生成签名
token = JWT.create()
.withHeader(header)//设置第一份信息
.withClaim("id",admin.getId())//设置第二部分 载荷 管理员信息
.withClaim("account",admin.getAccount())
.withExpiresAt(expireDate)//设置token有效时间
.sign(algorithm);//设置密钥
}catch (Exception e){
e.printStackTrace();
return null;
}
return token;
}
/**
* 验证token是否有效
* @param token
* @return
*/
public static boolean verify(String token){
try {
//验签
Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception e) {//当传过来的token如果有问题,抛出异常
return false;
}
}
/**
* 获得token 中playload部分数据,按需使用
* @param token
* @return
*/
public static DecodedJWT getTokenInfo(String token){
return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
}
}