springmvc基础学习

pom.xml文件

一、简单控制器

创建一个index.jsp文件在src/main/resources/views下。

/**
 * springmvc配置
 * @author think
 */
@Configuration
@EnableWebMvc
@ComponentScan("com")
public class MyMvcConfig {
    @Bean
    public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/classes/views/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }
}

/**
 * web配置
 * @author think
 */
public class WebInitializer implements WebApplicationInitializer{
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MyMvcConfig.class);
        context.setServletContext(servletContext);//与配置类关联
        Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));//注册springmvc的DispatcherServlet
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}

/**
 * 简单的一个控制器
 * @author think
 */
@Controller
public class ControllerTest {
    @RequestMapping("/index")//配制方法与url的映射
    public String hello(){
        return "index";
    }
}

WebApplicationInitializer是spring提供用来配置servlet3.0的接口,从而替代web.xml,
此接口会自动SpringServletContainerInitializer(用来启动serlvet3.0容器)获取到。

二、springmvc常用注解

1、@Controller声明是一个控制器,dispatcherservlet会自动扫描此注解的类,并将web讲求映射到有@RequestMapping的方法上。
2、在声明普通bean时,使用@Component、@Service、@Repository、@Controller是等同的,但是在作为springmvc的控制器bean时,只能使用@Controller。
3、@RequestMapping用来映射web请求、处理类和方法的,支持servlet的request和response作为参数,也支持对request和response的媒体类型进行配置。
4、@ResponseBody支持将返回值放在response体内,而不是返回一个页面,在很多基于ajax的程序时,可以用此注解返回数据,而不是页面。
5、@RequestBody允许参数再request体内,而不是在地址后面
6、@PathVariable用来接收路径参数,如/news/001,可以接收001作文参数
7、@RestController是组合注解,组合了@Controller和@ResponseBody

简单使用:

/**
 * 实体类
 * @author think
 */
public class Obj {
    private Long id;
    private String name;
    public Obj() {//对象转换json时候需要此空参构造
        super();
    }
    public Obj(Long id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Obj [id=" + id + ", name=" + name + "]";
    }
}

/**
 * 参数转化
 * @author think
 */
@Controller
@RequestMapping("/obj")//映射此类的访问路径是/obj
public class ObjController {
    @RequestMapping(produces = "text/plain;charset=UTF-8")//使用此类的访问路径,produces设置返回的response的媒体类型和字符集
    public @ResponseBody String normal(HttpServletRequest request){
        return "url:" + request.getRequestURL();
    }
    @RequestMapping(value = "/{pathVar}", produces = "text/plain;charset=UTF-8")//value接收的路径参数,结合@PathVariable获取访问路径参数
    public @ResponseBody String pathVar(@PathVariable String pathVar, HttpServletRequest request){
        return "url:" + request.getRequestURL() + ",路径参数:" + pathVar;
    }
    @RequestMapping(value = "/requestParam", produces = "text/plain;charset=UTF-8")//常规的request作为参数,获取路径后面拼接的id=xx
    public @ResponseBody String requestParam(Long id, HttpServletRequest request){
        return "url:" + request.getRequestURL() + ",id:" + id;
    }
    @RequestMapping(value = "/turn2Obj", produces = "application/json;charset=UTF-8")//对象自动转换json,返回的媒体对象为json
    @ResponseBody//可以用在方法上也可以用在方法中
    public Obj turn2Obj(Obj obj, HttpServletRequest request){
        return new Obj(obj.getId(), obj.getName());
    }
    @RequestMapping(value = {"/name1", "/name2"}, produces = "text/plain;charset=UTF-8")//不同路径映射到相同的方法
    public @ResponseBody String multiPath(HttpServletRequest request){
        return "url:" + request.getRequestURL();
    }
}

三、静态资源映射和拦截器

SpringMVC的定制配置需要我们的配置类继承一个WebMvcConfigurerAdapter类,并在此类使用@EnableWebMvc注解来开启对SpringMVC的配置支持,这个累里面有许多好用的方法,这样我们可以重写这个类的方法来完成我们的常用配置。

创建一个静态文件demo.txt在src/main/resource/assets下。

/**
 * 自定义拦截器
 * @author think
 */
public class Interceptor 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("执行时间:" + (endTime - startTime));
        request.setAttribute("handlingTime", endTime - startTime);
    }
}

/**
 * 配置
 * @author think
 */
@Configuration
@EnableWebMvc//开启springmvc支持,没有此句,重写WebMvcConfigurerAdapter无效
@ComponentScan("com")
public class MyMvcConfig extends WebMvcConfigurerAdapter{
    @Bean
    public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/classes/views/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }
    @Bean//配置拦截器的bean
    public Interceptor getInterceptor(){
        return new Interceptor();
    }
    @Override//静态资源映射
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //addResourceHandler对外暴露的访问路径,addResourceLocations文件放置的目录
        registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
        super.addResourceHandlers(registry);
    }
    @Override//注册拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getInterceptor());
        super.addInterceptors(registry);
    }
}

这样就可以访问项目目录下的静态文件资源,同时可以对请求进行拦截。

四、@ControllerAdvice

@ControllerAdvice作为一个全局配置的控制器,其组合了@Component,自动注册为spring的bean,所有配置信息都写在本类里面,注解了@Controller类的方法可以使用@ExceptionHandler,@ModelAttribute,@InitBinder,对所有注解了@RequestMapping的控制器都有效。

创建一个处理异常的页面error.jsp文件在src/main/resources/views下。

/**
 * 全局配置
 * @author think
 */
@ControllerAdvice
public class ExceptionHandlerAdvice {
    @ExceptionHandler(value = Exception.class)//全局异常配置
    public ModelAndView exception(Exception exception, WebRequest request){
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("errorMessage", exception.getMessage());
        return modelAndView;
    }
    @ModelAttribute//自动绑定键值对到model中,所有@RequestMapping的能获得此处的值
    public void addAttributes(Model model){
        model.addAttribute("msg", "额外信息");
    }
    @InitBinder//自动绑定前端的请求参数到model中
    public void initBinder(WebDataBinder binder){
        binder.setDisallowedFields("id");//将request参数封装为对象的时候忽略id这个属性,正常获取id参数还是可以获取到的。
    }
}

@Controller
public class AdviceController {
    @RequestMapping("advice")
    public String getGlobal(@ModelAttribute("msg") String msg, Obj obj, String id){
        throw new IllegalArgumentException("异常,msg:" + msg + ",obj:" + obj + ",id:" + id);
    }
}

发送 “springmvc4/advice?id=55&name=名字” 请求后,在error.jsp中用${errorMessage }就可以获取到:
这里写图片描述

五、其他配置

1、快捷返回页面ViewController

//简单的返回页面
@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/index").setViewName("/index");
    super.addViewControllers(registry);
}

用上面的代码可以替代掉下面的代码,从而达到一个简化的目的,前提是这只是一个简单的页面转向,不涉及到任何的逻辑。

@Controller
public class ControllerTest {
    @RequestMapping("/index")
    public String hello(){
        return "index";
    }
}

2、路径匹配参数配置

在SpringMVC中,请求路径如果带有“.”的话,后面的值将会被忽略,例如访问“/springmvc4/obj/pathvar.33”时,是无法获取“obj/”后面的完整参数。通过重写configurePathMatch将设置为不忽略“.”后面的参数:

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

猜你喜欢

转载自blog.csdn.net/zajiayouzai/article/details/80339894