JSON字符串、Ajax异步请求、拦截器Interceptor详解

1、JSON

1、什么是JSON

JSON(JavaScript Object Notation)JavaScript对象标记。是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据,具有简洁和清晰的层次结构,易于人阅读编写和机器解析生成,提升网络的传输效率。

简单来说。JSON就是一种数据交换格式,JSON在与JS进行数据交互的时候,可以简单的将JSON理解为字符串,将JS对象转换为JSON字符串,方便数据传输,在要使用JS对象的时候再将JSON字符串转换成JS对象

2、JSON对象和JS对象的关系与转换

可以简单的理解为,JSON对象是JS对象的字符串表示,JSON对象使用文本的形式保存JS对象的信息,本质上是一个字符串

JSON对象和JS对象的互相转换

  • JSON对象转JS对象

    JSON.parse("JSON字符串")

  • JS对象转JSON字符串

    JSON.stringify(JS对象)

JS中对象、数组与JSON字符串的转换

  • 表示对象:使用花括号 {},属性以键值对的形式存储
  • 表示数组:使用方括号 []

代码测试

1、新建简单Maven项目,添加web框架支持

2、在web目录下新建json01.html文件,编写测试内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON练习</title>
</head>
<body>

<script type="text/javascript">
    //编写一个js对象,js对象的属性以键值对的形式存储
    let user = {
        name: "张三",
        age: "23",
        sex: "男",
    };

    //将js对象转换成json字符串
    let jsonUser = JSON.stringify(user);
    //将json字符串输出到浏览器控制台
    console.log(jsonUser);


    //将json字符串转换成js对象
    let jsUser = JSON.parse(jsonUser);
    console.log(jsUser);
</script>

</body>
</html>

在浏览器控制台查看运行结果:

在这里插入图片描述

3、Jackson工具

1、导入Jackson依赖(json解析工具包,此外还有fastjson等)

<!--jackson依赖-->
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.1</version>
</dependency>

<!--fastjson依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

2、配置web.xml

注册DispatcherServlet,开启过滤器

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

    <!--1、DispatcherServlet配置,代替servlet-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--上下文路径配置-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--配置启动时间-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--匹配所有的servlet,不包括jsp等静态资源-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--2、过滤器filter配置,处理中文乱码-->
    <filter>
        <filter-name>filetr</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <!--解决中文乱码问题-->
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filetr</filter-name>
        <!--过滤所有的页面-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--3、设置session过期时间-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

</web-app>

3、springmvc-servlet.xml配置

配置注解扫描包、视图解析器

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--自动扫描指定的包,将包下的所有注解类交给IOC容器管理-->
    <context:component-scan base-package="org.westos.controller"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!--拼接完之后就成了:/WEB-INF/jsp/返回值.jsp-->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

4、编写User实体类,使用lombok,要导入lombok的依赖

lombok依赖

<!-- lombok依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>

User实体类

package org.westos.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String name;
    private int age;
    private String sex;

}

5、编写Controller

package org.westos.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.westos.pojo.User;

/**
 * @BelongsProject: ssmIntegration
 * @BelongsPackage: org.westos.controller
 * @Author: 北风
 * @CreateTime: 2020-03-01 18:25
 * @Description: ${Description}
 */
@Controller
public class JsonUserController {

    @RequestMapping("/json1")
    //加上@ResponseBody注解,请求值会返回一个json字符串,而不会被视图解析器解析成页面
    @ResponseBody
    public String json1() throws JsonProcessingException {
        //这里使用的是Jackson的ObjectMapper对象,是JSON解析工具
        ObjectMapper mapper = new ObjectMapper();
        //创建User对象
        User user = new User("张三", 23, "男");
        //使用Jackson工具,将对象转换成JSON字符串
        String strUser = mapper.writeValueAsString(user);
        //返回
        return strUser;
    }
}

配置Tomcat服务器,启动测试,发现虽然字符串过来了,但是有中文乱码

在这里插入图片描述

6、乱码的两种解决方案

1、在@RequestMaping的produces属性设置

@RequestMapping(value = "/json1", produces = "application/json;charset=utf-8")
@ResponseBody
public String json1() throws JsonProcessingException {
    //这里使用的是Jackson的ObjectMapper对象,是JSON解析工具
    ObjectMapper mapper = new ObjectMapper();
    //创建User对象
    User user = new User("张三", 23, "男");
    //使用Jackson工具,将对象转换成JSON字符串
    String strUser = mapper.writeValueAsString(user);
    //返回
    return strUser;
}

启动服务器,发现乱码问题解决了,但是这种方法太麻烦了,每个方法上面都要进行配置,我们推荐使用第二种

在这里插入图片描述

2、在springmvc配置文件上添加StringHttpMessageConverter配置

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

去掉方法1中@RequestMaping注解的produces属性设置,启动服务器,发现依然没有乱码

4、测试集合输出

1、将Controller类上的注解更换为@RestController,这样子该类里面的请求值会返回json字符串。新增方法,测试输出集合

@RequestMapping("/json2")
public String json2() throws JsonProcessingException {
    //使用Jackson的对象映射器,用来解析数据
    ObjectMapper mapper = new ObjectMapper();
    //创建User对象
    User user1 = new User("张三1", 23, "男");
    User user2 = new User("张三2", 23, "男");
    User user3 = new User("张三3", 23, "男");
    User user4 = new User("张三4", 23, "男");
    //创建List集合,将User对象放进集合里
    List<User> list = new ArrayList<User>();
    list.add(user1);
    list.add(user2);
    list.add(user3);
    list.add(user4);
    //使用Jackson工具,将对象解析成JSON字符串
    String jsonList = mapper.writeValueAsString(list);
    //返回
    return jsonList;
}

开启服务器,发现没有问题

在这里插入图片描述

2、输出时间对象

增加新的方法

@RequestMapping("/json3")
public String json3() throws JsonProcessingException {
    //创建一个JSON解析工具对象
    ObjectMapper mapper = new ObjectMapper();
    //创建一个日期对象
    Date date = new Date();
    //将时间对象解析成为json格式,默认是时间戳的格式
    String str = mapper.writeValueAsString(date);
    return str;
}

运行结果发现是时间戳的格式(1970年1月1日到现在的毫秒数)

在这里插入图片描述

更改代码,设置自定义的日期格式

public String json4() throws JsonProcessingException {
    //创建一个JSON解析工具对象
    ObjectMapper mapper = new ObjectMapper();
    //不使用时间戳格式
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    //自定义日期格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //将自定义日期格式设置进JSON解析工具中
    mapper.setDateFormat(sdf);
    //创建日期对象
    Date date = new Date();
    //转换为JSON字符串
    String str = mapper.writeValueAsString(date);
    return str;
}

在这里插入图片描述

5、fastjson工具

fastjson是阿里巴巴开发的一款针对Java开发的工具包,可以实现json对象和JavaBean对象的转换、JavaBean对象和JSON字符串的转换、JSON对象和JSON字符串间的转换。

fastjsonMaven依赖

<!--fastjson依赖-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

fastjson三个主要的类

  • JSONObject

    代表json对象,可以使用get方法拿到JSON对象中的数据,

    实现了Map接口,本质是调用Map接口的中的方法实现的

  • JSONArray

    代表json对象数组

    实现了List接口,内部由List接口的方法实现

  • JSON

    实现JSONObject和JSONArray之间的转换

编写测试类

package org.westos.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.westos.pojo.User;
import java.util.ArrayList;
import java.util.List;


public class FastJsonDemo {
    public static void main(String[] args) {
        //创建List集合
        User user1 = new User("秦疆1号", 3, "男");
        User user2 = new User("秦疆2号", 3, "男");
        User user3 = new User("秦疆3号", 3, "男");
        User user4 = new User("秦疆4号", 3, "男");
        List<User> list = new ArrayList<User>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);

        //将Java对象转换为JSON字符串
        String str1 = JSON.toJSONString(list);
        System.out.println("Java对象转换为JSON字符串,JSON.toJSONString(list):" + str1);
        String str2 = JSON.toJSONString(user1);
        System.out.println("Java对象转换为JSON字符串,JSON.toJSONString(user1):" + str2 + "\n");

        //将JSON字符串转换成Java对象
        User jp_user1 = JSON.parseObject(str2, User.class);
        System.out.println("JSON字符串转换成Java对象,JSON.parseObject(str2,User.class):" + jp_user1 + "\n");

        //将Java对象转换为JSON对象
        JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
        System.out.println("Java对象转换为JSON对象,(JSONObject) JSON.toJSON(user2):" + jsonObject1.getString("name") + "\n");

        //将JSON对象转换为Java对象
        User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
        System.out.println("JSON对象转换为Java对象,JSON.toJavaObject(jsonObject1, User.class):" + to_java_user + "\n");
    }
}
方法作用
JSON.toJSONString(user1)将Java对象转换为json字符串
JSON.parseObject(str2, User.class)将json字符串解析为Java对象
JSON.toJSON(user2)将Java对象转换为json对象
JSON.toJavaObject(jsonObject1, User.class)将json对象转换为js=ava对象

2、Ajax

1、什么是Ajax

Ajax(Asynchronous Javascript And XML),异步的JavaScript和XML,指创建交互式的、快速动态网页应用的网页开发技术,在无需加载整个网页的情况下,部分更新网页的技术。

通过后台和服务器的少量数据交换,Ajax可以实现网页的异步更新(一部分更新,一部分不更新),增加用户体验

传统网页想要更新内容或提交表单,就要重新加载整个网页,但是使用Ajax可以与后台服务器进行少量的数据交互,实现异步局部更新。

使用iframe标签,模拟ajax异步更新

编写ajax-frame.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>ajax-frame</title>
</head>
<body>

<script type="text/javascript">
    window.onload = function(){
        let myDate = new Date();
        //得到id=currentTime的元素,将当前的时间戳作为文本追加上去
        document.getElementById('currentTime').innerText = myDate.getTime();
    };

    function LoadPage(){
        //根据id得到text文本框内的值
        let targetUrl =  document.getElementById('url').value;
        console.log(targetUrl);
        //根据id得到iframe元素,并设置该元素的src属性等于text文本框内的URL
        document.getElementById("iframePosition").src = targetUrl;
    }

</script>

<div>
    <p>请输入要加载的地址:<span id="currentTime"></span></p>
    <p>
        <input id="url" type="text" value="https://www.baidu.com/"/>
        <!--当点击提交按钮的时候,触发LoadPage方法-->
        <input type="button" value="提交" onclick="LoadPage()">
    </p>
</div>

<div>
    <h3>加载页面位置:</h3>
    <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div>

</body>
</html>

运行结果,可以看到,当点击提交按钮,只有iframe元素内的页面刷新了,而其他的,例如时间戳等都为发生变化,未刷新

在这里插入图片描述

利用AJAX可以做:

  • 注册时,输入用户名自动检测用户是否已经存在。
  • 登陆时,提示用户名密码错误
  • 在搜索框搜索时,实时显示可能的搜索结果
  • 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。
  • …等等

2、jQuery.Ajax

Ajax的核心是XMLHttpRequest对象(xhr),xhr为向服务器发送请求和解析服务器响应提供了接口,能够以异步的方式从服务器中获取新数据

jQuery提供了对各与Ajax相关的方法,便于使用。利用jQuery提供的方法,可以使用get/post方法从服务器中请求文本、HTML文件、XML文件或JSON数据等,同时也可以将这些数据直接载入网页元素中

jQuery Ajax的本质就是XMLHttpRequest,对xhr进行了封装,方便调用

jQuery ajax的部分参数

参数含义
url请求地址
type请求方式(get/post)
headers请求头
data要发送的数据
contentType发送给服务器的内容的编码类型,默认为utf-8
async是否异步
timeout设置请求的超时时间
beforeSend发送请求前的执行函数(全局)
complete完成之后执行的回调函数(全局)
success执行成功后的回调函数
error执行失败后的回调函数
accepts通过请求头发送给服务器,告诉服务器当前客户端可以接收的数据类型
dataType将服务器返回的数据转换成指定的数据类型
“xml”将服务器返回的数据转换成xml格式
“text”将服务器返回的数据转换成普通文本格式
“html”将服务器返回的数据转换成普通文本格式,在插入DOM的时候,如果包含JavaScript标签,则会尝试执行
“script”c尝试将返回值作为JavaScript去执行,再将服务器端返回的内容转换称普通文本格式
“json”将服务器返回的数据转换成JavaScript对象
“jsonp”JSONP 格式使用 JSONP 形式调用函数时,如 “myurl?callback=?” jQuery 将自动替换 ? 为正确的函数名,以执行回调函数

3、使用原生的HttpServletResponse处理异步请求

1、配置web.xml和springmvc配置文件

使用上面JSON中的即可

2、编写AjaxController

package org.westos.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.westos.pojo.User;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
public class AjaxController {

    @RequestMapping("/a1")
    public void ajax1(String name , HttpServletResponse response) throws IOException {
        //判断前端传递的参数name的值是否为admin,然后将判断结果响应回去
        if ("admin".equals(name)){
            response.getWriter().print("true");
        }else{
            response.getWriter().print("false");
        }
    }
}

3、编写jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax</title>
    <%--使用百度的jQuery--%>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <script>
        function a1() {
            $.postMessage({
                //提交到a1请求路径下,交由控制器处理
                url: "${pageContext.request.contextPath}/a1",
                data: {'name': $("txtName").value()},
                //得到控制器的参数,弹窗显示
                success: function (data, status) {
                    alert(data);
                    alert(status);
                }
            });
        }
    </script>
</head>
<body>

<%--单击触发事件,调用a1方法--%>
用户名:<input type="text" id="txtName" οnclick="a1()"/>

</body>
</html>

4、使用springmvc实现

1、创建实体类User

package org.westos.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String name;
    private int age;
    private String sex;
}

2、获取一个集合对象,展示到前端页面

@RequestMapping("/a2")
public List<User> ajax2() {
    List<User> list = new ArrayList<User>();
    list.add(new User("张三1", 23, "男"));
    list.add(new User("张三2", 23, "男"));
    list.add(new User("张三3", 23, "男"));
    //将list集合转换为json字符串返回
    return list;
}

3、前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<input type="button" id="btn" value="获取数据"/>
<table width="80%" align="center">
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
    </tr>
    <tbody id="content">
    </tbody>
</table>

<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>

    $(function () {
        $("#btn").click(function () {
            //交由a2请求路径处理
            $.post("${pageContext.request.contextPath}/a2", function (data) {
                console.log(data)
                let html = "";
                //遍历得到date中的数据,并填充到HTMLDOM元素中
                for (let i = 0; i < data.length; i++) {
                    html += "<tr>" +
                        "<td>" + data[i].name + "</td>" +
                        "<td>" + data[i].age + "</td>" +
                        "<td>" + data[i].sex + "</td>" +
                        "</tr>"
                }
                $("#content").html(html);
            });
        })
    })
</script>
</body>
</html>

执行结果

在这里插入图片描述

当点击获取数据后,自动从后台刷新数据

在这里插入图片描述

5、注册提示效果

1、编写Controller

@RequestMapping("/a3")
public String ajax3(String name, String pwd) {
    String msg = "";
    //模拟数据库中数据,判断用户名是否为admin
    if (name != null) {
        if ("admin".equals(name)) {
            msg = "OK";
        } else {
            msg = "用户名输入错误";
        }
    }
    //判断登陆密码是否为123456
    if (pwd != null) {
        if ("123456".equals(pwd)) {
            msg = "OK";
        } else {
            msg = "密码输入有误";
        }
    }
    //返回json数据
    return msg;
}

2、前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax</title>
    <%--使用百度的jQuery--%>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>

        function a1() {
            $.post({
                url: "${pageContext.request.contextPath}/a3",
                data: {'name': $("#name").val()},
                success: function (data) {
                    if (data.toString() == 'OK') {
                        $("#userInfo").css("color", "green");
                    } else {
                        $("#userInfo").css("color", "red");
                    }
                    $("#userInfo").html(data);
                }
            });
        }

        function a2() {
            $.post({
                url: "${pageContext.request.contextPath}/a3",
                data: {'pwd': $("#pwd").val()},
                success: function (data) {
                    if (data.toString() == 'OK') {
                        $("#pwdInfo").css("color", "green");
                    } else {
                        $("#pwdInfo").css("color", "red");
                    }
                    $("#pwdInfo").html(data);
                }
            });
        }

    </script>
</head>
<body>
<p>
    用户名:<input type="text" id="name" οnblur="a1()"/>
    <span id="userInfo"></span>
</p>
<p>
    密码:<input type="text" id="pwd" οnblur="a2()"/>
    <span id="pwdInfo"></span>
</p>
</body>
</html>

3、获取百度的接口案例

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>JSONP百度搜索</title>
    <style>
        #q{
            width: 500px;
            height: 30px;
            border:1px solid #ddd;
            line-height: 30px;
            display: block;
            margin: 0 auto;
            padding: 0 10px;
            font-size: 14px;
        }
        #ul{
            width: 520px;
            list-style: none;
            margin: 0 auto;
            padding: 0;
            border:1px solid #ddd;
            margin-top: -1px;
            display: none;
        }
        #ul li{
            line-height: 30px;
            padding: 0 10px;
        }
        #ul li:hover{
            background-color: #f60;
            color: #fff;
        }
    </style>
    <script>

        // 2.步骤二
        // 定义demo函数 (分析接口、数据)
        function demo(data){
            var Ul = document.getElementById('ul');
            var html = '';
            // 如果搜索数据存在 把内容添加进去
            if (data.s.length) {
                // 隐藏掉的ul显示出来
                Ul.style.display = 'block';
                // 搜索到的数据循环追加到li里
                for(var i = 0;i<data.s.length;i++){
                    html += '<li>'+data.s[i]+'</li>';
                }
                // 循环的li写入ul
                Ul.innerHTML = html;
            }
        }

        // 1.步骤一
        window.onload = function(){
            // 获取输入框和ul
            var Q = document.getElementById('q');
            var Ul = document.getElementById('ul');

            // 事件鼠标抬起时候
            Q.onkeyup = function(){
                // 如果输入框不等于空
                if (this.value != '') {
                    //SONPz重点
                    // 创建标签
                    var script = document.createElement('script');
                    //给定要跨域的地址 赋值给src
                    //这里是要请求的跨域的地址 我写的是百度搜索的跨域地址
                    script.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+this.value+'&cb=demo';
                    // 将组合好的带src的script标签追加到body里
                    document.body.appendChild(script);
                }
            }
        }
    </script>
</head>

<body>
<input type="text" id="q" />
<ul id="ul">

</ul>
</body>
</html>

3、拦截器

拦截器:springmvc中的

  • 和过滤器类似,用来拦截资源的,但是拦截器值会拦截Controller中的方法,不会拦截请求html/jsp/image等资源的
  • 有两种状态,拦截或放行(flase/true)
  • 定义拦截器:实现Interceptor接口的类
  • 只有springmvc框架的工程才可以使用

1、编写拦截器

1、编写拦截器

package org.westos.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    //在所有的请求之前执行,最常用
    //返回false表示不放行
    //返货true表示放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle方法");
        return true;
    }

    //在请求执行之后要进行的操作
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法");
    }

    //在整个DispatcherServlet执行完毕之后要进行的收尾工作
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion方法");
    }
}

2、在springmvc配置文件中配置

<!--拦截器配置-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--
        path是拦截器要拦截请求的路径
        /表示是所有的路径
        **表示是该路径下的所有请求
        /**表示所有路径下的所有请求
        -->
        <mvc:mapping path="/**"/>
        <bean class="org.westos.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3、编写Controller,接收请求

package org.westos.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class InterceptorController {

    @RequestMapping("/test1")
    public String test1(Model model) {
        System.out.println("test方法");
        model.addAttribute("msg", "hello,interceptor");
        return "hello";
    }
}

运行结果,可以看到,先是preHandle方法执行了,在此方法里面进行一些判断,决定是否放行;然后是Controller请求中的方法体,接下来是postHandle方法,最后由afterCompletion方法进行收尾工作

在这里插入图片描述

2、验证用户是否登录小案例

要求

  • 登陆页面,提交表单,如果账号密码正确就跳转到主页
  • 登录成功之后可以在主页看到自己的信息,首页还有一个注销按钮,点击注销按钮可以清空用户数据,然后跳转到登录界面
  • 在登录页面还有一个成功按钮,如果用户已经登陆过了,就跳转到主页,如果没登录或注销了,就跳转到登陆界面

1、登陆界面,login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>

<body>
<form action="${pageContext.request.contextPath}/user/login">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

2、Controller处理请求

package org.westos.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class InterceptorController {

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "login";
    }

    @RequestMapping("/login")
    public String login(String username, String password, HttpSession session) {
        //向session中记录用户的信息
        session.setAttribute("name", username);
        return "success";
    }

    @RequestMapping("/toSuccess")
    public String test3() {
        return "success";
    }

    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        //注销掉用户的session
        session.invalidate();
        return "login";
    }
}

3、编写登录成功页面,success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>

<h1>登录成功!</h1>
<br>
<h1>欢迎你:${name}</h1>

<a href="${pageContext.request.contextPath}/user/logout">注销</a>

</body>
</html>

4、编写首页,firstPage.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>

<a href="${pageContext.request.contextPath}/user/toLogin">登录</a>
<a href="${pageContext.request.contextPath}/user/toSuccess">成功</a>

</body>
</html>

此时我们启动服务器,发现不管用户有没有,都可以直接进入success.jsp页面,这是不对的,所以我们在自定义的拦截器中进行设置

5、编写拦截器

package org.westos.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class MyInterceptor implements HandlerInterceptor {
    //在所有的请求之前执行
    //返回false表示不放行
    //返货true表示放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果是登录请求,就放行
        if (request.getRequestURI().contains("login")) {
            return true;
        }
        //获得session
        HttpSession session = request.getSession();
        //如果用户已经登陆了,放行
        if (session.getAttribute("user") != null) {
            return true;
        }
        //用户没有登录就跳转到登录界面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }
}

启动服务器,现在发现就没有问题了,只有登录了才能进success.jsp页面。当没有登陆或注销登录时,都是进入登录页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值