SpringMVC知识点总结

SpringMVC 知识点总结

MVC 设计思想

mvc: (Model View Controller), 将一个web应用程序进行分层、model专注于
业务逻辑(业务层、持久层、实体层), view 专注于页面表现,通过将 业务和表现 进行分离
可以降低程序的耦合度,让程序变得更加容易维护,通过 controller 将 view 和 model进行
关联,从而实现web应用程序的开发,mvc强调所有的请求应该有一个统一的访问入口,在SpringMVC
中,通过 DispatcherServlet 核心控制器进行实现

DispatcherServlet

DispatcherServlet 是一个 Servlet, 所以 SpringMVC 本质上仍旧是Servlet, 只是对Servlet
进行了深度的封装, DispatcherServlet会产生一个 springmvc容器,该容器默认的配置文件是
-servlet.xml, 可以通过contextConfigLocation进行配置文件的设置

  • 在 web.xml 中 配置 核心控制器 DispatcherServlet
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-mvc.xml</param-value>
    </init-param>
    <!-- DispatcherServlet中的init方法会随tomcat启动而加载,如果不配置,会在第一次使用servlet的时候才会执行 -->
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  • 在 web.xml 中,配置 Spring容器

Spring容器不是必须的,可以整个环境只有一个springmvc容器,官方推荐使用两个容器

<context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath*:spring-context.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Spring容器, SpringMVC容器扫描配置

  • 将 控制层 交给 SpringMVC 容器 负责扫描
spring-mvc.xml
   
<context:component-scan base-package="com.qikux" use-default-filters="false">
    <!--   添加一个 白名单,只让它扫描 Controller 注解注释的类  -->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

use-default-filters 默认是true, 代表会扫描类上的 @Controller, @Service, @Repository, @Component注解
如果设置为false, 那么只会扫描 白名单中配置的某个注解

  • 将除控制层 之外的其他对象交给 Spring容器负责扫描
spring-context.xml

<context:component-scan base-package="com.qikux">
    <!--   添加一个 黑名单,让它扫描 除 Controller 注解注释的类之外的类  -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

视图解析器 InternalResourceViewResolver

视图解析器是为了映射控制层返回的结果,控制层,返回String或者 ModelAndView ,那么如果找到对应的 view 页面

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

控制器的编写

@Controller
@RequestMapping("/index")
public class IndexController {
    
    @GetMapping("/")
    public ModelAndView index() {
        return new ModelAndView("index");
    }
}

@RequestMapping 可以写在 类上,用来定义访问请求的一级路径,可以写在方法上,用来定义二级路径
在方法上,推荐使用 @GetMapping, @PostMapping, @PutMapping, @DeleteMapping …

PS: http://localhost:8080/index/ 即可找到 /WEB/INF/jsp/index.jsp 视图

SpringMVC 接收页面参数

  1. 在控制器上,直接通过 @RequestParam 注解 接收传入的参数

缺点: 如果参数过多,那么控制器的方法声明会显得非常臃肿,并且在接收数据后可能还要进行数据组装

@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public ModelAndView index(@RequestParam(value="name", required=true) String name) {
        return new ModelAndView("index");
    }
}

PS: http://localhost:8080/index/?name=张三

@RequestParam 注解

  • value : 用来设置表单提交参数的key, 如果不指定,默认和被注解的变量名称保持一致
  • required: 是否必传,默认为 true, 用来限定参数是否必传
  • defaultValue : 设置默认值,通过和 required=false 配合使用
  1. 使用模型对象接收页面参数

优点: 可以将多个参数直接组装成一个模型对象

缺点: 不能限制某个参数是否必传,可以配置后期的数据校验来实现参数的限制

@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public ModelAndView index(User user) {
        return new ModelAndView("index");
    }
}

class User {

    private String username ; 
    
    private String password ; 
    
    ... set, get ...
}

PS: http://localhost:8080/index/?username=admin&password=123456

  1. 使用 Map 来接收页面参数
@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public ModelAndView index(@RequestParam Map<String, Object map) {
        return new ModelAndView("index");
    }
}

PS: http://localhost:8080/index/?name=admin&pwd=123456

参数 会自动被放入到 Map 中,在 Map参数前,必须添加 @RequestParam注解,且不能设置 value

  1. 路径参数

路径参数支持的写法有
{key} : key用来匹配一个路径参数,但不能匹配 /
{key:regexp} 在key的后面允许使用 正则表达式进行值的限制
支持 * , ? 等通配符

@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/{id}")
    public ModelAndView index(@PathVariable Long id) {
        return new ModelAndView("index");
    }
}

@PathVariable 注解

  • value : 用来设置 /{id} 占位符中的key, 和占位符中的key保持一致,如果不设置,则 需要变量名和占位符保持一致
  1. json格式参数接收

主要配合 异步请求实现 JSON数据格式的传输

@Controller
@RequestMapping("/index")
public class IndexController {

    @PostMapping("/json")
    @ResponseBody
    public User index(@RequestBody User user) {
        return user;
    }
}

fetch('http://localhost:8080/index/json', {
    method: 'post' , 
    headers: {
        'Content-Type': 'application/json' , 
    },
    body: JSON.stringify( {username: 'admin',  password: '123456'} )
})

响应方式

  1. 返回 String

    • 通过视图解析器转换到 jsp页面
    @Controller
    @RequestMapping("/index")
    public class IndexController {
    
        @GetMapping("/")
        public String index() {
            return "index";
        }
    }
    

    pS: 会找到 /WEB-INF/jsp/index.jsp

    • 转发到一个内部请求中
    
    @Controller
    @RequestMapping("/index")
    public class IndexController {
    
        @GetMapping("/")
        public String index() {
            return "forward:/index/a";
        }
    
        @GetMapping("/a")
        public String a() {
            return "a";
        }
    }
    

    当访问 /index/ 的时候,会通过转发 跳转到 /index/a 最终呈现的是 a.jsp页面效果

    • 重定向
    @Controller
    @RequestMapping("/index")
    public class IndexController {
    
        @GetMapping("/")
        public String index() {
            return "redirect:/index/a";
        }
    
        @GetMapping("/a")
        public String a() {
            return "a";
        }
    }
    

    当访问 /index/ 的时候,会通过重定向 跳转到 /index/a 最终呈现的是 a.jsp页面效果

  2. 返回 ModelAndView (官方推荐写法)

返回一个ModelAndView 对象,可以通过 构造方法或者setViewName 设置视图名,
视图名的写法参考 返回String 的三种写法

return new ModelAndView("index") ;

return new ModelAndView("forward:/index/a")

return new ModelAndView("redirect:/index/a")
  1. 返回 HttpEntity 或者 ResponseEntity

主要应用于文件下载

@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public HttpEntity<String> index() {
        return ResponseEntity.ok("hello world!");
    }
}

Ps:当访问 http://localhost:8080/index/ 的时候,浏览器会显示一个 hello world!

  1. 返回 JSON

    • 方式一:
    @Controller
    @RequestMapping("/index")
    public class IndexController {
    
        @GetMapping("/")
        public HttpEntity<User> index() {
            return ResponseEntity.ok(User....);
        }
    }
    
    • 方式二:
    @Controller
    @RequestMapping("/index")
    public class IndexController {
    
        @GetMapping("/")
        @ResponseBody
        public User index() {
            return User...;
        }
    } 
    

如果需要返回JSON, 那么需要添加 jackson对应的依赖包,并配置消息转换器。
如果一个类所有的请求都需要返回JSON, 可以直接在类上使用@ResponseBody
或者 使用 @RestController 替代 @Controller + @ResponseBody

消息转换器配置

<bean id="mappingJackson2HttpMessageConverter"
      class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="defaultCharset" value="utf-8"/>
    <property name="supportedMediaTypes">
        <list>
            <value>text/html;charset=utf-8</value>
            <value>application/json;charset=utf-8</value>
        </list>
    </property>
    <property name="objectMapper">
        <bean class="com.qikux.modules.Jdk8TimeMapper"/>
    </property>
</bean>

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="defaultCharset" value="utf-8"/>
    <property name="supportedMediaTypes" value="text/html;charset=utf-8"/>
</bean>


<mvc:annotation-driven>
    <mvc:message-converters>
        <ref bean="stringHttpMessageConverter"/>
        <ref bean="mappingJackson2HttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

服务器向客户端传递数据方式

  • 使用 ModelMap 传递数据
@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public String index(ModelMap modelMap) { 
        // 传递一个键值对格式的数据
        modelMap.addAttribute(key, val) ;
        // 传递 一组 键值对格式的数据 
        modelMap.addAllAttributes(map);
        ...
        return "index";
    }
} 

值会被携带到 /WEB-INF/jsp/index.jsp中,并放在了request作用域中,
可以通过EL表达式,根据键 获取值

  • 使用 Model 传递数据

用法和 ModelMap 完全相同

  • 使用 ModelAndView 传递数据
@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public ModelAndView index(ModelAndView mav) { 
        
        mav.setViewName("index") ;
        mav.addObject(key, val); 
        mav.addAllObjects(map) ;
        ...
        return mav ;
    }
} 

值会被携带到 /WEB-INF/jsp/index.jsp中,并放在了request作用域中,
可以通过EL表达式,根据键 获取值

  • 使用 原生 request 传递数据
@Controller
@RequestMapping("/index")
public class IndexController {
    
    //@Resource
    //private HttpServletRequest request ;

    @GetMapping("/")
    public String index(HttpServletRequest request) { 
        request.setAttribute(key, val) ;
        ...
        return "index" ;
    }
} 

需要引入 servlet-api 依赖包, request对象也可以通过 属性依赖注入的方式获取

  • 使用 RedirectAttributes 传递数据

解决 重定向 无法 通过 request 向下一个请求 传值的问题

@Controller
@RequestMapping("/index")
public class IndexController {


    @GetMapping("/")
    public String index(RedirectAttributes ra) { 
        
        // 通过闪存属性将数据传递到下一个请求中 
        ra.addFlashAttribute(key, val) ;
        
        return "redirect:/index/a" ;
    }
    
    @GetMapping("/a")
    public String a(ModelMap model) { 
        
        // 获取上一个请求通过闪存 传递的数据 
        Object obj =  model.getAttribute(key) 
        ...
        return "a" ;
    }
} 
  • 使用 session 传递数据
public class IndexController {
    
    //@Resource
    //private HttpSession session ;

    @GetMapping("/")
    public String index(HttpSession session) { 
        session.setAttribute(key, val) ;
        ...
        return "index" ;
    }
} 

文件上传

  • 通用文件上传解析器实现文件上传
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--设置 文件上传编码方式-->
    <property name="defaultEncoding" value="UTF-8"/>
    <!--默认值是 -1 ,代表 不限制上传文件的大小-->
    <property name="maxUploadSize" value="-1"/>
</bean>

需要 依赖 commons-fileupload 依赖包 , 在控制层上 使用 MultipartFile 接收上传的文件

public class IndexController {
    
    //@Resource
    //private HttpSession session ;

    @PostMapping("/upload")
    public String upload(@RequestPart("photo") MultipartFile photo) { 
        // 获取上传的文件名 
        photo.getOriginalFilename();
        // 上传的文件是否是空的
        photo.isEmpty(); 
        // 获取上传的文件大小
        photo.getSize();
        // 用 byte[] 存储上传的文件 
        photo.getBytes(); 
        // 以 字节流的形式存储上传的文件
        photo.getInputStream();
        // 将文件存储到指定的位置
        photo.transferTo(file);
    
        ...
        return "index" ;
    }
} 

MultipartFile 用来接收上传的文件对象,如果是多个文件,可以采用数组方式进行接收,
可以使用 @RequestParam 注解来限定上传对象对象,也可以通过 @RequestPart 来限定

  • 基于 servlet3.0 文件上传

配置servlet标准文件上传解析器

<bean id="multipartResolver" 
      class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />

在 核心控制器 DispatcherServlet中,添加 支持文件上传 , 使用 Part 对象接收上传的文件
支持 @RequestPart注解来限定文件上传

public class IndexController {
    
    //@Resource
    //private HttpSession session ;

    @PostMapping("/upload")
    public String upload(@RequestPart("photo") Part photo) { 
        // 获取上传的文件名 
        photo.getSubmittedFileName();
        // 获取上传的文件大小
        photo.getSize();
        // 以 字节流的形式存储上传的文件
        photo.getInputStream();
        // 将文件存储到指定的位置
        photo.write(file);
        ...
        return "index" ;
    }
} 

无论使用那种文件上传,文件上传解析器的bean的ID必须叫 multipartResolver

文件下载 HttpEntity

public class IndexController {
    
    //@Resource
    //private HttpSession session ;

    @PostMapping("/download")
    public HttpEntity<byte[]> download() { 
    
        byte[] files = ... ; 
        String filename = ... ;
        
        // 解决下载中文乱码问题
        filename = URLEncoder.encode(filename, StandardCharsets.UTF_8); 
        
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + filename)
                .body(files)
    }
} 

数据校验

Spring 提供了数据校验的功能,但Spring本身对数据校验实现的很少,
需要依赖 javax.validation 和 hibernate-validator 依赖包

常见的注解

  • @Email : 用来校验 邮箱
  • @Max : 用来限定数字的最大值
  • @Min : 用来限定数字的最小值
  • @Null / @NotNull : 用来限制值是否允许为空/非空
  • @Pattern : 使用正则表达式 验证字符串
  • @Past : 是否是 过去日期
  • @Future : 是否是未来日期
  • @Size(): 限制字符串最大/小长度
  • @Lenght(): 限制字符串最大/小长度
  • @Range(): 用来限定数字的范围
public class User {

    @Pattern(regexp = "[a-zA-Z][a-zA-Z0-9]{6,20}", message = "用户名以字母开头,且由字母和数组组成长度为6~20位")
    @NotEmpty(message = "用户名不能为空")
    private String username;

    @NotNull(message = "密码不允许为空")
    @Length(max = 20, min = 6, message = "密码长度在6~20位")
    private String password;

    ... 
}

校验数据

public class IndexController {
    
    //@Resource
    //private HttpSession session ;

    @PostMapping("/regist")
    public String regist(@Valid User user, BindingResult bindingResult) { 
       
       // 如果 校验失败
       if (bindingResult.hasErrors()) {
            // 获取错误消息 
            bindingResult.getFieldErrors(); 
            
            // 将错误信息 放到 Map 对象中
            Map<String, String> error = fieldErrors.stream()
                 .reduce(new HashMap<>(), (map, f) -> {
                     map.put(f.getField(), f.getDefaultMessage());
                     return map;
                 }, (a, b) -> a) ; 
                 
            ....      
       }
       
        return "index" ;
    }
} 

数据校验需要配置一个 LocalValidatorFactoryBean 对象,
可以通过 <mvc:annotation-driven /> 来启用该 bean 。
bindingResult.getFieldErrors()得到的错误信息,在jsp页面中,可以通过 spring 标签库获取

常见的过滤器

  • CharacterEncodingFilter : 字符集编码过滤器
<filter>
     <filter-name>encodingFilter</filter-name>
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
     <init-param>
         <param-name>forceEncoding</param-name>
         <param-value>true</param-value>
     </init-param>
     <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>

字符集编码过滤器通常配置在其他过滤器的前面

  • HiddenHttpMethodFilter : 让表单支持 PUT, DELETE, PATCH 请求方式
<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>

在提交表单是时候,提交方式设置为 POST, 传递一个 _method 参数,值为 PUT, DELETE, PATCH ,
让传统的同步表单提交支持 PUT , DELETE, PATCH 请求

  • FormContentFilter : XMLHttpRequest异步请求无法使用PUT,DELETE, PATCH 传递表单参数
<filter>
     <filter-name>formContentFilter</filter-name>
     <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>formContentFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>
  • CorsFilter : 解决 异步请求 跨域

静态资源处理

方式一:

<mvc:default-servlet-handler/> 

底层使用 DefaultServletHttpRequestHandler 处理静态资源

方式二:

<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/images/**" location="/images/" />

底层使用 ResourceHttpRequestHandler 处理静态资源

拦截器 HandlerInterceptor

拦截器 是 SpringMVC 特有的 切面手段,可以拦截 控制层对应的请求,
主要采用反射技术实现

  • preHandler : 前置处理器

会在进行到 控制器对应的方法前,执行 preHandler处理器中定义的代码,
如果 preHandler 返回 true, 则 继续执行下一个拦截器的preHandler或者
执行控制器对应的方法, 如果返回 false, 则会中断程序的执行,默认情况下
在浏览器上会呈现一片空白的效果。可以借助 request, response 进行合适的跳转

  • postHandler : 后置处理器

会在控制器方法执行完成(没有异常)的情况下,执行 postHandler后置处理器中的代码
可以获取到 控制器方法返回的结果 ModelAndView

  • afterCompletion : 最终处理器

无论控制器的方法是否有异常,都会执行的代码, 如果产生了异常,可以通过Exception异常对象来获取

拦截器 VS 过滤器

相同点:

  1. 都采用的切面技术
  2. 都可以拦截请求和响应

不同点:

  1. 过滤器filter 是 servlet容器提供的, 拦截器interceptor是 springmvc 框架提供的
  2. 过滤器filter 采用链式调用,拦截器是采用反射调用的
  3. 过滤器原则上可以拦截几乎所有请求,而拦截器只能拦截action请求
  4. 过滤器 先于 拦截器 执行
  5. 如果只需要对Action请求进行拦截,那么优先使用拦截器,如果对所有请求进行拦截,那么优先采用过滤器

国际化 (国内开发实际应用较少)

国际化主要通过 拦截器技术实现的,主要使用的类是 LocaleChangeInterceptor

在一些大型网站中,通常为了方便大众的使用,会对网站提供多语言的支持,例如支持
中文、英文、日文、韩文、俄文。那么此时网站需要对页面呈现的数据进行国际化处理

  • 配置 语言解析器

    1. AcceptHeaderLocaleResolver
    2. CookieLocaleResolver
    3. SessionLocaleResolver
<bean id="localeResolver" 
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />

默认采用的是 AcceptHeaderLocaleResolver 解析器,根据浏览器请求的 Accept-language 头信息
获取 对应的语言环境 , 可以使用 CookieLocaleResolver 和 SessionLocaleResolver 将要切换的语言
放到 Cookie / Session 中 ,解析器beanID 必须设置为 localeResolver

  • 管理国际化配置文件 ResourceBundleMessageSource

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
   <property name="defaultEncoding" value="UTF-8" />
        <!--  国际化配置文件的前缀名,默认是 messages -->
        <property name="basename" value="messages" />
</bean>

国际化配置文件的命名规范是 _语言.properties, 例如
messages_zh_CN.properties (中文), message_en_US.properties (英文)
messages_ja_JP.properties (日文) …

messages_zh_CN.properties

login=登录
msg=密码长度在{0}和{1}之间

messages_en_US.properties

login=Login
msg= password length required between {0} and {1}
  • 配置 语言拦截器
<mvc:interceptors>
   
   <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" 
         p:paramName="locale"/>
   
</mvc:interceptors>
  • 配置超链接,切换语言
<a href="?locale=zh_CN">中文</a>
<a href="?locale=en_US">英文</a>
<a href="?locale=ja_JP">日文</a>
  • 在 jsp 页面,使用 <spring:message /> 标签国际化页面数据
<spring:message code="" arguments="..."/>

code 是 国际化配置文件中定义的键,arguments 是该键对应值需要的参数
在 值上可以使用 {n} 进行占位, n 从 0开始

  • 在代码中,使用国际化
@Autowired
private MessageSource messageSource ;

... 
messageSource.getMessage(code, args, locale);

异常处理器

SpringMVC 提供了异常解决方案,可以通过 xml 或者 注解的方式 来进行配置

xml配置异常处理器 SimpleMappingExceptionResolver

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
     <!--
         配置 默认错误发生的时候,进入的 视图页面, 会自动找 /WEB-INF/jsp/error.jsp
             程序产生异常 才会进入的 页面
      -->
     <property name="defaultErrorView" value="error" />
     <!-- 当 进入 错误页面的时候,默认显示的状态码 , 默认是 200 -->
     <property name="defaultStatusCode" value="500" />

     <!-- 根据 程序返回的异常,跳转 不同的视图页面 -->
     <property name="exceptionMappings">
         <props>
             <prop key="java.lang.RuntimeException">error_run</prop>
             <prop key="java.lang.Exception">error</prop>
         </props>
     </property>
 </bean>

注解配置异常处理器 @ExceptionHandler

  • 局部配置 异常处理器
@Controller
@RequestMapping("/index")
public class IndexController {

    @GetMapping("/")
    public ModelAndView index() {
        return new ModelAndView("index");
    }
    
    @ExceptionHandler
    public ModelAndView error(Throwable e) {
       ... 获取 异常信息
       return new ModelAndView("error");
    }
}

如果在一个控制器中,添加一个 @ExceptionHandler,那么该注解注释的方法
只能在该控制器下的请求发生异常的时候,才会触发,其他控制器产生异常,不会
触发该异常处理

  • 全局配置 异常处理器
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler
    public ModelAndView error(Throwable e) {
       ... 获取 异常信息
       return new ModelAndView("error");
    }
}
  • 全局 JSON 异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler
    public Object error(Throwable e) {
       ... 获取 异常信息
       return ... ;
    }
}

@ExceptionHandler 可以通过 value 设置 针对具体哪种异常进行处理

其它注解

  • @ModelAttribute : 在接收参数的模型对象上,可以使用该注解,将 参数放到 request作用域中

@Controller
public class IndexController {
   
    public String register(@ModelAttribute("user")User user) {
         
         return "..." ;
    }
}
  • @SessionAttributes : 该注解主要应用于类上,将指定的数据放入到 session中

@Controller
@SessionAttributes(AppConst.LOGIN_FLAG)
public class LoginController {
   
    public ModelAndView login(String username ,String password) {
         
         ... 
         // 当向 ModelAndView 中,添加一个 
            键为 AppConst.LOGIN_FLAG(和 sessionattributes中的键相同)
            的时候,那么会自动将 该数据添加到 session中 
          
         mav.addObject(AppConst.LOGIN_FLAG, user) ;
         
         return "..." ;
    }
}
  • @SessionAttribute : 获取 Session中对应的数据
@Controller
public class IndexController {
     /**
         从 session中获取 User 对象
     */
    public String index(
            @SessionAttribute(value=AppConst.LOGIN_FLAG, required=false)User user) {
         
         // 直接通过 @SessionAttribute 获取登录标记 
         
         return "index" ;
    }
}
  • SessionStatus 清除 session 中的数据
@Controller
public class IndexController {
     /**
         从 session中获取 User 对象
     */
    public String logout(SessionStatus status) {
         ... 
         
         if (status.isComplete()) {
               // 清除 session 中的数据
               status.setComplete(); 
         }
         
         return "index" ;
    }
}
  • @CookieValue : 用来获取Cookie中指定键对应的值

  • @RequestHeader : 用来获取 Header请求头中某个键对应的值

任务调度

添加依赖包

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>2.3.2</version>
</dependency>
  • 基于XML的实现方式
  1. 编写一个任务
public class SimpleJob {
    /**
     * 负责打印内容
     */
    public void printText() {
        System.out.println("job is running .... 打印的内容是: hello");
    }
}
  1. 定义一个 jobDetail 任务
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
     <property name="targetObject">
         <bean class="com.qikux.quartz.SimpleJob" />
     </property>
     <property name="targetMethod" value="printText"/>
 </bean>
  1. 定义一个 Trigger 任务触发器
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
  <property name="jobDetail" ref="jobDetail" />
  <property name="cronExpression" value="0/3 * * * * ?"></property>
</bean>
  1. 定义一个 Schedule 任务调度器
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
      <array>
          <ref bean="cronTrigger" />
      </array>
  </property>
</bean>
  • 基于 JavaConfig 开发
  1. 在 配置类上,添加 @EnableScheduling

  2. 在 任务类上,添加 @Scheduled

@Component
public class SimpleJob {
    /**
     * 负责打印内容
     */
     @Scheduled(cron="0/3 * * * * ?")
    public void printText() {
        System.out.println("job is running .... 打印的内容是: hello");
    }
}
  1. 定义一个 jobDetail 任务
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
     <property name="targetObject">
         <bean class="com.qikux.quartz.SimpleJob" />
     </property>
     <property name="targetMethod" value="printText"/>
 </bean>
  1. 定义一个 Trigger 任务触发器
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
  <property name="jobDetail" ref="jobDetail" />
  <property name="cronExpression" value="0/3 * * * * ?"></property>
</bean>
  1. 定义一个 Schedule 任务调度器
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
      <array>
          <ref bean="cronTrigger" />
      </array>
  </property>
</bean>
SpringMVC的核心知识点包括以下内容:@Controller类注解、SpringMVC控制器类、SpringMVC核心配置类。 @Controller是SpringMVC框架中的一个注解,用于定义控制器类,表示该类是一个用于处理请求的控制器。 SpringMVC控制器类是指使用@Controller注解标注的类,它负责接收请求并调用相应的业务逻辑进行处理。控制器类中的方法通常使用@RequestMapping注解来映射具体的URL请求路径。控制器类可以处理不同的请求,根据请求的URL路径和请求方法的不同,执行相应的方法逻辑。 SpringMVC核心配置类是用于配置SpringMVC框架的配置类,它负责设置相关配置,例如扫描controller包、加载Controller控制器bean等。通过配置类,我们可以对SpringMVC框架进行进一步的个性化定制和配置。 总结起来,SpringMVC的核心知识点包括使用@Controller注解定义控制器类,编写控制器方法来处理请求,以及配置SpringMVC框架的核心配置类。这些知识点SpringMVC框架中重要的组成部分,用于实现请求的分发和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JAVA最全的核心知识点.rar](https://download.csdn.net/download/qq_37196324/12575426)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringMVC知识点](https://blog.csdn.net/qq_52822200/article/details/126799608)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值