SpringMVC使用笔记知识点

更多内容见:全球顶级java开发面试宝典

SpringMVC常用注解

@RequestMapping进行请求匹配,分发处理匹配的请求,可以作用在类上作整体的请求路径,也可以作用在方法上作更细粒度的请求路径。

@Controller
@RequestMapping("/search/save")
public class ElasticsearchSaveController {
    @RequestMapping("/product")
    public R productStatusUp() {
    }
}

@PostMapping,@GetMapping,@DeleteMapping,@PutMapping等restful风格的请求注解,可以匹配到对应请求类型的路径。如get请求/product和put请求/product可以匹配到对应的@GetMapping(“/product”)和@PutMapping(“/product”)中而无需改多个名字。

@PathVariable用来提取请求路径中变量的值。

@Controller
@RequestMapping("/user/{username}")
public String userProfile(@PathVariable(value="username") String username) {
    	return "user"+username;
}

@RequestParam则是用来提取请求携带的参数。如/user?blogId=9

@Controller
@RequestMapping(value="/user")
public String getUserBlog(@RequestParam("id") int blogId) {
	return blogId;
}

@RequestBody用于接收请求携带的请求体,一般来自post请求,使用对象接收。

@Controller
@RequestMapping"/commit"public class test{
    public void testMethod(@RequestBody User user)"{
    }
}

@ResponseBody和@RestController。@ResponseBody用在方法上表示默认将返回值直接放入http的body数据中,@RestController用在类上,表示本类所有的方法都默认执行此行为,在前后端分离常用。

@RestController
public class TestController{

    @RequestMapping("/ts")
    // @ResponseBody
    public String test(){
        return "ajax";
    }

}

@ModelaAtrribute

SpringMVC执行流程

  1. DispatcherServlet调用注册过的BeanNameUrlHandlerMapping(处理映射器)根据请求去查找Handler,并把解析后执行链的信息返回给DispatcherServlet

  2. DispatcherServlet调用注册过的SimpleControllerHandlerAdapter(处理适配器)找到对应的Handler去执行并获得它的信息,将信息ModeAndView返回给DispatcherServlet

  3. DispatcherServlet调用注册过的InternalResourceViewResolver(视图解析器)对ModelAndView中的数据进行处理,如获得数据和获得视图名并拼接地址,然后把信息返回给DispatcherServlet

  4. DispatcherServlet根据视图解析器的结果调用视图渲染呈现

如下图所示

在这里插入图片描述

其中组件:

  1. DispatcherServlet
    DispatcherServlet 是前端控制器,Spring MVC的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
  2. BeanNameUrlHandlerMapping
    BeanNameUrlHandlerMapping 是处理器映射器,其作用是根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息。
  3. SimpleControllerHandlerAdapter
    SimpleControllerHandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)。
  4. Handler
    Handler 是处理器,和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。
  5. InternalResourceViewResolver
    InternalResourceViewResolver 是视图解析器,其作用是进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如拼接地址通过一个路径返回一个真正的对应页面)。
  6. ModelAndView
    Model是模型,对数据进行存储。View 是视图,其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等)。

SpringMVC基本使用过程

  1. 在web.xml中配置DispatchServlet,绑定Resource下配置的springmvc-servlet.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:springmvc-servlet.xml</param-value><!-- xml命名:servlet的名字+配置的是个是啥 -->
        </init-param>
        <load-on-startup>1</load-on-startup>    <!--启动级别-->
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>       <!-- / 匹配请求,不会去匹配jsp(jsp直接走页面)   /* 匹配所有,包括jsp(匹配jsp过来之后)   -->
    </servlet-mapping>
  1. springmvc-servlet.xml中开启包上下文扫描,mvc注解支持,<mvc:default-servlet-handler/>,和视图解析器配置前后缀
<mvc:default-servlet-handler/>           <!--让.css,.html,.mp3等什么的去他自己固定的地方-->
    <mvc:annotation-driven/>                 <!--mvc注解支持-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
  1. 对应类用注解注册为bean,用注解@RequestMapping映射请求,处理后可用ModelAndView存储处理后的数据和返回的视图return回去,也可以直接返回数据或者视图名
    @RequestMapping("/get/getProductById")
    public ModelAndView getProductById(ModelAndView modelAndView){
        modelAndView.addObject(new User());
        modelAndView.setViewName("pro");
        return modelAndView;
    }

    @RequestMapping("/getUser")
    public String user(Model model){
        model.addAttribute("msg",user);
        return "First";
    }

SpringMVC重定向and转发

重定向和转发在return时进行处理,可用Model携带中间参数。如下图示,在return写好对应的功能即可,同理也可使用ModelAndView写入对对应路径进行请求转发和重定向。

    @RequestMapping("/forward")
    public String forward(Model model){
        model.addAttribute("msg","forward");
        return "forward:/WEB-INF/jsp/First.jsp";      //转发,就是普通的return,加了forward和redirect后视图解析器不生效
    }

    @RequestMapping("/redirect")
    public String redirect(Model model){
        model.addAttribute("msg","redirect");
        return "redirect:index";                 //重定向
    }

一些区别:
1.重定向访问服务器两次,转发只访问服务器一次。

2.转发页面的URL不会改变,而重定向地址会改变

3.转发只能转发到自己的web应用内,重定向可以重定义到任意资源路径。

4.转发相当于服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,可以通过此来传递一些数据或者session信息。而重定向会产生一个新的request,不能共享request域信息与请求参数

5.转发相当于同一次请求,可以访问到/WEB-INF目录下的资源,重定向相当于第二次单独请求,不能直接访问/WEB-INF目录下的资源,只得通过controller再次普通return.

SpringMVC拦截器

拦截器在设置完以后,可以对特定的请求路径进行方法执行前方法执行后等处进行拦截,也可以对方法进行限制不予以放行。

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LoginService loginService;

    @Override    // 只要用到拦截器,就可以用到拦截器存下的threadlocal
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!(handler instanceof HandlerMethod)) {
            return true;
        }

        log.info("=================request start===========================");
        String requestURI = request.getRequestURI();
        log.info("request url:{}",requestURI);
        log.info("request method:{}",request.getMethod());
                                                                            // request.getHeader("xxx");
        String token = request.getHeader("Oauth-Token");
        System.out.println("浏览器的token:"+token);
        System.out.println("整理后+"+token.substring(1,token.length()-1));
        log.info("token:{}", token); // 正常是从请求头中取的
        log.info("=================request end===========================");

        // 如果缓存里没有这个token,可以重定向到主页,以redis过期时间来操作对用户的上线下线
        if(StringUtils.isBlank(token)){
            Result fail = Result.fail(ErrorCode.NO_LOGIN.getCode(), ErrorCode.NO_LOGIN.getMsg());
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().println(JSON.toJSONString(fail));
            return false;
        }

        SysUser sysUser = loginService.checkToken(token.substring(1,token.length()-1));
        if(sysUser==null){
            Result fail = Result.fail(ErrorCode.NO_LOGIN.getCode(), ErrorCode.NO_LOGIN.getMsg());
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().println(JSON.toJSONString(fail));
            return false;
        }
        // 得到用户信息,方便使用
        UserThreadLocal.put(sysUser);   // UserThreadLocal建立了一个类,方便去里面拿资源

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 删除ThreadLocal里的信息,防止内存泄漏
        UserThreadLocal.remove();
    }
}

在xml配置好生效的路径。

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>  <!-- /**当前下所有文件包括子文件夹 | /* 当前下文件不包括子文件夹 | /请求 -->
            <bean class="com.xin.config.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

在SpringBoot则统一配置类中进行配置。

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/comments/create/change")
                .addPathPatterns("/articles/publish");
    }
}

SpringMVC统一异常处理

统一异常处理,顾名思义是对某一处文件所可能抛出的异常进行统一捕获处理,并且可以对不同种类的异常进行不同的处理。但是在使用时不谨慎会有很大的问题,比如应用出异常被捕获没做显眼的处理,导致排错时很难受。

@ControllerAdvice      // 对@Controller的类进行aop
public class AllExceptionHandler {

    @ExceptionHandler(Exception.class)  // 对该种类异常进行捕获
    @ResponseBody                       // 捕获到异常即返回这里的信息
    public Result doException(Exception e){
        e.printStackTrace();
        return Result.fail(-999,"系统异常");
    }

}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值