SpringMvc4.x-3(基本配置)

静态资源配置:

Spring MVC的定制配置需要我们的配置类继承一个WebMvcConfigurerAdapter类,并在此类使用@EnableWebMvc注解,来开启对Spring MVC的配置支持,这样我们就可以重写这个类的方法,完成我们的常用配置。

我们将前面文章中的MyMvcConfig配置类继承WebMvcConfigurerAdapter,以后如果不做特别说明,则关于配置的相关内容都在MyMvcConfig里面编写。

程序的静态文件(js,css,图片)等需要直接访问,这时我们可以在配置里重写addResourceHandlers方法来实现。

添加静态资源

src/main/resources下建立assets/js目录,并复制一个jquery.js放置在该目录下

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc// ①
@ComponentScan("org.light4j.springMvc4")
public class MyMvcConfig extends WebMvcConfigurerAdapter {// ②

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/classes/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);
        return viewResolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");// ③
    }
}

① @EnableWebMvc开启SpringMvc支持,若无此句,重写WebMvcConfigurerAdapter的方法无效。
② 继承WebMvcConfigurerAdapter类,重写其方法可对Spring MVC进行配置。
③ addResourceLocations指的是文件放置的目录,addResourceHandler指的是对外暴露的访问路径。

拦截器配置

拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似于ServletFilter

可让普通的Bean实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类来实现自定义拦截器。

通过重写WebMvcConfigurerAdapteraddInterceptors方法来注册自定义的拦截器,下面演示一个简单的拦截器的开发和配置。业务含义为计算每一次请求的处理时间。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * ① 继承HandlerInterceptorAdapter类来实现自定义拦截器。
 * ② 重写preHandle方法,在请求发生前执行。
 * ③ 重写postHandle方法,在请求完成后执行。
 *
 */
public class DemoInterceptor extends HandlerInterceptorAdapter {//①

    @Override
    public boolean preHandle(HttpServletRequest request, //②
            HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, //③
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        long startTime = (Long) request.getAttribute("startTime");
        request.removeAttribute("startTime");
        long endTime = System.currentTimeMillis();
        System.out.println("本次请求处理时间为:" + new Long(endTime - startTime)+"ms");
        request.setAttribute("handlingTime", endTime - startTime);
    }
}

 配置:

	/**
	 * ① 配置拦截器的Bean
	 * ② 重写addInterceptors方法,注册拦截器。
	 * @return
	 */
	@Bean // ①
	public DemoInterceptor demoInterceptor() {
		return new DemoInterceptor();
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {// ②
		registry.addInterceptor(demoInterceptor());
	}

@ControllerAdvice注解

通过@ControllerAdvice。我们可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler@InitBinder@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效。

  1. @ExceptionHandler:用于全局处理控制器里面的异常。
  2. @InitBinder:用来设置WebDataBinderWebDataBinder用来自动绑定前台请求参数到Model中。
  3. @ModelAttribute@ModelAttribute本来的作用是绑定键值对到Model里,此处是让全局的@RequestMapping都能获得在此处设置的键值对。

下面将使用@ExceptionHandler处理全局异常,将异常信息更加人性化的输出给用户。

import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice //①
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(value = Exception.class)//②
    public ModelAndView exception(Exception exception, WebRequest request) {
        ModelAndView modelAndView = new ModelAndView("error");// error页面
        modelAndView.addObject("errorMessage", exception.getMessage());
        return modelAndView;
    }

    @ModelAttribute //③
    public void addAttributes(Model model) {
        model.addAttribute("msg", "额外信息"); //④
    }

    @InitBinder //④
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.setDisallowedFields("id"); //⑤
    }
}

① @ControllerAdvice声明一个控制器建言,@ControllerAdvice组合了@Component注解,所以自动注册为Spring的Bean
② @ExceptionHandler在此处定义全局处理,通过@ExceptionHandlervalue属性可过滤拦截的条件,在此处可以看出拦截的是所有的Exception
③ 此处使用@ModelAttribute注解将键值对添加到全局,所有注解了@RequestMapping的方法可获得此键值对。
④ 通过@InitBinder注解定制WebDataBinder

import org.light4j.springMvc4.domain.DemoObj;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class AdviceController {
    @RequestMapping("/advice")
    public String getSomething(@ModelAttribute("msg") String msg,DemoObj obj){//①

        throw new IllegalArgumentException("非常抱歉,参数有误/"+"来自@ModelAttribute:"+ msg);
    }
}

src/main/resources/views下,新建error.jsp,内容如下:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>@ControllerAdvice Demo</title>
</head>
<body>
    ${errorMessage}
</body>
</html>

快捷的ViewController

此处无任何的业务处理,只是简单的页面跳转,写了至少三行有效的代码,在实际的开发中会涉及大量这样的页面转向,若都这样写会特别的麻烦,我们通过在配置类MyMvcConfig里通过重写addViewControllers来简化配置:

@RequestMapping("/index")//②
    public  String hello(){

        return "index";
    }
@Override
public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("/index");
}

路径匹配参数配置

Spring MVC中,路径参数如果带”.”的话,”.”后面的值将被忽略,例如,访问http://localhost/springMvc4.x/anno/pathvar/xxx.yy,此时,”.”后面的yy被忽略;

通过重写configurePathMatch方法可实现不忽略”.”后面的参数,在配置类MyMvcConfig中增加代码如下:

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    configurer.setUseSuffixPatternMatch(false);
}

Spring Mvc更多配置

更多配置请查看WebMvcConfigurerAdater类的API。因其是WebMvcConfigurerAdater接口的实现,所以WebMvcConfigurerAdaterAPI内的方法也可以用来配置MVC。下面列出WebMvcConfigurerAdaterWebMvcConfigurer的源码供参考。

1. WebMvcConfigurerAdater

public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation returns {@code null}
     */
    @Override
    public Validator getValidator() {
        return null;
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public MessageCodesResolver getMessageCodesResolver() {
        return null;
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    }

    /**
     * {@inheritDoc}
     * <p>This implementation is empty.
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }

}

 WebMvcConfigurer

public interface WebMvcConfigurer {

    /**
     * Add {@link Converter}s and {@link Formatter}s in addition to the ones
     * registered by default.
     */
    void addFormatters(FormatterRegistry registry);

    /**
     * Configure the {@link HttpMessageConverter}s to use for reading or writing
     * to the body of the request or response. If no converters are added, a
     * default list of converters is registered.
     * <p><strong>Note</strong> that adding converters to the list, turns off
     * default converter registration. To simply add a converter without impacting
     * default registration, consider using the method
     * {@link #extendMessageConverters(java.util.List)} instead.
     * @param converters initially an empty list of converters
     */
    void configureMessageConverters(List<HttpMessageConverter<?>> converters);

    /**
     * A hook for extending or modifying the list of converters after it has been
     * configured. This may be useful for example to allow default converters to
     * be registered and then insert a custom converter through this method.
     * @param converters the list of configured converters to extend.
     * @since 4.1.3
     */
    void extendMessageConverters(List<HttpMessageConverter<?>> converters);

    /**
     * Provide a custom {@link Validator} instead of the one created by default.
     * The default implementation, assuming JSR-303 is on the classpath, is:
     * {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}.
     * Leave the return value as {@code null} to keep the default.
     */
    Validator getValidator();

    /**
     * Configure content negotiation options.
     */
    void configureContentNegotiation(ContentNegotiationConfigurer configurer);

    /**
     * Configure asynchronous request handling options.
     */
    void configureAsyncSupport(AsyncSupportConfigurer configurer);

    /**
     * Helps with configuring HandlerMappings path matching options such as trailing slash match,
     * suffix registration, path matcher and path helper.
     * Configured path matcher and path helper instances are shared for:
     * <ul>
     * <li>RequestMappings</li>
     * <li>ViewControllerMappings</li>
     * <li>ResourcesMappings</li>
     * </ul>
     * @since 4.0.3
     */
    void configurePathMatch(PathMatchConfigurer configurer);

    /**
     * Add resolvers to support custom controller method argument types.
     * <p>This does not override the built-in support for resolving handler
     * method arguments. To customize the built-in support for argument
     * resolution, configure {@link RequestMappingHandlerAdapter} directly.
     * @param argumentResolvers initially an empty list
     */
    void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);

    /**
     * Add handlers to support custom controller method return value types.
     * <p>Using this option does not override the built-in support for handling
     * return values. To customize the built-in support for handling return
     * values, configure RequestMappingHandlerAdapter directly.
     * @param returnValueHandlers initially an empty list
     */
    void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers);

    /**
     * Configure the {@link HandlerExceptionResolver}s to handle unresolved
     * controller exceptions. If no resolvers are added to the list, default
     * exception resolvers are added instead.
     * @param exceptionResolvers initially an empty list
     */
    void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);

    /**
     * Add Spring MVC lifecycle interceptors for pre- and post-processing of
     * controller method invocations. Interceptors can be registered to apply
     * to all requests or be limited to a subset of URL patterns.
     * <p><strong>Note</strong> that interceptors registered here only apply to
     * controllers and not to resource handler requests. To intercept requests for
     * static resources either declare a
     * {@link org.springframework.web.servlet.handler.MappedInterceptor MappedInterceptor}
     * bean or switch to advanced configuration mode by extending
     * {@link org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
     * WebMvcConfigurationSupport} and then override {@code resourceHandlerMapping}.
     */
    void addInterceptors(InterceptorRegistry registry);

    /**
     * Provide a custom {@link MessageCodesResolver} for building message codes
     * from data binding and validation error codes. Leave the return value as
     * {@code null} to keep the default.
     */
    MessageCodesResolver getMessageCodesResolver();

    /**
     * Configure simple automated controllers pre-configured with the response
     * status code and/or a view to render the response body. This is useful in
     * cases where there is no need for custom controller logic -- e.g. render a
     * home page, perform simple site URL redirects, return a 404 status with
     * HTML content, a 204 with no content, and more.
     */
    void addViewControllers(ViewControllerRegistry registry);

    /**
     * Configure view resolvers to translate String-based view names returned from
     * controllers into concrete {@link org.springframework.web.servlet.View}
     * implementations to perform rendering with.
     */
    void configureViewResolvers(ViewResolverRegistry registry);

    /**
     * Add handlers to serve static resources such as images, js, and, css
     * files from specific locations under web application root, the classpath,
     * and others.
     */
    void addResourceHandlers(ResourceHandlerRegistry registry);

    /**
     * Configure a handler to delegate unhandled requests by forwarding to the
     * Servlet container's "default" servlet. A common use case for this is when
     * the {@link DispatcherServlet} is mapped to "/" thus overriding the
     * Servlet container's default handling of static resources.
     */
    void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);

}

猜你喜欢

转载自blog.csdn.net/qq_15140841/article/details/81771951
今日推荐