javaEE

JavaEE

概述

Java EE 是在 Java SE 的基础上构建的,它提供Web 服务等,是企业级应用程序版本

能够帮助我们开发和部署可移植、健壮、可伸缩且安全的服务器端Java应用程序

web开发

概述

web开发是指从网页向后端程序发送请求,与后端进行交互。

web服务器

Web服务器是指驻留于因特网上某种类型计算机的程序.

可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界 浏览;

它是一个容器,是一个连接用户与程序之间的中间件

常用的由Tomcat、WebSphere 、 WebLogic、Jboss等

搭建web环境

下载

这里我们使用Tomcat搭建

官网是:tomcat.apache.org

环境

设置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);
    }

}
相关推荐
阿伟*rui44 分钟前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck3 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei3 小时前
java的类加载机制的学习
java·学习
Yaml45 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~5 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616885 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7895 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java6 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~6 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust