SpringMVC学习笔记

发布于:2025-07-22 ⋅ 阅读:(16) ⋅ 点赞:(0)

        本文章是用来记录自己学习知识时所记录的笔记,并不是对springMVC的完全讲解,用于自己后续复习使用,本文包括后续的文章可能会在基础上不断更新和完善,主要偏向于实际应用的例子。


目录

创建Java项目的5种方式

创建tomcat项目的流程

@RequestMapping的使用

常用注解

异常处理以及自定义异常

SpringMVC 拦截器


创建Java项目的5种方式

1、普通Java项目 2、普通JavaWeb项目 3、maven Java项目 4.maven JavaWeb项目 5、springboot项目

创建tomcat项目的流程

(一)配置项目结构

1.创建web项目

2.打开项目结构->模块->添加一个Web框架

3.项目结构->工件->添加Web应用程序:归档(或者在第二步下面可以直接点击创建工件)

(二)配置Tomcat服务器

1.右上角当前文件-编辑,+ 号,添加本地Tomcat服务器

2.添加好后,右边导航栏第二个部署-添加刚才创建好的工件

3.配置服务器的内容

(三)写代码

1.在web目录下(自动生成的),编写一个index.jsp文件作为首页【至此,已经完成了一个简单的web访问界面】

2.在web目录下创建一个WEB-INF目录,里面再编写一个web.xml文件

web.xml文件的作用:

  1. Servlet 配置
    • 注册和映射 Servlet 类,指定 URL 路径与 Servlet 类的对应关系。如:

    • 所有url以.do结尾都会被拦截,交给controller处理
    • 配置 Servlet 的初始化参数和加载顺序。
  1. 过滤器(Filter)配置
    • 定义请求和响应的预处理 / 后处理逻辑,例如字符编码过滤、权限验证等。
    • 指定过滤器的应用顺序和作用路径。
  1. 监听器(Listener)配置
    • 注册 Web 应用生命周期事件的监听器,例如会话创建 / 销毁、应用启动 / 停止等。
  1. 安全约束
    • 定义受保护的资源路径和访问权限。
    • 配置用户认证方式(如表单认证、HTTP 基本认证)和角色权限。

3.编写从web.xml中配置的springmvc文件

4.从springmvc文件中配置扫包路径以及视图解析器:

5.此时便再写其他业务代码,如controller包。如果需要写界面,需要写在web/WEB-INF下,但这里面的页面资源不可以随意访问(如url访问),必须通过 Servlet 或控制器转发:JSP 需作为服务器端视图被调用,例如通过RequestDispatcher.forward()或 Spring MVC 的ModelAndView。如

返回了suc后,会在视图解析器中拼接上前后缀,然后返回对应的界面。/WEB-INF/pages/suc.jsp

【遇到的问题】

更改web目录后,一共需要变动如下三个地方:

项目结构->模块->新建一个web,改动如下两个地方:

紧接着点击工件,一定要把原来的删除!,然后新建一个,不要在上一步自己生成工件,会有问题,在工件新建一个Web应用程序 -展开型,然后选择原模块,创建好以后,再重新配置下Tomcat中的部署

这样就都完成了


@RequestMapping的使用

RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

RequestMapping注解可以作用在方法和类上

  1. 作用在类上:第一级的访问目录
  2. 作用在方法上:第二级的访问目录
  3. 细节:路径可以不编写 / 表示应用的根目录开始

属性:

path:指定请求路径的url

value:和path一样

param:匹配请求参数的条件

@RequestMapping(params = "id")(必须包含参数id

method:请求方法:GET、POST

如@RequestMapping(method = RequestMethod.POST)


记得在controller代码前一定加上@controller注解,不然无法识别到!

请求参数的绑定:

1.绑定机制

  1. 表单提交的数据都是k-v形式的,如username=hao&password=123
  2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为 controller 中的方法的参数进行绑定的
  3. 要求:提交表单的namecontroller参数的名称是相同的

2.支持的数据类型

  1. 基本数据类型和字符串类型
  2. 实体类型(JavaBean,即自定义的类)
  3. 集合数据类型(List、map集合等)

实体类型(JavaBean):

1.提交表单的name要和JavaBean实体类中属性名称一致(即如果一个User实体类中有name属性,那么提交的表单名称也必须是name)

2.如果一个JavaBean实体类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:address.name

集合数据类型(List、map集合等)

如果集合的属性是实体类,那么编写方式是编写方式:list[0].属性。如list[0].name

代码:

User实体类:

Address实体类:

前端jsp代码:

后端controller代码:

注意,在后端

1,RequestMapping最前面可以加斜线,比如:@RequestMapping("/testPath")

2,RequestMapping最前面可以不加斜线,比如:@RequestMapping(“testPath”)

3,RequestMapping最前面可以加很多斜线,比如:@RequestMapping("///testPath")

因为spring框架都会进行处理,///test///testPath和/test/testPath按斜线分割后都是{“test”,“testPath”}

但如果在前端,/就是可加可不加了

加了 '/' 表示从服务器根路径开始,而不加 '/' 表示从相对路径开始

例如我在tomcat中配置

如果是第一个,会变成绝对路径,从根开始访问,点击提交后跳转到

但是第二个,提交的话,会根据上下文进行拼接:

整体就是这样的区别


关于传输日期:

如果前端传入一个日期字符串,如2025/7/2,那么后端在输出Date形式的时候,会输出如下格式:

如果想要格式化为指定格式的日期,可以在controller中加一层处理

或者可以自定义类型转化器,

一、使用@DateTimeFormat注解

这样前端必须使用yyyy-MM-dd的形式,不然会报错

二、如果想自定义数据类型转换,可以实现Converter的接口

因为spring是组件形式的,因此需要注册使其生效,在springmvc.xml配置文件中编写配置


常用注解

@RequestParam注解

  1. 作用:把url请求中的指定名称的参数传递给控制器中的形参赋值,加在控制器参数前面

  2. 属性

    1. value:请求参数中的名称
    2. required:请求参数中是否必须提供此参数,默认值是true,必须提供

代码如下:

@Controller
public class helloController {
    @RequestMapping("/hello.do")
    public String hello(@RequestParam(value = "username",required = false,defaultValue = "abc")
                            String name){
        System.out.println("SpringMVC! " + name);
        return "suc";
    }
}

当我启动服务,访问对应的url时,第一次我先不加参数,访问如下url:

查看后端输出:此时应该采用的默认值abc,因为没有指定username

当我在请求中加入参数:

再次查看后端输出

@RequestBody注解

1、作用:该注解用于获取请求体中的内容(GET方法不可以!),加在控制器参数前面

2、属性:required:是否必须有请求体,默认值是true

3、代码如下:

@Controller
public class helloController {
    @RequestMapping("/hello.do")
    public String hello(@RequestBody String body){
        System.out.println("Body Content: " + body);
        return "suc";
    }
}

我使用postman进行测试,在Body中加入“test”字符串

后端便成功获取到body的内容了,注意不写body会返回400,如果required=true

@PathVariable注解

1、作用:用于从请求的url路径中提取动态参数,并将其绑定在控制器的方法参数上。

它主要用于处理 RESTful 风格的 URL,通过占位符的形式在 URL 中定义变量,使 URL 更加灵活和语义化。

2、属性:指定url中占位符的名称

3、代码如下:

@Controller
public class helloController {
    @RequestMapping("/hello.do/{id}")
    public String hello(@PathVariable(value="id") Integer id){
        System.out.println("PathVariable: " + id);
        return "suc";
    }
}

 当我访问这个指定url时,可以看到结果输出了2,正如预期

@RequestHeader注解

1、作用:获取指定请求头的值

2、属性:value:请求头的名称

3、代码如下:

@Controller
public class helloController {
    @RequestMapping("/hello.do/{id}")
    public String hello(@RequestHeader(value="Accept") String accept){
        System.out.println("Accept: " + accept);
        return "suc";
    }
}

    @CookieValue注解

    1.用于获取指定Cookie名称的值

    2、属性:value:cookie的名称

    3、代码:

    @Controller
    public class helloController {
        @RequestMapping("/hello.do")
        public String hello(@CookieValue(value = "JSESSIONID") String cookie){
            System.out.println("CookieValue : " + cookie);
            return "suc";
        }
    }
    

    使用postman进行访问,得到如下输出:

     


    问题:html和jsp的区别

    1. 运行机制:HTML 运行在客户端,由浏览器解释执行;JSP 运行在服务器端,需要 Web 容器提供运行环境。
    2. 用途:HTML 侧重于静态数据展示;JSP 侧重于和服务器交互,主要用于动态网页开发。[服务器(如 Tomcat)将 JSP 转换为 Servlet(Java 类)执行 Servlet 中的 Java 代码,生成动态内容]
    3. 嵌入代码:JSP 是一个特殊的 HTML,相当于在 HTML 中嵌入了 Java 代码。
    4. 加载速度:HTML 在本地计算机上运行时加载速度更快;JSP 需要与 Web 服务器进行交互,因此加载速度较慢。
    • try:用于包裹可能会抛出异常的代码块。
    • catch:用于捕获异常并处理异常的代码块。
    • finally:用于包含无论是否发生异常都需要执行的代码块。
    • throw:用于手动抛出异常。
    • throws:用于在方法声明中指定方法可能抛出的异常。
    • Exception类:是所有异常类的父类,它提供了一些方法来获取异常信息,如 getMessage()、printStackTrace() 等。

    异常处理以及自定义异常

    异常类(Exception)有两个主要的子类:IOException 类和 RuntimeException 类。

    声明自定义异常处理

    先定义自定义异常类

    此时可以在程序中可以直接抛这种自定义类型的异常

    如 throw new SysException("Error!");但是只能抛出这一种类型的异常,遇到其他的异常还需要再处理。

    如果此时再写一个SysExceptionResolver,SysExceptionResolver 的本质是 “统一异常响应格式”,无论什么类型的异常,最终都以相同的格式(跳转到 error 页面,显示 errorMsg)返回给用户。需要实现HandlerExceptionResolver 类,并实现其中的接口resolveException。

    此时便可以处理所有的异常,对于

    异常如果是自定义异常(SysException类),那么就直接使用其错误信息;

    其他异常(如 NullPointerException、IllegalArgumentException):将其转换为 SysException,并统一处理。

    • 对用户友好:无论发生什么异常,用户只会看到统一的错误页面(如 “系统繁忙,请稍后再试”),而不是技术细节(如堆栈跟踪)。

    比如在Controller中,不捕捉异常,然后主动触发一个异常,然后会被SysExceptionResolver 捕获异常,比如如下的算数异常,会被捕捉到,然后进入resolveException进行处理。因为不是自定义异常,所以会设置为“系统繁忙,请稍后再试”,然后设置到mv,然后让用户跳转到error界面,同样会加上前后缀。

    当我访问http://localhost:9000/test_war_exploded/role/findAll.do的时候,然后就会触发除0算数异常,然后返回给用户error.jsp界面

    此时我把controller代码改成自定义类型异常


    Java Web的三大组件:

    Servlet、Filter(过滤器),Listener(监听器)

    拦截器是SpringMVC专属

    SpringMVC 拦截器

    1. SpringMVC框架中的拦截器用于对处理器(controller)进行预处理和后处理的技术。
    2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
    3. 拦截器和过滤器的功能比较类似,有区别
      1. 过滤器Filter是Servlet规范的一部分,任何框架都可以使用过滤器技术。
      2. 拦截器是SpringMVC框架独有的。
      3. 过滤器配置了/*,可以拦截任何资源(包括静态资源,如static/js/*)。
      4. 拦截器只会对控制器Controller中的方法进行拦截。
    1. 拦截器也是AOP思想的一种实现方式
    2. 想要自定义拦截器,需要实现HandlerInterceptor接口,该接口中有三个方法:preHandle、postHandle、afterCompletion

    preHandle:是在controller方法执行前执行拦截的方法:

      1. 可以使用request或者response跳转到指定的页面
      2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。(取决与springmvc.xml中的配置的拦截器数量,根据配置的顺序顺序执行)
      3. return false不放行,不会执行controller中的方法。
      4. 应用场景:权限拦截
        若用户权限不足,可在 postHandle 中转发到 error.jsp 或登录页。

    postHandle:postHandle是controller方法执行后执行的方法,在JSP视图执行前

      1. 可以使用request或者response跳转到指定的页面
      2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。

    afterCompletion:在JSP执行后执行

      1. request或者response不能再跳转页面了

    代码:创建一个软件包,在里面创建一个拦截器类:

    创建controller类

    在springmvc.xml中配置:

    这样当我们访问http://localhost:9000/test_war_exploded/dept/findAll.do的时候,会先执行prehandle方法,再执行controller中的方法,再执行postHandle中的方法,将页面跳转至index.jsp,不再是suc.jsp,最后执行afterCompletion方法

    输出结果如下:

    配置多个拦截器

    再编写一个拦截器

    在springmvc.xml中配置

    再次输出:


    遇到的问题:

    1、启动tomcat服务器,当提交上传文件后,服务器一直报500错误。根本原因是commons-fileupload和commons-io找不到,但是在maven中已经成功导入。最后发现是tomcat的lib库中缺少commons-fileupload和commons-io,将这两个jar包放入到tomcat的lib库中即可。

    2、前端上传文件时,name属性名字一定要和后端中的参数名称一致,不然参数会为null


    网站公告

    今日签到

    点亮在社区的每一天
    去签到