springboot(视图解析流程,内容协商,模板引擎,拦截器,Web原生组件注入(Servlet、Filter、Listener),整合mybatis)

配置文档地址: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties.
云雀笔记地址:https://www.yuque.com/atguigu/springboot

1、视图解析原理流程
1、目标方法处理的过程中,所有数据都会被放在 ModelAndViewContainer 里面。包括数据和视图地址
2、方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在 ModelAndViewContainer 
3、任何目标方法执行完成以后都会返回 ModelAndView(数据和视图地址)。
4、processDispatchResult  处理派发结果(页面改如何响应)
• 1render(mv, request, response); 进行页面渲染逻辑
• 1、根据方法的String返回值得到 View 对象【定义了页面的渲染逻辑】
• 1、所有的视图解析器尝试是否能根据当前返回值得到View对象
• 2、得到了  redirect:/main.html --> Thymeleaf new RedirectView()3、ContentNegotiationViewResolver 里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。
• 4、view.render(mv.getModelInternal(), request, response);   视图对象调用自定义的render进行页面渲染工作
• RedirectView 如何渲染【重定向到一个页面】
• 1、获取目标url地址
• 2、response.sendRedirect(encodedURL);
视图解析:
• 返回值以 forward: 开始: new InternalResourceView(forwardUrl); -->  转发request.getRequestDispatcher(path).forward(request, response); 
• 返回值以 redirect: 开始: new RedirectView() --》 render就是重定向 
• 返回值是普通字符串: new ThymeleafView()--->

内容协商:
引入依赖

 <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

自定义messageconverter:

public class WebConfig extends WebMvcConfigurationSupport {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        Map<String, MediaType> mediaTypes = new HashMap<>();
        mediaTypes.put("json",MediaType.APPLICATION_JSON);
        mediaTypes.put("xml",MediaType.APPLICATION_XML);
        //mediaTypes.put("",MediaType.)自定义
        ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
        //strategy.setParameterName("");//设置名字,默认format
        HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
        configurer.strategies(Arrays.asList(parameterStrategy,headerStrategy));
    }
}

模板引擎:
官方文档:using spring boot - starters—freemarker 页面渲染
Thymeleaf
链接: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html.

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
<html xmlns:th="http://www.thymeleaf.org">

抽取公共界面:

<footer th:=fragment = "copy">
	$;sadjkasjd
</footer>


 <div th:insert="footer :: copy"></div>
 <div th:replace="footer :: copy"></div>
 <div th:include="footer :: copy"></div>


<div>
	<footer>
		$;sadjkasjd
	</footer>
</div>

<footer>
		$;sadjkasjd
</footer>
<div>
	$;sadjkasjd
</div>

<--如果是id选择器,那么
<footer id = "copy">
	$;sadjkasjd
</footer><div>th:replace="footer :: #copy"</div>-->

拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override//目标方法执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录检查逻辑
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if (loginUser!=null){
            return true;//放行
        }
        //未登录状态,跳转至登录页
        request.setAttribute("msg","请先登录");
        request.getRequestDispatcher("/").forward(request,response);
        return false;//拦截
    }
    }

注册:

public class AdminWebConfig implements WebMvcConfigurer {
    @Override//注册拦截器,拦截哪些,放行哪些
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/","login","/css/**","/fonts/**","/js/**","/images/**");
    }
}

定制错误处理逻辑

  1. 自定义错误页
    • error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页
  2. @ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持的
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})
    public String handleArithException(Exception e){
        log.error("异常是:",e);
        return "login";
    }
}
  1. @ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户数太多")
public class UserTooManyException extends RuntimeException{
    public UserTooManyException() {
    }
    public UserTooManyException(String message) {
        super(message);
    }
}
  1. Spring底层的异常,如 参数类型转换异常;DefaultHandlerExceptionResolver 处理框架底层的异常。
    • response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
  2. 自定义实现 HandlerExceptionResolver 处理异常;可以作为默认的全局异常处理规则
  3. ErrorViewResolver 实现自定义处理异常;
    • response.sendError 。error请求就会转给controller
    • 你的异常没有任何人能处理。tomcat底层 response.sendError。error请求就会转给controller
    • basicErrorController 要去的页面地址是 ErrorViewResolver ;

Web原生组件注入(Servlet、Filter、Listener)

1.@ServletComponentScan(basePackages = “com.atguigu.admin”) :指定原生Servlet组件都放在那里
@WebServlet(urlPatterns = “/my”):效果:直接响应,没有经过Spring的拦截器?
@WebFilter(urlPatterns={"/css/","/images/"})
@WebListener

2、使用RegistrationBean
ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean

@Configuration
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();

        return new ServletRegistrationBean(myServlet,"/my","/my02");
    }


    @Bean
    public FilterRegistrationBean myFilter(){

        MyFilter myFilter = new MyFilter();
//        return new FilterRegistrationBean(myFilter,myServlet());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener(){
        MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
        return new ServletListenerRegistrationBean(mySwervletContextListener);
    }
}

整合mybatis

引入mybatis-starter
配置application.yaml中,指定mapper-location位置即可
编写Mapper接口并标注@Mapper注解
简单方法直接注解方式
复杂方法编写mapper.xml进行绑定映射
@MapperScan(“com.atguigu.admin.mapper”) 简化,其他的接口就可以不用标注@Mapper注解

分页插件:

@Configuration
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor paginationInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join

        //这是分页拦截器
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOverflow(true);
        paginationInnerInterceptor.setMaxLimit(500L);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        return mybatisPlusInterceptor;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值