SpringMVC实战(二)——常见配置

该文章基于《Spring+MyBatis企业应用实战》进行总结,旨在积累巩固

DispatcherServlet

该类主要用于调度控制,所有的请求驱动都围绕着这个DispatcherServlet来分派请求,可以将DispatcherServlet理解为特殊的控制器,该类的配置一般在web.xml文件中,常见配置信息如下:

<!--web.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <servlet-name><!--Servlet名称--></servlet-name>
        <servlet-class>
            <!--一般为org.springframework.web.servlet.DispatcherServlet-->
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                <!--包含springmvc-config.xml的配置路径,以web路径为根节点-->
            </param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name><!--Servlet名称--></servlet-name>
        <url-pattern>
            <!--你想要监听的路径,如果该值为'/',那么将会监听所有请求-->
        </url-pattern>
    </servlet-mapping>
</web-app>

Dispatcher会查找配置路径下对应的配置文件,然后基于ServletContext实例初始化WebApplicationContext,具体的源码分析可以查看我之前的博客SpringMVC源码分析

Controller(控制器)

非注解方式

Controller本身应该是需要实现org.springframework.web.servlet.mvc.Controller接口的ModelAndView handleRequest(HttpServletRequest,HttpServletResponse)方法,我们在谈到DispatcherServlet时也谈到了contextConfigLocation属性用于指定搜索servlet名称-config.xml文件,故Controller的配置就应该位于此xml文件中,以达到模块化开发的目的
一下为常见的配置文件格式:

<!--servlet名称-config.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans">
    <bean name= "需要处理的请求的映射,例如'/test'"
        class="Controller接口的实现类的位置"/>
</beans>

其中Spring会自动初始化三个其他的bean,包括BeanNameUrlHandlerMapping用于将bean的名称映射到请求,SimpleControllerHandlerAdapter用于完成对Controller类的handleRequest方法的调用,可以从名字看出这个类的设计是适配器InternalResourceViewResolver来解析适配器。注意如果Spring版本在4.0之前,那么需要显式地声明这几个bean。
如果出现无法加载lib中jar包的情况,将lib放在/web/WEB-INF/目录之下

注解方式

通过@Controller代替实现Controller接口,通过@RequestMapping代替通过beanname指定请求路径,通过注解方式配置的Controller的[servlet]-config文件与通过实现接口的配置文件有不同:下面是典型的xml配置文件:

<!--[servlet]-config.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"
       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">
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

    <context:component-scan base-package="controller"/>
</beans>

最主要的就是这一项配置了,与通过非注释方法配置的Controller相对应的是,这种情况下Spring会自动加载三个bean——RequestMappingHandlerMapping(查找对应的映射)、RequestMappingHandlerAdapter(用来完成对@RequestMapping标注方法的调用)、与注释方法相同的InternalResourceViewResolver(解析视图)

InternalResourceViewResolver

该类可以通过指定它的prefix和suffix属性,返回指定路径下的页面
例如:

<!--[servletname]-config.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"
       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">
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

    <context:component-scan base-package="controller"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/view/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

所有controller返回的ModelAndView的视图名称都会加上/WEB-INF/view/前缀和.jsp后缀

@RequestMapping

用于映射请求的URL,可以为类级别或者方法级别,常见属性有value、method、params(用于处理包含指定参数的请求)、headers(用于处理包含指定Referer的请求)该注解注解的方法参数类型不唯一、返回类型也不唯一,参数类型很多在此不赘述,下面主要谈一下返回类型中最重要的几个返回参数的类型:
(1)Model通过返回String指定返回的view对参数操作需要通过调用asMap方法
(2)ModelMap通过返回String指定返回的view可以直接通过addAttribute添加参数
(3)ModelAndView通过setViewName指定返回的View通过addObject添加参数
(4)@ModelAttribute
(5)@SessionAttributes

参数绑定注解

处理request body部分的注解:@RequestParam@RequestBody
处理request uri部分的注解:@PathVariable
处理request header部分的注解:@RequestHeader@CookieValue
处理attribute类型的注解:@SessionAttributes@ModelAttribute
处理response类型的注解:@ResponseBody
一下按照顺序进行总结:

@RequestParam

用于将请求参数映射到方法参数中,主要用于名称的转化

@RequestBody

可以用于将JSON格式的输入转化为指定的domain,故为参数层面注解

@PathVariable

@PathVariable通过与@RequestMapping进行配合,可以将请求中的URL参数绑定到方法参数中,如下所示:

@RequestMapping(value="/path/{param}")
public void pathVariableTest(@PathVaraiable String param)

@RequestHeader

实际作用同@PathVariable相同,但是这里映射的是映射头的值,而不是URL的动态参数

@CookieValue

用于将Cookie中的值映射到参数中,可以设置default属性

@SessionAttributes

只能用于类声明,而不能用在方法,用于有选择的指定Model中哪些属性:1.需要将ModelXXX中转存到HttpSession对象中2.通过names指定,或者通过types属性指定(不能通过父类指定)

@ModelAttribute

该注解可以用于①方法,②参数,@ModelAttribute修饰的方法会先于@RequestMapping的方法调用 / 或者Controller方法,用于前置的参数处理,注释的方法的参数名称默认和传入的参数名称对应,否则可以通过@RequestParam进行注解,如果被注释的方法返回具体值,可以通过指定key直接将该返回值作为value加入Model中,需要注意,如果@ModelAttribute与@RequestMapping同时注释一个方法,那么该方法实际只会调用一次,通过代码解释:

@ModelAttribute("mapkey")
@RequestMapping("/index")
public String handleRequest() throws Exception {
    System.out.println("invoke");
    return "mapvalue";
}

当有/index的请求时上面的代码只会被调用一次,并且会返回至@RequestMapping的属性值指定的页面中,而Model属性中会添加“mapkey” → “mapvalue”私以为这是SpringMVC设计时的错误,因为在这种状态下,本来应该被执行两次的方法实际上只被执行了一次当注释在参数上时与之前谈到的放入不同,参数上的@ModelAttribute实际是从Model模型中取出值,或者由请求参数构造实例

@ModelAttribute获得的值实际上是放在ModelMap中

@ResponseBody

用于将输出的参数转化为JSON,故为方法层面注解
处理不同ContentType分为一下几种情况:

ContentType@RequestBody@ModelAttribute@RequestParam
application/x-www-form-urlencoded
multipart/form-data×??
application/json、application/xml××

信息转换

HttpMessageConverter<T>

HttpMessageConverter<T>是Spring3.0之后新增的接口,负责将请求信息转化为一个对象、或者将对象转化为相应信息,由HandlerAdapter的实现类RequestMappingHandlerAdapter进行使用:
这里写图片描述
可以看到其中默认加载了几个实例,其他的实例需要通过显示添加才行。
转换JSON数据的HttpMessageConverter→MappingJackson2HttpMessageConverter

<mvc:annotation-driven/>

在[servletname]-config.xml进行注册,用于自动注册RequestMappingHandlerMappingRequestMappingHandlerAdapter在这里记录一件非常操蛋的事情,就是不要重复的注册RequestMappingHandlerXXX与<mvc:annotation-driven/>,这样会引起错误,如果不想使用默认的转换器,需要在配置文件中重写,代码如下所示:

<mvc:annotation-driven>
        <!-- 设置不使用默认的消息转换器 -->
        <mvc:message-converters register-defaults="false">
            <!-- 配置Spring的转换器 -->
            <bean class="XXX"/>
            <!-- 配置fastjson中实现HttpMessageConverter接口的转换器 -->
            <bean id="fastJsonHttpMessageConverter" 
                class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <!-- 加入支持的媒体类型:返回contentType -->
                <property name="supportedMediaTypes">
                    <list>
                        <!-- 这里顺序不能反,一定先写text/html,不然ie下会出现下载提示 -->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

<mvc:default-servlet-handler/>

在[servletname]-config.xml进行注册,用于使用默认的servlet响应静态文件,一般用于js文件引用的问题,最好不要将js、css文件放入WEB-INF目录中

@InitBinder

该注解用于判断输入是否正确,并且是方法层面的注解,可以和自带标签库中的errors标签进行配合

@InitBinder//在@Controller类中定义
public void initBinder(DataBinder binder){
    binder.setValidator(new XXXValidator());
}
public class XXXValidator implements Validator{
    public boolean supports(Class<?> clazz){
        return XXX.class.equals(clazz);
    }
    public void validate(Object object, Errors errors){
        ValidationUtils.rejectIfEmpty(errors,"属性名",null,"错误信息");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值