【SpringMVC笔记,大厂Java高级面试题汇总解答

===================================================================================

SpringMVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行 预处理 和 后处理。开发者可以自己定义一些拦截器来实现特定的功能。

过滤器与拦截器的区别:拦截器是 AOP 思想的具体应用。

过滤器(filter):

  • servlet 规范中的一部分,任何 java web 工程都可以使用;

  • <url-pattern> 中配置了 /* 之后,可以对所有要访问的资源进行拦截;

拦截器(interceptor):

  • 拦截器属于 SpringMVC 框架的,只有使用了 SpringMVC 框架的工程才能使用;

  • 拦截器只会拦截访问的控制器方法, 如果访问的是 jsp/html/css/image/js 是不会进行拦截的;

自定义拦截器


想要自定义拦截器,必须实现 HandlerInterceptor 接口。

  1. 配置 web.xml 和 springmvc-servlet.xml 文件

  2. 编写一个拦截器:


package com.yusael.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 {

    // 在请求处理的方法之前执行

    // 如果返回 true 执行下一个拦截器(放行)

    // 如果返回 false 就不执行下一个拦截器

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("---------处理前---------");

        return true;

    }



    // 在请求处理方法执行之后执行

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("---------处理后---------");

    }



    // 在 dispatcherServlet 处理后执行, 做清理工作

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("---------清理---------");

    }



} 

  1. 在 SpringMVC 的配置文件中配置拦截器:

<!--关于拦截器的配置-->

<mvc:interceptors>

    <mvc:interceptor>

        <!--/** 包括路径及其子路径-->

        <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->

        <!--/admin/** 拦截的是/admin/下的所有-->

        <mvc:mapping path="/**"/>

        <!--bean配置的就是拦截器-->

        <bean class="com.yusael.interceptor.MyInterceptor"/>

    </mvc:interceptor>

</mvc:interceptors> 

  1. 编写一个 Controller,接收请求:

package com.yusael.controller;



import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;



// 测试拦截器的控制器

@RestController

public class InterceptorController {



    @RequestMapping("/interceptor")

    public String testFunction() {

        System.out.println("控制器中的方法执行了!");

        return "hello";

    }



} 

  1. 前端 index.jsp

<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a> 

  1. 启动 Tomcat 进行测试。

如果自定义拦截器中 preHandle 返回 false,表示不放行,被拦截了,不继续执行了。在这里插入图片描述

如果自定义拦截器中 preHandle 返回 true,表示放行,继续执行后面的代码。

在这里插入图片描述

验证用户是否登录 (认证用户)

==================================================================================

思路:

  1. 有一个登陆页面,需要写一个 Controller 访问页面。

  2. 登陆页面有一个提交表单的动作,需要在 Controller 中处理;

    判断用户名密码是否正确:如果正确,向 session 中写入用户信息,返回登陆成功。

  3. 拦截用户请求,判断用户是否登陆。

    如果用户已经登陆,放行;

    如果用户未登陆,跳转到登陆页面;

没有拦截器


如果没有拦截器,也就是上面思路中的 1 和 2 步,用户未登录也可以进入主页

  1. 编写一个登陆页面 login.jsp

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

<html>

<head>

    <title>login</title>

</head>



<h1>登录页面</h1>

<hr>



<body>

<form action="${pageContext.request.contextPath}/user/login">

    用户名:<input type="text" name="username"> <br>

    密码:<input type="password" name="pwd"> <br>

    <input type="submit" value="提交">

</form>

</body>

</html> 

  1. 编写一个 Controller 处理请求

package com.yusael.controller;



import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;



import javax.servlet.http.HttpSession;



@Controller

@RequestMapping("/user")

public class UserController {



    // 跳转到登录界面

    @RequestMapping("/toLogin")

    public String toLogin() {

        return "login";

    }



    // 跳转到成功页面

    @RequestMapping("/toSuccess")

    public String toSucess() {

        return "success";

    }



    // 登录提交

    @RequestMapping("/login")

    public String login(HttpSession session, String username, String password) {

        // 向 session 记录用户身份信息

        System.out.println("接收前端 ===> " + username);

        session.setAttribute("user", username);

        return "success";

    }



    // 登录过期

    @RequestMapping("/logout")

    public String logout(HttpSession httpSession) {

        // session 过期

        httpSession.invalidate();

        return "login";

    }



} 

  1. 编写一个登陆成功的页面 success.jsp

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

<html>

<head>

    <title>success</title>

</head>

<body>



<h1>登录成功页面</h1>

<hr>



${user}

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

</body>

</html> 

  1. 编写主页 index.jsp

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

<html>

<head>

    <title>index</title>

</head>

<body>

<h1>首页</h1>

<hr>

<%--登录--%>

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

<a href="${pageContext.request.contextPath}/user/toSuccess">成功页面</a>

</body>

</html> 

测试:

在这里插入图片描述

点击 登录,会请求跳转到 登陆页面 login.jsp;

点击 成功页面,会请求跳转到 成功页面 success.jsp

这里就出现问题了,只要在 地址栏发出请求,可以直接 越过登录,进入登录成功的界面,这个肯定是有问题的。那要如何解决这个问题呢? —— 通过 拦截器

配置拦截器


  1. 编写用户登录拦截器 LoginInterceptor.java

package com.yusael.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 LoginInterceptor implements HandlerInterceptor {

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 如果是登录页面则放行

        System.out.println(request.getRequestURI());

        if (request.getRequestURI().contains("login")) {

            return true;

        }



        HttpSession session = request.getSession();

        // 如果用户已经登录也放行

        if (session.getAttribute("user") != null) {

            return true;

        }



        // 如果用户没有登录则跳转到登录界面

        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);

        return false;

    }



    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {



    }



    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {



    }

} 

  1. 在 Springmvc 的配置文件中注册拦截器:

<!--关于拦截器的配置-->

<mvc:interceptors>

    <mvc:interceptor>

        <mvc:mapping path="/**"/>

        <bean id="loginInterceptor" class="com.yusael.interceptor.LoginInterceptor"/>

    </mvc:interceptor>

</mvc:interceptors> 

测试:

在这里插入图片描述

由于配置了 拦截器,直接登录 成功页面,虽然会请求跳转到 success.jsp 页面,但是由于不满足拦截器进行了判断,不满足放行的条件则会跳转到 登录界面。只有满足拦截器放行的条件才会跳转到 成功页面。

文件的上传

========================================================================

文件上传是项目开发中最常见的功能之一 ,SpringMVC 可以很好的支持文件上传,但是 SpringMVC 上下文中默认没有装配 MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring 的文件上传功能,则需要在上下文中配置 MultipartResolver

对前端表单的要求:为了能上传文件,必须将表单的 method 设置为 POST,并将 enctype 设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

表单中的 enctype (编码方式)属性的说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。

  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。

  • text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。


<form action="" enctype="multipart/form-data" method="post">

   <input type="file" name="file"/>

   <input type="submit">

</form> 

一旦设置了 enctypemultipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的 HTTP 响应。

在2003年,Apache Software Foundation 发布了开源的 Commons FileUpload 组件,其很快成为Servlet/JSP 程序员上传文件的最佳选择。

Servlet3.0 规范已经提供方法来处理文件上传,但这种上传需要在 Servlet 中完成;而Spring MVC则提供了更简单的封装;

Spring MVC 为文件上传提供了直接的支持,这种支持是用即插即用的 MultipartResolver 实现的。

Spring MVC 使用 Apache Commons FileUpload 技术实现了一个 MultipartResolver 实现类:

CommonsMultipartResolver。因此,SpringMVC 的文件上传还需要依赖 Apache Commons FileUpload 的组件。

文件输出流进行文件上传


  1. 引入 commons-fileupload 的依赖

<!--文件上传-->

<dependency>

   <groupId>commons-fileupload</groupId>

   <artifactId>commons-fileupload</artifactId>

   <version>1.3.3</version>

</dependency>



### 最后分享一波,Java核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的

![image](https://img-blog.csdnimg.cn/img_convert/74967cad038af784dc72bb8d0339e087.png)

![image](https://img-blog.csdnimg.cn/img_convert/a67498a8af7269e2f8e3d0268f8a1953.png)

![image](https://img-blog.csdnimg.cn/img_convert/8fdaf8ab03a2e6100aaa672898dadfdd.png)

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补,不过这份《Java核心架构进阶知识点整理pdf》以及前面P8整理的全套系列大厂面试题皆可免费分享给有需要的你,**[点击这里即可免费领取文中所有资料](https://gitee.com/vip204888/java-p7)**

ndency>

   <groupId>commons-fileupload</groupId>

   <artifactId>commons-fileupload</artifactId>

   <version>1.3.3</version>

</dependency>



### 最后分享一波,Java核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的

[外链图片转存中...(img-s4NnrsPx-1628600392991)]

[外链图片转存中...(img-ePFTpVHk-1628600392994)]

[外链图片转存中...(img-EBnE4isz-1628600392996)]

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补,不过这份《Java核心架构进阶知识点整理pdf》以及前面P8整理的全套系列大厂面试题皆可免费分享给有需要的你,**[点击这里即可免费领取文中所有资料](https://gitee.com/vip204888/java-p7)**

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值