当前位置: 首页>前端>正文

springmvc使用笔记

1、springmvc三大组件:HandlerMapping,HandlerAdaptor、ViewResolver
在springmvc.xml中添加如下配置:

<!-- 定义JSP视图解析器-->  
<!--根据项目使用的模板引擎,视图解析器可以配置多个,比如jsp,freemaker-->
<bean id="jspViewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/"></property>
    <property name="suffix" value=".jsp"></property>
    <property name="order" value="1" />
</bean>
<!-- 开启基mvc的自动配置,自动注册合适的HandlerMapping和HanlerAdaptor-->
<mvc:annotation-driver>

2、拦截路径区分:
在tomcat的web.xml文件中默认配置了两个serverlet

 <!-- 默认配置的servlet,当没有servlet处理请求时,使用这个,返回404 -->
 <!--tomcat中配置的默认servlet优先级低于mvc中配置的,
如果在mvc中配置 / ,会覆盖这个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>
/ 拦截动态请求和静态资源,但是不拦截 .jsp
/* 拦截所有请求的所有文件夹,但是 【不拦截静态资源】、也拦截.jsp
/** 拦截所有请求的所有文件夹和子文件夹,不拦截静态资源,拦截.jsp
jsp请求被拦截后,controller返回的jsp页面会再次发请求到服务器,
请求的url是:jsp页面所在相对路径,比如:/WEB-INF/pages/index.jsp

3、拦截静态资源解决方案

方案一:
      tips:静态资源必须放在webapp的根目录下,否则无效 
    <mvc:default-servlet-handler/>
方案二:
    mapping:约定的静态资源的url规则
    location:约定的静态资源的存放位置
<mvc:resource location="classpath:/" mapping="resources/**">

4、日期类型转换:实现Converter接口 来自定义类型转换器

/**
 * Description:自定义日期类型转换器
 *
 * @author:53493
 * @date 2022/12/31 21:43
 */
public class DataConvertor implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = format.parse(source);
            return date;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

在springmvc的配置文件中注册自定义converter

<bean id="conversionServiceBean" class="com/lagou/springboot_01_demo/DataConvertor.java:21">
  <properties>
      <set>
           <bean class = "com.abc.springboot_01_demo.DataConvertor"></bean>
      </set>
  </properties>
</bean>
<!--关联到HandlerAdaptor上-->
<mvc:annotation-driven conversion-service="conversionServiceBean">

5、HandlerMapping

HandlerMapping:处理请求和hanlder之间的映射关系,根据url路径,找到对应的handler,返回的是**HandlerExecutionChain**
HandlerIntercetor

6、HandlerAdaptor

解析参数
查找controller
返回处理结果,包括参数绑定

7、form表单中 method只能写post和get,如果要发送put请求,需要特殊处理,如下:

1、在<form>表单中添加隐藏域标签
name:固定值(_method)
value:要发送的请求类型
<input type="hidden" name="_method" value="put">
2、在web.xml中添加过滤器
<!--  配置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>

8、post请求中中文参数乱码
方案:使用filter(拦截器可以很好的解决乱码问题)
springmvc提供了编码过滤器,在web.xml中添加配置

<!--  springmvc提供的针对post请求的编解码过滤器-->
<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>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

get请求乱码,需要在tomcat下的server.xml添加配置

<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

9、filter和HandlerInterceptor的区别

Filter定义在web.xml中,在servlet前后起作用
HandlerInterceptor定义在在mvc的配置文件中,在handler前后起作用

10、配置多个静态资源目录

1、在mvc配置文件中配置
2、页面上的<script> 标签会发送请求到服务器,其中的src属性也需要根据以下的路径进行映射
<mvc:resource location="WEB-INF/js" mapping="/js/**">

11、参数绑定

参数绑定:取数参数值,赋值给handler的形参
1、springmvc对原生servlet的api的支持,比如HttpServletRequest/HttpServletResponse/HttpSession
   直接在handler方法的形参中直接声明使用即可
2、springmvc接收简单数据类型(八种基本数据类型及包装类)
    直接在handler方法的形参中声明即可
            要求:传递的参数名和声明的参数名一致,
                 当不一致的时候,使用@RequestParam("xx") 指定
tips:推荐使用包装数据类型,避免出现参数为null时出现报错
          对于Boolean类型,只接受4个值:true,false,0,1
3、接收pojo类型参数,直接形参声明即可,类型就是pojo的类型
      但要求传的参数名必须和pojo的属性名保持一致
4、pojo包装类型(属性是一个pojo类型)
        1)绑定时直接形参声明即可
        2)传参参数名和pojo属性保持一致,可以通过 属性名+"." 的方式进一步绑定数据

12、ajax交互和@RequestBoby

交互:两个方向
1)前端到后台:前端ajax发送json格式字符串,后台直接接收为pojo参数,使用@RequestBoby,标注到方法的形参上。
   注意:@RequestBody取的时body请求体中的数据,get方式请求无法使用这个注解来【绑定参数】
2)后台到前端:后台直接返回pojo对象,前端接收为【json对象】或字符串,使用直接@ResponseBody,
标注到方法上,或 【返回值前面】
注意:添加@ResponseBody之后,不再走视图解析器的那个流程,
          而是等同于servlet原生的response对象直接输出数据

13、拦截器(Inteceptor)、监听器(Listener)、过滤器(Filter)

一、Filter(web.xml中):对request请求起到过滤的作用,作用在servlet之前,
如果配置为 【/ *】可以对所有资源访问(servlet,js/css静态资源等)过滤

二、Listener(web.xml中):实现了javax.servlet.servletContextListener接口的组件,
它随着web应用的启动而启动,只初始化一次,然后会一直运行监视,随web应用的停止而销毁。
作用一:做一些初始化工作,web应用中spring容器启动的ContextLoaderListener
作用二:监听web中特定的事件HttpSession,ServletRequest的创建和销毁;变量的创建、销毁、
修改等,可以在动作前后增加处理,比如:统计在线人数,HttpSessionListener等。

    ------------- 以上两个组件是j2ee的组件,配置在web.xml中-----------

三、Interceptor:是mvc表现层自己的框架,不会拦截静态资源,只会拦截handler方法。
  可以拦截三处:
        1)在handler业务执行前拦截一次
        2)在handler业务执行完毕但是未跳转页面之前拦截一次
        3)在跳转页面之后拦截一次

request---->filter--->interceptor(handler执行之前拦截一次)
--->controller--->interceptor(handler执行之后拦截一次)
---->视图渲染(经过DispatcherServlet中转)--->interceptor(跳转页面之后拦截一次,可以修改modelAndView的数据)
-->response

           *****三次拦截在一个interceptor实现类中******
拦截器可以有多个,对一个请求进行多次拦截。

四、自定义拦截器:
      1)实现HandlerInterceptor接口,重写里面的方法
      2)在mvc的配置文件中添加配置
      <mvc:interceptors>
        <mvc:interceptor>
            <!--**代表当前目录及子目录下的所有url-->
            <mvc:mapping path="/**"/>
              <!--在mapping的基础上,需要排除的url-->
                        <mvc:exclude-mapping path="/demo/**">
            <bean class="xxx.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

五、多个拦截器的拦截顺序
        interceptor1(preHandler)--->interceptor2(pre)
                      --->handler
            --->i2(post)--->i1(post) 
                          -->DispatcherServlet(render)
             -->i2(afterCompletion)--->i1(afterCompletion)      

-----------------进 和 出,顺序相反--------------             

14、处理multipart形式的数据(文件上传)

      1) 引入需要的jar包
       <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
      2)客户端
          1、form表单
          2、method=post
          3、enctype=multipart/form-data
          4、action=handler路径
          4、file组件
              <input type="file" name="uploadFile" />
      3)服务端
          1、重命名(给一个唯一的名字)
          2、存储到磁盘(考虑同一个目录文件太多,可以按照日期创建文件夹)
          3、把文件存储路径更新到数据库
      4)在springmvc配置文件中添加【文件上传解析器】
<bean id="multipartResolver" 
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!---设置属性值,单位是字节,-1代表没有限制,默认就是-1-->
  <property name="maxUploadSize" value="500000"></property>
</bean>

代码如下:

/**
     * 上传文件
     * @param uploadFile 必须和form表单中的<input type=”file“ name="uploadFile">的name相同
     * @return
     */
    @RequestMapping("/upload")
    public ModelAndView upload(MultipartFile uploadFile, HttpSession session) throws IOException {
        // 原始名称
        String originalFilename = uploadFile.getOriginalFilename();
        String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length());
        String newName = UUID.randomUUID().toString() + "." + ext;
        // 存储,到指定的文件夹(当前项目的目录,或者共享盘,通过nginx配置访问路径)
        // 得到项目下的uploads文件的磁盘路径,这里的/指的是webapp根目录
        String realPath = session.getServletContext().getRealPath("/uploads");
        String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File folder = new File(realPath + "/" + datePath);
        if(!folder.exists()){
            folder.mkdir();
        }
        uploadFile.transferTo(new File(folder,newName));
        // TODO
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("date",new Date());
        modelAndView.setViewName("success");
        return modelAndView;
    }

15、springmvc的异常处理机制

一、设置全局异常处理(定义异常处理类)
@ControllerAdvice
public class GlobalExceptionResolver {
    // 针对ArithmeticException异常类型
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView handlerExcption(ArithmeticException exception, HttpServletResponse response){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg",exception.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

二、针对某一个controller类进行异常处理
        在这个controller类中编写异常处理方法(和上面一样的逻辑)
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView handlerExcption(ArithmeticException exception, HttpServletResponse response){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg",exception.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }

16、springmvc 重定向参数传递问题

一、转发和重定向
  转发:A找B,B找C然后B返回A(B的个人行为)
        url不会变,参数也不会丢失,一个请求
  重定向:A找B,B指向C,A找C
        url会变,参数会丢失,两个请求

二、传递参数的方案:在方法上添加RedirectArrtibutes类型的参数

代码如下:

@RequestMapping("/handlerRedirect")
    public String handlerRedirect(String name,RedirectAttributes redirectAttributes){
        // andFlashArrtibute方法设置了一个false类型属性,该属性会被暂存到session中,
        // 在跳转到页面之后该属性销毁
        // 也可以自己放到session中,但是跳转之后需要自己来销毁
        redirectAttributes.addFlashAttribute("name",name);
        return "redirect:handler01";
        // 方案一:拼接参数,安全性和参数长度受限
//      return "redirect:handler01?name="+name;
    }
    @RequestMapping("/handler01")
    public void handler01(String name,ModelAndView modelAndView){
        // TODO
        modelAndView.setViewName("success");
    }

https://www.xamrdz.com/web/2nu1995596.html

相关文章: