springmvc controller

资料参考:https://mp.weixin.qq.com/s?__biz=Mzg2NTAzMTExNg==&mid=2247483993&idx=1&sn=abdd687e0f360107be0208946a7afc1d&scene=19#wechat_redirect


控制器Controller

  1. 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
  2. 控制器负责解析用户的请求并将其转换为一个模型。
  3. 在Spring MVC中一个控制器类可以包含多个方法
  4. 在Spring MVC中,对于Controller的配置方式有很多种

在开发中我们一般使用注解方式进行开发

Controller接口

@FunctionalInterface
public interface Controller {

	/**
	 * Process the request and return a ModelAndView object which the DispatcherServlet
	 * will render. A {@code null} return value is not an error: it indicates that
	 * this object completed request processing itself and that there is therefore no
	 * ModelAndView to render.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @return a ModelAndView to render, or {@code null} if handled directly
	 * @throws Exception in case of errors
	 */
	@Nullable
	ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}

主要是看一下这里的注释,是处理请求并返回一个ModelAndView对象,DispatcherServlet将渲染该对象。 一个null的返回值并不是一个错误:它表示这个对象自己完成了请求处理,没有ModelAndView可以渲染。

在AbstractController类中实现了Controller类,handleRequest实现如下

	@Override
	@Nullable
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		if (HttpMethod.OPTIONS.matches(request.getMethod())) {
			response.setHeader("Allow", getAllowHeader());
			return null;
		}

		// Delegate to WebContentGenerator for checking and preparing.
		checkRequest(request);
		prepareResponse(response);

		// Execute handleRequestInternal in synchronized block if required.
		if (this.synchronizeOnSession) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				Object mutex = WebUtils.getSessionMutex(session);
				synchronized (mutex) {
					return handleRequestInternal(request, response);
				}
			}
		}

		return handleRequestInternal(request, response);
	}

过程可以大致看一下,首先是设置header的allow,允许资源可以用哪些HTTP方法进行请求,比如Allow: GET, HEAD,Allow:*,接着委托给WebContentGenerator进行检查和准备,然后如果需要,在同步块中执行handleRequestInternal,否则直接执行handleRequestInternal方法。

handleRequestInternal方法的实现

	/**
	 * Retrieves the URL path to use for lookup and delegates to
	 * {@link #getViewNameForRequest}. Also adds the content of
	 * {@link RequestContextUtils#getInputFlashMap} to the model.
	 */
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
		String viewName = getViewNameForRequest(request);
		if (logger.isTraceEnabled()) {
			logger.trace("Returning view name '" + viewName + "'");
		}
		return new ModelAndView(viewName, RequestContextUtils.getInputFlashMap(request));
	}

getViewNameForRequest获取视图的名字,再进行logger.trace,最后创建ModelAndView对象返回。

但是在真正用的时候我们是只重写handleRequest,封装Model,返回ModelAndView就行了。

public class HelloController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();
        //封装对象,放在ModelAndView中。Model
        mv.addObject("msg","HelloSpringMVC!");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

说明:

  1. 实现接口Controller定义控制器是较老的办法
  2. 缺点:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;(网站开发随便就是几十个接口,创建几十个类是不能接受的)

Controller注解

@Controller注解类型用于声明Spring类的实例是一个控制器(被spring接管,注解@Contronller的类下面的所有的String方法,返回值都会被视图解析器解析,如果可以跳转就跳转),Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。<context:component-scan base-package="com.kuang.controller"/>

Controller注解的定义,很简单里面用的就就一个value

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

注解本质就只是一个接口,程序处理的难点是在反射,而框架把这些处理内容隐藏起来了,除非阅读源码很难接触到。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值