javaEE(2)

一. 过滤器

**作用:**拦截web服务器向后端发送的数据,使请求地址在到达servlet之前进入到指定的过滤器中,可以对数据进行一些统一的处理,比如设置编码,权限控制等

**使用:**创建一个类实现Filter接口,并实现里面的doFilter()方法,过滤器要做的作用主要写在doFilter方法中

java 复制代码
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

这是一个设置编码的过滤器,被配置的会被该过滤器拦截的servlet程序,都会在到达后端前被统一设置为utf-8编码

注意:

  1. 上述案例最后一句代码必须要写,否则程序不会继续向下执行,发出的请求将不会到达后端程序,最后一句表示将信息继续传递给下一个过滤器,如果所有过滤器都被执行,就会传递到后端
  2. 过滤器中除了有抽象方法doFilter,还有两个默认方法init()和destroy()不是必须要实现的,在需要的时候实现即可,不实现默认调父类的,父类的是空的
  3. 但是仅仅只是实现了Filter这个接口并不能使用过滤器,因为过滤器和servlet程序一样需要进行配置,我们需要对他设置哪些servlet程序会被该过滤器拦截,和servlet程序一样,有两种配置方法

1. web.xml文件中配置过滤器

html 复制代码
    <!--
    注册过滤器,告诉服务器有这么一个过滤器
    -->
    <filter>
       <filter-name>coding</filter-name>
       <filter-class>com.ffyc.dormServer.filter.EncodingFilter</filter-class>
    </filter>

    <!--
    配置过滤器,指定哪些servlet程序会被该过滤器拦截
    /* 表示所有servlet程序都会被拦截
    /login 表示地址为/login的servlet程序会被拦截
    -->
    <filter-mapping>
        <filter-name>coding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2. 注解配置过滤器

java 复制代码
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

在类的上面加上@WebFilter注解,服务器会自动的检查该注解里面的信息,就知道该过滤器会拦截哪些servlet程序,urlPatterns表示要拦截的地址,里面还可以有很多属性,比如name表示为该过滤器起一个名字,loadonStartup默认为-1表示在第一次访问时创建servlet对象,如果将其改为0或1表示在服务器启动时就创建该servle对象

二. 同步请求与异步请求

1. 同步请求

**同步:**同时只能做一件事

**同步请求:**当前端向后端发送请求时,此时客户端的一切操作会停止,后端返回来的响应会覆盖当前网页中的内容,一次只能做一件事,与服务器交互时,客户端就不能继续进行操作了,很影响客户体验

1.1 实现同步请求

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js"></script>
		<script>
			function checkAccount(account){
				location.href="http://127.0.0.1:8088/webServer/check?account="+account;
		</script>
	</head>
	<body>
		账号:<input type="text" name="account" onblur="checkAccount(this.value)"/><span id="msg"></span><br/>
		密码:<input type="password">
	</body>
</html>

当我们将输入好账号时,本来应该输入密码,但由于输入完账号,就要像后端发出请求,来验证我这个账号是否已经存在,存在就不能注册,不存在才能注册,但由于是同步请求,输入结束后,该页面就被后端的响应覆盖,导致用户无法继续操作,体验感很差

2. 异步请求

**异步:**同时能做多件事

**异步请求:**当客户端与服务器交互时,不会影响客户端页面的操作,后端发来的响应不会覆盖整个页面

可以同时完成多件事,比如客户端的操作和向后端发送的请求处理

2.1 实现异步请求

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js"></script>
		<script>
			function checkAccount(account){
			   
			   // 1.创建请求对象
			   var httpobj = new XMLHttpRequest();
			   httpobj.open("get","http://127.0.0.1:8088/webServer/check?account="+account); //封装请求
			   httpobj.send(null); //发送请求 */
			   
			   // 2.执行回调函数,接收响应的结果
			      httpobj.onreadystatechange = function(){
				  document.getElementById("msg").innerHTML = httpobj.responseText;
			}
		}
		</script>
	</head>
	<body>
		账号:<input type="text" name="account" onblur="checkAccount(this.value)"/><span id="msg"></span><br/>
		密码:<input type="password">
	</body>
</html>

可以看到当我们填写完账号时,向后端发出检查的请求,后端做出响应后,客户端仍然可以进行操作,且页面内容不会被覆盖

2.2 axios框架实现异步请求

虽然上述方法成功实现了异步请求,但是写法相对麻烦,但却是最本质的,为了便于程序员书写,我们可以用axios框架实现异步请求,axios是一个http的网络请求库

2.2.1 基本的HTML文件中配置axios框架
  1. 首先去官网找文档,下载axios.js文件

http://axios-js.com/

将上述地址复制到浏览器中,右键点击另存为下载到一个能找到的地方,然后打开HBuilder X

将其拖到你创建的普通项目的js文件夹中,然后导入到html文件中,就和之前导入vue普通项目一样

然后按照下面的代码就可以使用框架实现异步请求

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js"></script>
		<script>
			function checkAccount(account){
			
				  axios.get("http://127.0.0.1:8088/webServer/check?account="+account)
				  .then(function(response){
					  document.getElementById("msg").innerHTML = response.data;
					  console.log(response);
				  })
			}
		}
		</script>
	</head>
	<body>
		账号:<input type="text" name="account" onblur="checkAccount(this.value)"/><span id="msg"></span><br/>
		密码:<input type="password">
	</body>
</html>
2.2.2 vue-cli项目中配置axios框架
  1. 打开HBuilder X创建一个vue-cli项目并完成配置,打开终端输入以下指令

    npm install axios

  2. 在main.js中完成以下配置

2.1 导入axios

 import axios from 'axios';

2.2 设置访问后台服务器的地址

html 复制代码
axios.defaults.baseURL="http://127.0.0.1:9999/api/";
<!--
127.0.0.1:9999这是IP和端口,是服务器的IP和端口,需要自己改
/api是访问后台哪个serlet程序的地址,这些在web.xml文件或注解中都配置过
也需要自己改
-->

注意:

127.0.0.1:9999这是IP和端口,是服务器的IP和端口,需要自己改

/api是访问后台哪个serlet程序的地址,这些在web.xml文件或注解中都配置过也需要自己改

2.3 将axios挂载到vue全局对象中,使用this可以直接访问

html 复制代码
Vue.prototype.$http=axios;

这句话的意思是,将axios挂载到全局唯一的vue对象中,并给axios起了一个别名叫http,可以通过this.$http来访问该axios对象

这样就配置完成了,接下来使用get或post方法即可发送对应的请求,then方法中的回调函数会在请求成功或失败时触发,通过回调函数的形参可以获取响应内容,或错误信息

基本语法:

html 复制代码
this.$http.get(地址?Key=value&key2=val1).then(function(response){ }
this.$http.post("login",{key:"value",key2:"val2"}).then(function(response){ }

post请求的写法

get请求也是类似的

三. 跨域问题

前后端在进行异步交互时会出现跨域问题

1. 跨域问题

不同服务器间进行访问,浏览器不允许js接收来自其他服务器响应的数据,只要协议,域名,端口其中一个不同,都属于跨域访问

2.为什么要跨域访问

1.因为一个公司会有很多业务,这些业务部署在不同的服务器中,当某个业务需要与其他业务进行交互时,就会遇到两个不同的服务器之间需要进行访问.

2.现在的项目大部分都是前后端分离的,而往往前端项目部署在一个服务器中,后端项目部署在一个服务器中,这样就能减轻服务器的压力,但是访问时就需要跨域访问了

所以我们必须要允许跨域访问的存在

3.浏览器为什么阻止跨域访问

为了安全,不能让其他服务器中的内容肆意的响应到自己的服务器中

4.如何解决跨域问题

后端:在响应时告诉浏览器允许接收来自某些指定服务响应的内容,加一个过滤器即可

前端:处理方式很多,而且跨域问题本就是前端需要考虑的问题

四. 后端响应标准格式json数据

当我们前端向后端发送一个请求,后端经过处理向前端返回一个响应,但前后端所用的语言不同,换句话说,前端无法正确识别后端返回来的信息,也就无法将其正确的输出到网页中,所以为了统一,作出了一种规定,后端向前端响应的是标准格式的json数据

**json(javaScript Object Notation):**javaScript对象表示法,用于交换解析文本信息的,比以前的web.xml文件更轻量级

有了json我们后端的java程序只要发送一种固定的json数据格式,这样前端就能成功识别并显示

json格式:"{键:值},{键:值}"这样的字符串

当然在后端并不需要我们自己去将结果拼接成一个这样的字符串,而是通过第三方的jar包来实现好的,我们只需要导入相应的依赖到maven中即可

json依赖:

html 复制代码
               <!--json-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.14.2</version>
        </dependency>

我们后端在处理时往往会创建一个Result类该类专门用于返回响应结果,结果包含状态码,响应内容,以及相应的对象数据

java 复制代码
/*
登录处理的servlet程序
 */
@WebServlet(urlPatterns = "/login",name = "login",loadOnStartup = 1)
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求
        String account = req.getParameter("account");
        String password = req.getParameter("password");
        PrintWriter pw = resp.getWriter();
        Result<Admin> result = null;
        //对请求进行处理
        try {
            Admin admin = new LoginDao().login(account, password);
            if(admin!=null){
                result = new Result<>(200,"登录成功",admin);
            }else{
                result = new Result<>(201,"账号或密码错误",null);
            }
        } catch (Exception e) {
            result = new Result<>(500,"系统忙,请稍后再试!",null);
        }
        pw.write(new ObjectMapper().writeValueAsString(result));
    }
}

可以看到这是一个登陆的后端响应程序,我们将与数据库交互的结果放在一个对象中,并将该对象存在一个Result对象中,这样就能返回一个标准的json格式的响应

相关推荐
让学习成为一种生活方式11 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
晨曦_子画17 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
南宫生40 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
Heavydrink1 小时前
HTTP动词与状态码
java
ktkiko111 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
神里大人1 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
小冉在学习2 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
代码之光_19802 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi2 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet