SpringMVC知识点总结

本文主要包含:

1.springMVC视图解析器配置(InternalResourceViewResolver)

2.数据输出中 Model 、Map、 ModelMap及ModelAndView关系

3.<url-pattern>标签拦截规则

4. 自定义转换器实现日期类型参数

5.springMVC自带针对post请求的编码过滤器 (CharacterEncodingFilter)

6. springMVC对Restful风格的支持

7. 过滤器、拦截器、监听器

8.  Multipart实现文件上传

9.异常处理机制

10.重定向参数传递(flash属性)

1.springMVC视图解析器配置(InternalResourceViewResolver)

在springMVC配置文件中

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

2.数据输出中 Model 、Map、 ModelMap及ModelAndView关系

springMVC在handler方法上传入Map、Model、ModelMap和ModelAndView参数(可以在方法上传入,也可以在方法内声明),并向这些参数中保存数据(放入到请求域),都可以在页面获取到

Model 、Map及 ModelMap 实例getClass打印类型为org.springframework.validation.support.BindingAwareModelMap

而ModelAndView getCalss 打印类型为org.springframework.web.servlet.ModelAndView

public class BindingAwareModelMap extends ExtendedModelMap 
public class ExtendedModelMap extends ModelMap implements Model 
public class ModelMap extends LinkedHashMap<String, Object> {
public class ModelAndView {

	/** View instance or view name String. */
	@Nullable
	private Object view;

	/** Model Map. */
	@Nullable
	private ModelMap model;


    public ModelAndView addObject(String attributeName, @Nullable Object attributeValue) {
		getModelMap().addAttribute(attributeName, attributeValue);
		return this;
	}

}

3.<url-pattern>标签拦截规则

web.xml中配置DispatcherServlet前端控制器,并将springMvc.xml配置给DispatcherServlet前端控制器后,需要通过<url-pattern>标签定义拦截规则 <url-pattern>中配置方式

A. / 拦截所有,除了jsp文件

<url-pattern>/</url-pattern>

B. /* 拦截所有,包括jsp文件

<url-pattern>/*</url-pattern>		

C.带后缀

<url-pattern>*.action</url-pattern>

分析:

        为什么配置  /  时,会拦截所有静态文件(静态文件:除servlet、jsp之外的js,css,png等)?

因为tomcat容器中有一个web.xml(父),自己的项目也有一个web.xm(子),是一个继承关系,夫tomcat的web.xml中有一个 DefaultServlet,配置的 url-pattern 是一个 /(如下);而在自己的项目中配置了 / , 相当于覆写了父 web.xml的配置

        为什么不拦截.jsp呢 ? 
因为父web.xml中有一个JspServlet,这个servlet拦截.jsp文件,而我们并没有覆写这个配置,所以springmvc此时不拦截jsp,jsp的处理交给了tomcat

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>
<!-- The mapping for the default servlet -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- The mappings for the JSP servlet -->
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

4. 自定义转换器实现日期类型参数

A. 自定义类实现Converter接口,实现其convert方法 (注意 Converter中需要传两个类型 前一个为源类型,后一个为转换之后的类型即:目标类型)

import org.springframework.core.convert.converter.Converter;


public class StringConvertToDate implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

B.在springMVC配置文件中: 注册自定义转换器 (FormattingConversionServiceFactoryBean

    <bean id="formattingConversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.kay.converter.StringConvertToDate"></bean>
            </set>
        </property>
    </bean>

C. 在springMVC配置文件中 :<mvc:annotation-driven> 中conversion-service属性指向FormattingConversionServiceFactoryBean

 <mvc:annotation-driven conversion-service="formattingConversionServiceFactoryBean"/>

5.springMVC自带针对post请求的编码过滤器 (CharacterEncodingFilter)

在web.xml中增加过滤器

    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

6. springMVC对Restful风格的支持

http get请求 查询资源;user/1 get

http put请求资源 更新;user/1 put

http delete 删除资源 ; user/1 delete

同样的URL地址,根据请求类型不同,操作不同的handler

A.@PathVarible注解 

    @PutMapping("/handle05/{id}")
    public String handle05(@PathVariable("id")String id){}

B. 请求转换过滤器

前期请求类型只有GET 及 POST,Restful风格根据不同的请求,通过GET/PUT/DELETE/POST

进行资源的查询/修改/删除/新增;springMVC提供HiddenHttpMethodFilter过滤器;将特定的post请求转换为putdelete请求

HiddenHttpMethodFilter 

在post请求传入的参数中,增加 参数 _method 其值配置为put则请求类型为PutMapping;其值为delete时请求的类型为DeleteMapping

  <!--配置springmvc请求方式转换过滤器,会检查请求参数中是否有_method参数,如果有就按照指定的请求方式进行转换-->
  <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>
    @PutMapping("/handle/{id}")
    public String handle05(@PathVariable("id")String id) {}

    @DeleteMapping("/handle/{id}")
    public String handle06(@PathVariable("id")String id) {}
<input type="hidden" name="_method" value="put"/>

7. 过滤器、拦截器、监听器

servlet:处理Request请求和Response响应

A.自定义拦截器

1). 自定义类实现HandlerInterceptor,重写对应方法

public class MyInterceptor01  implements HandlerInterceptor {

    /**
     * handler逻辑方法执行之前
     *可用于方法鉴权
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("-------------------- MyInterceptor01 preHandle --------------");
        return true; //return 是否放行, true 放行,false 终止
    }

    /**
     * handler的方法执行之后,但是还没有返回页面
     * 此时可以通过对modelAndView 可以对数据和视图进行修改
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("-------------------- MyInterceptor01 postHandle --------------");
    }

    /**
     * 页面已经渲染完毕
     * 可以在此处做捕获异常的处理
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("-------------------- MyInterceptor01 afterCompletion --------------");
    }
}

2) 在springmvc配置文件中,配置自定义拦截器

 ** 代表拦截当前目录下及其子目录下的所有url

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="myInterceptor01" class="com.kay.interceptor.MyInterceptor01"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

拦截所有还可以配置成以下

<mvc:interceptors>
    <bean id="myInterceptor01" class="com.kay.interceptor.MyInterceptor01"></bean>
</mvc:interceptors>

B.多拦截器执行流程

1)配置文件中注册拦截器的上下顺序即为拦截器顺序

2)preHandle()按照拦截器的配置顺序执行,postHandle()和afterCompletion()则会按照配置顺序的反序执行

8.  Multipart实现文件上传

A.引入文件上传jar依赖(自编写代码编译不需要此jar,但是spring容器在创建multipartResolver时需要,否则会报错)

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

 B.在springmvc配置文件中,注册文件上传解析器,id必须为multipartResolver

<!--    文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--        最大上传大小 in bytes -->
        <property name="maxUploadSize" value="1024000"></property>
<!--        Default is ISO-8859-1, according to the Servlet spec.-->
<!--        <property name="defaultEncoding" value=""></property>-->
    </bean>

C.前端请求传参需要是post、type="file" 并且enctype="multipart/form-data"

<form method="post" enctype="multipart/form-data" action="/demo/upload">
 <input type="file" name="uploadFile"/>
 <input type="submit" value="上传"/>
</form>

 D.Controller中使用 MultipartFile 接受文件信息 且MultipartFile 对应的参数名称必须和type=file的字段名保持一致(此处为 uploadFile)

    @PostMapping("/upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest request) throws IOException {
        String originalFilename = uploadFile.getOriginalFilename(); // 文件原名称
        originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length()); // 获取扩展名 .png

        String upload = request.getSession().getServletContext().getRealPath("upload");
        String dataString = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File folder = new File(upload + "/" + dataString); // /upload/日期 文件夹

        if (!folder.exists()) {
            folder.mkdirs();
        }
        String fileName = UUID.randomUUID().toString();
        uploadFile.transferTo(new File(folder, fileName + originalFilename)); // 将文件从MultipartFile对象中的写入到文件中
        return "success";
    }

9.异常处理机制

异常处理器 HandlerExceptionResolve ,常用的是注解 @ExceptionHandler,结合@ControllerAdvice controller增强注解使用,其配置的异常拦截对所有controller都生效(注意:@ControllerAdvice需要被component-scan扫描到!!)

@ControllerAdvice
public class GlobeExceptionHandler {

    @ExceptionHandler(ArithmeticException.class)
    public void myExceptionHandler(ArithmeticException exception, HttpServletResponse httpServletResponse) {
        try {
            httpServletResponse.getWriter().write("error" + exception.getMessage());
            return;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView myExceptionHandler(Exception exception) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", exception.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

10.重定向参数传递(flash属性)

重定向请求时,浏览器请求URL会改变,参数会丢失,在请求时需要将参数重新拼接传递

@RequestMapping("/testA")
public String testA(String name) {
    return "redirect:testB?name=" + name;
}

 以上方式存在问题:这种get请求的拼接方式,参数的长度有限制,而且安全性也不够高;

springMVC提供了flash属性机制,向上下文中添加flash属性,框架会在session中记录该属性值,当跳转到页面之后框架会自动删除flash属性,不需要我们手动删除

RedirectAttributes   addFlashAttribute  (注意此处使用@ModelAttribute接收)

    @RequestMapping("/testA")
    public String testA(RedirectAttributes redirectAttributes, String name) {
        redirectAttributes.addFlashAttribute("name", name);
        return "redirect:testB";
    }

    @RequestMapping("/testB")
    public String testB(@ModelAttribute("name") String name) {
        return "success";
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值