MVC学习笔记

一、什么是MVC

V 是View (视图),代表与用户交互界面。

M 是Model(模型层),业务流程/状态的处理以及业务规则的制定。模型层接受视图层的请求,并返回最终的处理结果。

C 是Controller(控制层),分发,决定使用哪个模型,返回哪个视图。

二、SpringMVC

相关组件:

       DispatcherServlet  l拦截请求,发送给SpringMVC控制器;

       HandlerMapping映射器,记录url与处理器的映射,方式有注解、xml配置等,DispatcherServlet通过查询HandlerMapping来查询具体的请求对应哪个控制器,然后分发;

      Handler处理器,后端控制器,具体的业务代码,对用户的请求进行处理;

      HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多种类型的处理器。调用处理器响应处理方法,返回一个ModelAndView对象,包含模型数据、逻辑视图名;

      ViewResolver视图解析器将把逻辑视图名称解析为具体的View;

      View根据传过来的Model模型数据进行渲染;

     返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,至此一个流程结束。

web.xml配置示例:

<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:config/spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

     spring-mvc.xml配置示:

<beans>
    <!-- 配置映射处理器:根据bean(自定义Controler)的name属性的url去寻找hanler;springmvc默认的映射处理器是
    BeanNameUrlHandlerMapping
     -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>


    <!-- 配置处理器适配器来执行Controlelr ,springmvc默认的是
    SimpleControllerHandlerAdapter
    -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置自定义Controler -->
    <bean id="myController" name="/hello.do" class="org.controller.MyController"></bean>

    <!-- 配置sprigmvc视图解析器:解析逻辑试图; 
        后台返回逻辑试图:index
        视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/jsps/index.jsp
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsps/"></property>
        <property name="suffix" value=".jsp"></property>        
    </bean>
</beans>

此处配置也可以通过注解实现,在spring-mvc.xml中配置扫描对应控制器的包:

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

controller包下增加对应的controller类代码:

注解时的写法:

@Controller
@RequestMapping("/xxx")
public class XxxController {

xml写法:

public class MyController implements Controller{

    public ModelAndView handleRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {

HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略。

映射处理器有三种,三种可以共存,相互不影响,分别是BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping、ControllerClassNameHandlerMapping;

//默认映射器,即使不配置,默认就使用这个来映射请求。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
//映射器把请求映射到controller
<bean id="testController" name="/hello.do" class="org.controller.TestController"></bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/ss.do">testController</prop>
            
        </props>
    </property>
</bean>
//那么上面的这个映射配置:表示多个*.do文件可以访问多个Controller或者一个Controller。 
//前提是:都必须依赖自定义的控制器bean
<bean id="testController" name="/hello.do" class="org.controller.TestController"></bean>
//这个Mapping一配置:我们就可以使用Contrller的 [类名.do]来访问这个Controller.
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>

处理适配器有SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter,前者是默认的处理器,后者将http请求封装为HttpServletRequest和HttpServletResponse两个对象。

<!-- 配置HttpRequestHandlerAdapter适配器 -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>

代码示例:

public class HttpController implements HttpRequestHandler{

    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //给Request设置值,在页面进行回显
        request.setAttribute("hello", "这是HttpRequestHandler!");
        //跳转页面
        request.getRequestDispatcher("/WEB-INF/jsps/index.jsp").forward(request, response);
    }
}

部分源码:

public interface Controller
{

    public abstract ModelAndView handleRequest(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)
        throws Exception;
}
public interface HandlerAdapter
{

    public abstract boolean supports(Object obj);

    public abstract ModelAndView handle(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object obj)
        throws Exception;

    public abstract long getLastModified(HttpServletRequest httpservletrequest, Object obj);
}
public class SimpleControllerHandlerAdapter
    implements HandlerAdapter
{


    public boolean supports(Object handler)
    {
        return handler instanceof Controller;
    }

    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception
    {
        return ((Controller)handler).handleRequest(request, response);
    }

    public long getLastModified(HttpServletRequest request, Object handler)
    {
        if(handler instanceof LastModified)
            return ((LastModified)handler).getLastModified(request);
        else
            return -1L;
    }
}

从其他地方看来的dispatcher实现:

public class Dispatcher {
    public static List<HandlerAdapter> handlerAdapter = new ArrayList<HandlerAdapter>();

    public Dispatcher(){
        handlerAdapter.add(new SimpleHandlerAdapter());
       
    }

    //核心功能
    public void doDispatch() {
        
        SimpleController handler = new SimpleController();
       
        AnnotationController handler = new AnnotationController();

        //传递给对应的处理器适配器(HandlerAdapter)
        HandlerAdapter handlerAdapter = getHandlerAdapter(handler);

        //处理器适配器调用相应的Handler方法
        handlerAdapter.handle(handler);
    }

    //通过Handler找到对应的处理器适配器(HandlerAdapter)
    public HandlerAdapter getHandlerAdapter(Controller handler) {
        for(HandlerAdapter adapter : handlerAdapter){
            if(adapter.supports(handler)){
                return adapter;
            }
        }
        return null;
    }
}

public class Test {
    public static void main(String[] args) {
        Dispatcher dispather = new Dispatcher();
        dispather.doDispatch();
    }
}

前后端交互时防止乱码,在web.xml中增加过滤器:

<filter>
		<filter-name>encodingFilter</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>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值