Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • 手写Spring

  • SSM

    • Spring
    • SpringMVC
      • @RequeatMapping把请求的路径和对应处理的controller方法关联起来
      • 获取请求参数
      • 往域中共享数据及转发视图
      • RESTful
      • json
      • 文件上传下载
      • 拦截器
      • SpringMVC执行过程
      • SSM整合
    • Mybatis
    • 问题记录
  • SpringBoot

  • JavaWeb

  • Spring
  • SSM
phan
2023-05-15
目录

SpringMVC

# SpringMVC

# @RequeatMapping把请求的路径和对应处理的controller方法关联起来

url路径:ip+接口+上下文路径applicationContext+类上注解路径信息+方法前注解路径信息

使用对应请求方法派生的注解方式。使用@PathVariable注解把请求路径的占位符对应到形参中

@RequestMapping("/user")
public UserController{
@RequestMapping(value={"/index","/"},method = RequestMethod.GET)
public String index(){}

@PostMapping("/add")
public String add(){}
----restful风格-----
@GetMapping("/delete/{username}/{id}")
public String del(@PathVariable("id") Integer id,@PathVariable("username") String uasername){}
}
1
2
3
4
5
6
7
8
9
10
11

web-xml配置中央控制器servlet,并初始化spring资源

<servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 获取请求参数

Controller方法形参参数名和请求参数名对应(不对应使用@RequestParam匹配)

形参直接用实体类形参来获取请求参数,前提是实体类属性名要和请求参数名对应(设置get,set方法)。

@RequestMapping("/user")
public String add(String username,String password){}
public String add(User user){}
1
2
3

编码问题,直接在web-xml中使用spring封装的编码过滤器

<filter>
        <filter-name>characterEncodingFilter</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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
</filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 往域中共享数据及转发视图

使用model往请求域共享数据

会话域和应用域使用原生HttpSession的API方法以及session.getServletContext()

public String testModel(Model model) {
model.addAttribute("name", "admin");
return "index";
}
1
2
3
4

转发视图"forward:/test","redirect:/test"。浏览器(html)会自动解析/的路径不包含上下文路径,而服务器解析(后端controller)包含上下文路径applicationContext

# RESTful

所有资源统一由对应的地址标识,对资源不同方式的操作(增删改查)通过不同的请求方式来表述(get,post,delete,put),然后请求参数不再用?分隔url和请求参数,而是把参数拼接在url作为资源路径一部分user/1/admin,然后通过注解获取。

但是浏览器仅支持get和post请求,因此需要使用过滤器hiddenHttpMethodFilter来转换请求方式。转换时请求方式为post,然后表单包含一个请求参数_method,值为真实的请求方式(put,delete)

<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
------
GettingMapping/DeleteMapping
1
2
3

静态资源请求时要添加<mvc:default-servlet-handler/>,让默认的servlet处理

# json

springMVC使用@RequestBody把前端传到后端服务器的json格式请求参数转化成java对象

(maven导入jackson依赖=>spring.xml配置文件设置<mvc:annotation-driven />,启动springmvc控制器的注解功能 =>给形参中接收的变量注解)


@ResponseBody注解controller方法,方法返回值为要转化为json格式的java对象,SpringMVC会自动把该java对象转为json格式相应给请求的页面。

@RestController注解相当于类标识@Controller,然后类里面所有方法注解@ResponseBody

# 文件上传下载

使用ResponseEntity<byte[]作>为控制器的返回值

File.separator可以在不同文件系统下'/'或者'\'分割文件不同目录

@RequestMapping()
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws
IOException {
//获取ServletContext对象,也就是项目在服务器的上下文路径
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
InputStream is = new FileInputStream(realPath);
byte[] bytes = new byte[is.available()];
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers,
statusCode);
is.close();
return responseEntity;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

上传功能:spring配置multipartfile实例bean(通过id实例化bean)=>表单设置enctype属性=>controller方法形参添加MultipartFile photoname形参接收表单穿过来的文件数据。

----Spring bean配置-----
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
</bean>
-----前端form表单------
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
</bean>
-----服务器接收文件保存在服务器-----
@PostMapping("/upload")
public String testUpload(MultipartFile photo, HttpSession session) throws IOException {
    String filename = photo.getOriginalFilename();
    ServletContext servletContext = session.getServletContext();
    String photoPath=servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if (!file.exists()) {
        file.mkdir();
    }
    String filetype = filename.substring(filename.lastIndexOf("."));
     filename = UUID.randomUUID().toString() + filetype;
    String fileSavePath = photoPath + File.separator + filename;
    photo.transferTo(new File(fileSavePath));
    return "index";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 拦截器

用于拦截控制器方法的执行,需要实现HandlerInterceptor接口的三个方法(控制器方法之前,控制器方法之后,视图渲染之后),preHandle返回true则放行当前控制器方法。拦截器的作用对象是所有的控制器的方法,若想针对某个路径的请求通过<mvc:interceptors>

<mvc:interceptors>
<bean class="interceptor.FirstInterceptor"/>
</mvc:interceptors>
1
2
3

多个拦截器执行:一般情况执行顺序和在springMVC中配置的顺序有关,preHandle是顺序执行,而postHandle和afterCompletion是反序执行(for循环是从interceptors.size()—>0)。

若有拦截器返回false,则该拦截器之后的preHandle以及afterCompletion(包括当前拦截器)不会执行;所有拦截器的postHandle都不会执行。

# SpringMVC执行过程

DispatcherServlet初始化:创建WebApplicationContext容器(反射创建ioc容器对象—>把Spring容器设置为父容器)—>刷新容器(初始化策略包括初始化文件上传处理器,handlemapping)—>将ioc容器在应用域共享

DispatcherServlet处理请求过程:HttpServlet类中根据请求的method来调用对应的doGet/doPost方法;而在它的子类FrameworkServlet中,重写了所有do方法,全部都是processRequest来处理;最终在DispatcherServlet方法中真正处理请求的由doDispatch进行。

doDispatch:通过mappedHandle映射(url,method信息)找到对应的处理器方法,它本质是一个处理器执行链,里面还包括拦截器方法;然后由HandleAdapter执行处理器控制器方法(把请求参数填充控制器方法的形参)—>postHandle—>Handle处理完后,控制器方法返回类型选择合适的视图解析器,处理视图(render)—>afterCompletion

# SSM整合

在web服务器启动,读取Spring配置文件,创建Spring的IOC容器。使用监听器完成

控制层的bean通过SpringMVC配置文件进行管理,业务层服务层的bean通过Spring配置文件进行管理

web.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">
<!--    字符过滤编码-->
<filter>
    <filter-name>characterEncodingFilter</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>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!--    改变请求方式编码-->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!--    配置中央控制器-->
<servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--        设置springMVC文件位置和名称-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!--    配置spring监听器-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--    设置spring配置文件自定义的位置和名称-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

spring.xml(把mybatis核心配置文件整合到spring中,但是映射文件还需要自己写)配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<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:tx="http://www.springframework.org/schema/tx"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--    扫描除控制层所有包-->
<context:component-scan base-package="service"/>

<context:property-placeholder location="classpath:jdbc.properties"/>

<!--    配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

<!--    事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--    事务注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!--    实际上这个类实现了factoryBean接口,因此getObject返回sqlSessionFactory,能够在ioc拿到这个对象-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="typeAliasesPackage" value="pojo"></property>
    <property name="configuration">
        <bean class="org.apache.ibatis.session.Configuration">
            <property name="mapUnderscoreToCamelCase" value="true"></property>
        </bean>
    </property>
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor"></bean>
        </array>
    </property>
    
</bean>
<!--    配置mapper接口扫描,能将包下所有接口通过sqlSession创建代理实现类对象,并交给IOC容器管理-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="mapper"></property>
</bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

springMVC.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<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
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd  ">

<context:component-scan base-package="controller"></context:component-scan>
<bean id="viewResolver"
      class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"/>
    <property name="characterEncoding" value="UTF-8"/>
    <property name="templateEngine">
        <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
            <property name="templateResolver">
                <bean
    class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                    <!-- 视图前缀 -->
                    <property name="prefix" value="/WEB-INF/templates/"/>
                    <!-- 视图后缀 -->
                    <property name="suffix" value=".html"/>
                    <property name="templateMode" value="HTML5"/>
                    <property name="characterEncoding" value="UTF-8" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

<!--    默认servlet处理静态资源-->
<mvc:default-servlet-handler/>
<!--    开启mvc注解驱动-->
<mvc:annotation-driven/>
<!--        视图控制器-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<!--    文件上传解析器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" name="multipartResolver"></bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
编辑 (opens new window)
#Spring
上次更新: 2023/12/15, 15:49:57
Spring
Mybatis

← Spring Mybatis→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式