黑马程序员技术交流社区

标题: 【石家庄校区】Spring MVC 笔记 [打印本页]

作者: cyahua    时间: 2018-8-17 11:32
标题: 【石家庄校区】Spring MVC 笔记
本帖最后由 cyahua 于 2018-8-17 11:58 编辑

Spring MVC 笔记
Spring MVC处理流程组件说明问题:Spring MVC三大组件有哪些?
在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。
需要用户开发的组件有handler 和view

Spring MVC基础配置
[XML] 纯文本查看 复制代码
<!-- 扫描controller注解,多个包中间使用半角逗号分隔 -->
    <context:component-scan base-package="cn.itcast.springmvc.controller"/>


注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method。
从spring3.1版本开始,废除了DefaultAnnotationHandlerMapping的使用,推荐使用RequestMappingHandlerMapping完成注解式处理器映射。
[XML] 纯文本查看 复制代码
<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

注解式处理器适配器,对标记@ResquestMapping的方法进行适配
从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。
[XML] 纯文本查看 复制代码
<!--注解适配器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<mvc:annotation-driven>

springmvc使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。

配置前缀和后缀
[XML] 纯文本查看 复制代码
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
              value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

InternalResourceViewResolver:支持JSP视图解析
viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,所以classpath中必须包含jstl的相关jar 包。此属性可以不设置,默认为JstlView。
prefix 和suffix:查找视图页面的前缀和后缀,最终视图的址为:
前缀+逻辑视图名+后缀,逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为hello,则最终返回的jsp视图地址 “WEB-INF/jsp/hello.jsp”

SSM整合整合思路配置文件
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

  
[XML] 纯文本查看 复制代码
</configuration><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/s ... ing-context-4.0.xsd">
    <!--加载配置文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--数据库连接池-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:SqlMapConfig.xml"/>
    </bean>
    <!--扫描Mapper-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.itheima.springmvc.mapper"/>
    </bean>
</beans>

[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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--包扫描-->
    <context:component-scan base-package="com.itheima.springmvc.service"/>
    <!-- 事务管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 传播行为 -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- 切面 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice"
                     pointcut="execution(* com.itheima.springmvc.service.*.*(..))" />
    </aop:config>
</beans>

[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/s ... ing-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 扫描带Controller注解的类 -->
    <context:component-scan base-package="com.itheima.springmvc.controller"/>
    <!-- 加载注解驱动 -->
    <!--<mvc:annotation-driven conversion-service="conversionService"/>-->
    <mvc:annotation-driven />
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView"/>
        <!-- jsp前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- jsp后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--日期转换器-->
<!--如果在类中加上@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss"),就不用再配置-->   
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.itheima.springmvc.converter.DateConverter"/>
            </set>
        </property>
    </bean>

    <!--异常处理器-->
    <bean class="com.itheima.springmvc.exceptionresolver.CustomerExceptionResolver"/>
    <!--多媒体解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--最大上传问价1M-->
        <property name="maxUploadSize" value="1048576"/>
    </bean>
    <!--资源映射-->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
</beans>

参数绑定
支持的数据类型
解决乱码
post乱码
web.xml中配置filter
[XML] 纯文本查看 复制代码
<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>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
get乱码
方法1
修改tomcat配置文件添加编码与工程编码一致,如下:
[XML] 纯文本查看 复制代码
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
方法2
[Java] 纯文本查看 复制代码
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8");
自定义Converter
继承Converter接口
[Java] 纯文本查看 复制代码
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

配置converter
[XML] 纯文本查看 复制代码
<!-- 转换器配置 -->
<bean id="conversionService"
      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="cn.itcast.springmvc.convert.DateConverter"/>
        </set>
    </property>
</bean>

springmvc与struts2区别相关注解
@RequestMapping
@RequestParam当前台参数与接收名称不一致时使用
@RequestBody
@ResponseBody
@PathVariable
jsp中<c:forEach>标签的varStatus属性
varStatus属性常用参数总结下:
${status.index}      输出行号,从0开始。
${status.count}      输出行号,从1开始。
${status.current}   当前这次迭代的(集合中的)项
${status.first}  判断当前项是否为集合中的第一项,返回值为true或false
${status.last}   判断当前项是否为集合中的最后一项,返回值为true或false
begin、end、step分别表示:起始序号,结束序号,跳跃步伐。
Controller中方法的返回值重定向和转发区别全局异常处理器
自定义异常类
[Java] 纯文本查看 复制代码
public class CustomException extends Exception {

    /** serialVersionUID*/
    private static final long serialVersionUID = -5212079010855161498L;
   
    public CustomException(String message){
        super(message);
        this.message = message;
    }

    //异常信息
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

自定义全局异常处理器
[Java] 纯文本查看 复制代码
public class CustomerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handle, Exception e) {
        String message = null;
        ModelAndView modelAndView = new ModelAndView();
        if (e instanceof CustomerException) {
            CustomerException customerException = (CustomerException) e;
            message = customerException.getMessage();
        } else {
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            e.printStackTrace(printWriter);
            message = stringWriter.toString();
        }
        modelAndView.addObject("message", message);
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

编写错误页面
[HTML] 纯文本查看 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>错误页面</title>
</head>
<body>
您的操作出现错误如下:<br/>
${message }
</body>
</html>

配置异常处理器
[XML] 纯文本查看 复制代码
<!-- 异常处理器 -->
<bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>
上传图片
配置解析器
[XML] 纯文本查看 复制代码
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为5MB -->
    <property name="maxUploadSize">
        <value>5242880</value>
    </property>
</bean>

Controller
[Java] 纯文本查看 复制代码
@RequestMapping("/updateitem.action")
public String itemUpdate(Items items, MultipartFile pictureFile,Model model) throws IOException {
    if (pictureFile != null) {
        String originalFilename = pictureFile.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = UUID.randomUUID().toString()+suffix;
        File file = new File("D:/tmp/pic");
        if(!file.exists()){
            file.mkdirs();
        }
        pictureFile.transferTo(new File(file,fileName));
        model.addAttribute("id", items.getId());
        items.setPic(fileName);
    }
    itermsService.updateItems(items);
    return "redirect:itemEdit.action";
}

前台页面
[HTML] 纯文本查看 复制代码
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" enctype="multipart/form-data" method="post">
    <tr>
        <td>商品图片</td>
        <td>
            <c:if test="${item.pic !=null}">
                <img src="/pic/${item.pic}" width=100 height=100/>
                <br/>
            </c:if>
            <input type="file"  name="pictureFile"/>
        </td>
    </tr>
</form>
Json交互
406错误:没有导入json的jar包
@RestController相当于在类上添加@Controller和@ResponseBody
@RequestBody
@ResponseBody
配置json转换器
[XML] 纯文本查看 复制代码
<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
        </list>
    </property>
</bean>

注意:如果使用<mvc:annotation-driven /> 则不用配置上边的内容
REstfull支持
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。Put和Delete几乎不使用。
配置DispatcherServlet拦截路径
[XML] 纯文本查看 复制代码
<servlet>
    <servlet-name>springmvc-servlet-rest</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/springmvc.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc-servlet-rest</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

springMVC的url-pattern中的路径写法含义:
/ 表示拦截除.jsp和.jspx外的所有请求,  /*  表示拦截所有请求
/ 不拦截.jsp和.jspx的原因:
%tomcat%\conf\web.xml中有如下配置:
[XML] 纯文本查看 复制代码
<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>

<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

Controller中注解的写法
[Java] 纯文本查看 复制代码
@RequestMapping("/viewItems/{id}") 
    public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
        //方法中使用@PathVariable获取useried的值,使用model传回页面
        //调用 service查询商品信息
        ItemsCustom itemsCustom = itemsService.findItemsById(id);
        return itemsCustom;
}

如何传递多个参数?
路径的写法:"/viewItems/{id}/name/{name}"
配置资源映射
由于Restfull风格的url-pattern拦截了所有的路径,所以要配置资源映射
[XML] 纯文本查看 复制代码
<!--在srping-mvc.xml中配置-->
<!--  /** 表示包含子目录 -->
<mvc:resources location="/js/" mapping="/js/**"/>

拦截器
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
intercepter执行顺序
按照配置文件中的配置顺序执行
preHandle方法按照配置文件中的顺序执行
postHandle和afterCompletion按照倒序执行
postHandler在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用
如果转发到的是系统内部的方法,拦截器会拦截,如果到的是视图,不会拦截
编写自定义Interceptor,实现HandlerInterceptor接口
[Java] 纯文本查看 复制代码
public class UserLoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("拦截执行");
        String url = httpServletRequest.getRequestURL().toString();
        if(url.contains("login")){
            return true;
        }
        Object user = httpServletRequest.getSession().getAttribute("user");
        if(user !=null){
            return true;
        }
        httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(httpServletRequest,httpServletResponse);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
mvc配置文件
[XML] 纯文本查看 复制代码
<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.itheima.springmvc.interceptor.UserLoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>










欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2