SpringMVC学习总结

本文介绍了SpringMVC的核心特性,包括基于Spring的原生项目、DispatcherServlet的整合、全面的解决方案、高效开发、组件化与性能优化,以及Maven配置和关键组件的详细配置过程。
摘要由CSDN通过智能技术生成

特点:

  • Spring家族的原生项目,是Spring的一个子项目,与IOC等容器无缝对接
  • 基于原生的Servlet,通过前端控制器DispatcherServlet,对请求和响应进行统一处理
  • 表述层各细分领域需要解决的问题全方位覆盖,提供全面的解决方案
  • 代码清晰简洁,大幅度提升开发效率
  • 内部组件化程度高,可插拔式组件即插即用
  • 性能卓越,适合现代大型、超大型互联网项目需求

Maven工程SpringMVC依赖

//web工程打包方式
<packaging>war</packaging>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>x.x.x</version>
</dependency>

web.xml配置文件

  • 注入DispattcherServlet前端控制器
    • 设置Spring配置文件路径
    • 设置服务启动级别
    • 路径映射
      • /所匹配的请求可以是/login或.html或.js或.css方式的请求路径

      • /不能匹配.jsp请求路径的请求

  • 监听器
  • 过滤器
    • CharacterEncodingFilter   字符编码
    • HiddenHttpMethodFilter    URL请求方式
      • 表单提交
      • 请求方式必须POST
      • 请求参数必须为_method(隐式表单标签)
      • <input type="hidden" name="_method" value="PUT" />
<?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">
    <!--前端控制器-->
    <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>

    <!--字符编码过滤器,解决中文乱码-->
    <filter>
        <filter-name>encodingFilter</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>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--请求方式过滤器,开启PUT/DELETE请求-->
    <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>

</web-app>

SpringMVC配置文件

  • 开启注解扫描组件
  • 配置静态资源处理
  • 注册mvc注解驱动
  • 配置视图解析器
    • InternalResourceViewResolver:jsp页面使用
    • ThymeleafViewResolver

InternalResourceViewResolver   SpringMVC原生视图

​
<?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="com.atguigu.controller"></context:component-scan>
    <!--静态资源扫描-->
    <mvc:default-servlet-handler/>
    <!--注解驱动-->
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/templates/"></property>
        <!--后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

​

ThymeleafViewResolver   视图模版解析器

<?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="com.atguigu.mvc.controller"/>

    <!-- 配置Thymeleaf视图解析器 -->
    <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>

    <!-- 
       处理静态资源,例如html、js、css、jpg
      若只设置该标签,则只能访问静态资源,其他请求则无法访问
      此时必须设置<mvc:annotation-driven/>解决问题
     -->
    <mvc:default-servlet-handler/>

    <!-- 开启mvc注解驱动 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <!-- 处理JSON响应中文内容乱码 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="defaultCharset" value="UTF-8" />
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html</value>
                        <value>application/json</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>

请求控制器

对前端控制器发送的请求进行统一处理,对不同的请求创建对应的方法的过程;即创建一个类,每个请求创建对应的方法处理,称为请求控制器。每一个方法称为控制器方法

@Conttroller
public class Controller{}

  @RequestMapping请求映射注解

特点:

  • 注解的值唯一
  • 类:多用于不同模块功能开发
  • 方法:具体请求路径
        

value属性

属性值必须设置,可以使用数组,只要有一个属性值匹配就可以访问

ant风格

  • ?:表示任意单个字符
  • *:表示任意0个或多个字符
  • **:表示一层或多层目录
    • 格式:/**/xxx

restful风格

  • 格式:/{占位符}
  • 控制器方法形参:@PathVariable("占位符")
  • @PathVariable:将占位符所表示的数据赋值给控制器方法的形参
@RequestMapping("/test/{id}")
public String test(@PathVariable("id") int id){}

method属性

  • RequestMethod.GET/RequestMethod.POST/RequestMethod.PUT/RequestMethod.DELETE
  •  派生注解:GetMapping/PostMapping

请求路径满足value属性值,不满足method属性,页面报错405

params属性

  • params:请求参数中必须携带params请求参数
  • !params:请求参数中必须不携带params请求参数
  • params=value:请求参数中必须携带params请求参数,且参数值等于value
  • params!=value:请求参数中必须携带params请求参数,且参数值不等于value

headers属性

  • headers:请求参数中必须携带headers请求头信息
  • !headers:请求参数中必须不携带headers请求头信息
  • headers=value:请求参数中必须携带headers请求头信息,且等于value
  • headers!=value:请求参数中必须携带headers请求头信息,且不等于value

请求路径满足value属性值和method属性值,但是不满足params属性值或者headers属性值,页面报错400

SpringMVC请求参数获取

  • ServletAPI
    • request.getParameter()
  • 控制器方法形参
  • @RequestParam 
    • 请求参数和控制器方法的形参建立映射关系
    • value:指定为形参赋值的请求参数的参数名
    • required:设置是否必须传递此请求参数
      • true:必须传请求参数,若value未传值,defaultValue值未设置,页面报错400
        • false:不是必须传值,若未传值,形参值为null
    • defaultValue:无论required值是true或false,value属性值为空或者未传输时,使用默认值为形参赋值
  • @RequestHeader 
    • 请求头信息和控制器方法的形参建立映射关系
    • value
    • required
    • defaultValue
  • @CookieValue
    • cookie数据和控制器方法的形参建立映射关系
    • value
    • required
    • defaultValue
  • 控制器方法实体类形参(form表单)
    • 请求参数的参数名和实体类的属性名一致,请求参数自动为此属性赋值

数据处理及跳转(数据回显)

ModelAndView

@RequestMapping("/test")
public ModelAndView test(){
    ModelAndView mav = new ModelAndView();
    mav.addObject("msg","hello world");
    mav.serViewName("test");
    return mav;
}

Model

@RequestMapping("/test")
public String test(String name,Model model){
    model.addAttribute("name",name);
    return "sucees";
}

Map

@RequestMapping("/test")
public String test(Map<String,Object> map){
    map.put("name","name");
    return "sucees";
}

ModelMap

@RequestMapping("/test")
public String test(String name,ModelMap model){
    model.addAttribute("name",name);
    return "sucees";
}

Session(session域)

@RequestMapping("/test")
public String test(HttpSession session){
    session.setAttribute("session","Hello World");
    return "success";

}

Application(整个项目)

@RequestMapping("/test")
public String test(HttpSession session){
    ServletContext application = session.getServletContext();
    application.setAttribute("session","hello world");
    return "success";

}

页面跳转方式

  • 转发:forward
@RequestMapping("/test")
public String test(){
    return "forward:/success";
}
  • 重定向:redirect
@RequestMapping("/test")
public String test(){
    return "redirect:/success";
}

HttpMessageConverter报文信息转换器

将请求的报文转换为java对象,或者将java对象转换为响应报文

@RequestBody

  • Post请求获取请求体
  • 控制器方法形参前添加@RequestBody
@RequestMapping("/test")
public String test(@RequestBody String req){
    System.out.println(req);
    return "success";
}

RequestEntity

  • 封装请求报文的一种类型
  • 在控制器方法的形参设置该类型形参 RequestEntity<String>
  • getHeaders():获取请求头
  • getBody():获取请求体
@RequestMapping("/test")
public String test(RequestEntity<String>  req){
    System.out.println(req.getHeaders()+req.getBody());
    return "success";
}

@ResponseBody

  • 控制器方法添加@ResponseBody
  • 该方法的返回值类型直接作为响应报文的响应体响应到浏览器
@RequestMapping("/test")
@ResponseBody
public String test(){
    //success字符串直接响应到浏览器
    return "success";
}

ResponseEntity

  • 用于控制器方法的返回值类型
  • 常用于文件的上传下载功能

@RestController

  • 复合注解,@Controller/@ResponseBody
  • 标识在请求控制器类上,为当前类添加@Controller注解,为类下所有方法添加@ResponseBody注解

Json数据交互

{}保存对象数据,[ ] 保存数组数据

Jackson

  • 导jackson.jar包
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>x.x.x</version>
</dependency>
  • 添加mvc注解驱动
<mvc:annotation-driven />
  • 将java对象数据交由控制器方法的@ResponseBody注解处理,自动转换为json字符串

FastJson

  • 导入FastJson包
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>x.x.x</version>
</dependency>
  • JSON  Java对象 转 JSON字符串   
  • JSONArray  JSON字符串 转 Java对象
  • JSONObject  Java对象 转 JSON对象

JSON数据中文乱码

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

文件上传与下载

上传功能

  • 导入上传依赖jar包
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>x.x.x</version>
</dependency>
  • xml配置文件解析器
    •  id必须为multipartResolver
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
  • 上传控制器方法
@RequestMapping("/Up")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //获取上传的文件的文件名
    String fileName = photo.getOriginalFilename();
    //处理文件重名问题
    String hzName = fileName.substring(fileName.lastIndexOf("."));
    fileName = UUID.randomUUID().toString() + hzName;
    //获取服务器中photo目录的路径
    ServletContext servletContext = session.getServletContext();
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if(!file.exists()){
        file.mkdir();
    }
    String finalPath = photoPath + File.separator + fileName;
    //实现上传功能
    photo.transferTo(new File(finalPath));
    return "success";
}

下载功能实现

@RequestMapping("/Download")
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;
}

拦截器

  • 创建一个类,继承HandlerInterceptor接口,重写接口的3个方法
    • preHandle
    • postHandle
    • AfterComplation
  • SpringMVC.xml配置拦截器(对所有请求进行拦截)

方法 一

<mvc:interceptors>
    <bean class="拦截器全限定类名路径"></bean>
</mvc:interceptors>

方法二

<mvc:interceptors>
    <!--ref需要开启扫描注解,类名添加注解@Component-->
    <ref bean="类名"> 
</mvc:interceptors>

方法三

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <!-排除不拦截的请求路径-->
        <mvc:exclude-mapping path="/" />
        <ref bean="拦截器类名"></ref>
    </mvc:interceptor>
</mvc:interceptors>

异常处理器

两个接口实现类

  • DefaultHandlerExceptionResolver:Spring默认异常处理器
  • SimpleMappingExceptionResolver

配置文件

<!--配置异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--设置异常跳转的页面  error视图名称-->
            <prop key="异常全路径名">error</prop>
        </props>
    </property>
    <!--设置将异常信息共享在请求域中的键-->
    <property name="exceptionAttribute" value="ex"></property>
</bean>

注解配置

@ControllerAdvice:标识在控制器类上,将当前类标识为异常处理组件,@Component的扩展注解组件

@ExceptionHandler():标识控制器方法能处理的异常

Exception:当前请求中出现的异常对象

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(value = {异常名.class,NullPointerException.class})
    public String testException(Exception ex, Model model){
        model.addAttribute("ex",ex);
        return "error";
    }
}

注解配置SpringMVC方式

配置类(web.xml)

 AbstractAnnotationConfigDispatcherServletInitializer 

public class SpringConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * Spring配置类
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{Spring.class};
    }

    /**
     * SpringMVC配置类
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVC.class};
    }

    /**
     * DispatcherServlet的映射规则,即 url-pattern
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 过滤器
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("utf-8");
        characterEncodingFilter.setForceEncoding(true);
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};
    }
}

配置类(SpringMVC.xml)

@Configuration
//扫描组件
@ComponentScan("com.atguigu.mvc.controller")
//开启MVC注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    //使用默认的servlet处理静态资源
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    //配置文件上传解析器
    @Bean
    public CommonsMultipartResolver multipartResolver(){
        return new CommonsMultipartResolver();
    }

    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        FirstInterceptor firstInterceptor = new FirstInterceptor();
        registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
    }
    
    //配置视图控制
    
    /*@Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }*/
    
    //配置异常映射
    /*@Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
        Properties prop = new Properties();
        prop.setProperty("java.lang.ArithmeticException", "error");
        //设置异常映射
        exceptionResolver.setExceptionMappings(prop);
        //设置共享异常信息的键
        exceptionResolver.setExceptionAttribute("ex");
        resolvers.add(exceptionResolver);
    }*/

    //配置生成模板解析器
    @Bean
    public ITemplateResolver templateResolver() {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        // ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(
                webApplicationContext.getServletContext());
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    //生成模板引擎并为模板引擎注入模板解析器
    @Bean
    public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    //生成视图解析器并未解析器注入模板引擎
    @Bean
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setTemplateEngine(templateEngine);
        return viewResolver;
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值