初学Springboot(六)


前言

在Web开发中,会涉及到静态资源的访问支持、视图解析器的配置、转换器和格式化器的定制、文件上传下载等功能,甚至还需要考虑到与Web服务器关联的Servlet相关组件的定制,Spring Boot框架支持整合一些常用Web框架从而实现Web开发,并默认支持Web开发中的一些通用功能。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Spring MVC的整合支持

SpringBoot整合Spring MVC的自动化配置功能特性

①内置了两个视图解析器:ContentNegotiatingViewResolver和BeanNameViewResolver;

②支持静态资源以及WebJars;

③自动注册了转换器和格式化器;

④支持Http消息转换器;

⑤自动注册了消息代码解析器;

⑥支持静态项目首页index.html;

⑦支持定制应用图标favicon.ico;

自动初始化Web数据绑定器ConfigurableWebBindingInitializer

1、项目基础环境搭建

①使用Spring Initializr方式创建Spring Boot项目,并在Dependencies依赖选择中选择Web依赖启动器和Thymeleaf依赖启动器
在这里插入图片描述
②引入初学Springboot(五)已建好的项目我们在那个基础上进行修改
初学Springboot(五)
在这里插入图片描述
结构如上图

2、功能拓展实现

①注册视图管理器

创建一个实现WebMvcConfigurer接口的配置类MyMVCconfig,用于对MVC框架功能扩展

//实现WebMvcConfigurer接口,拓展MVC功能
@Configuration//声明为配置类
public class MyMVCconfig implements WebMvcConfigurer {
    @Override//添加视图管理
    public void addViewControllers(ViewControllerRegistry registry) {
        //请求toLoginPage映射路径或者login.html页面都会自动映射到login.html页面
        //addViewController请求访问的地址,setViewName跳转访问的地址
        //因为全局配置文件里面有设置
        // #指定模板页面名称的后缀
        //spring.thymeleaf.suffix = .html,所以直接填login就行
        registry.addViewController("/toLoginPage").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }
}

项目启动成功后运行一下启动类看一下效果
在这里插入图片描述
在这里插入图片描述
可以发现两个路径都能进入网站

②注册自定义拦截器MyInterceptor

实现HandlerInterceptor 接口,在该类中编写如下方法

@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        //用户请求/admin判断用户是否登录
        String uri = request.getRequestURI();
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (uri.startsWith("/admin") && null == loginUser) {
            response.sendRedirect("/toLoginPage");
            return false;
        }
        return true;}
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        //向request域中存放当前年份用于页面动态显示
        request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse
            response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
③注册拦截器

在实现mvc接口的配置类中添加(获取自定义拦截器),然后再重写注册

 @Resource
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addInterceptor注册自定义拦截器().addPathPatterns拦截所有路径请求
        registry.addInterceptor(myInterceptor)
                .addPathPatterns("/**")
                //放行处理
                .excludePathPatterns("/login.html");
    }

在这里插入图片描述

3、效果测试

重启项目,启动成功后,在浏览器上访问http://localhost:8080/admin
会发现直接跳转到/toLoginPage页面
在这里插入图片描述

二.自定义Servlet三大组件

自定义Servlet

步骤: ①创建一个自定义Servlet类

@Component
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doPost(req, resp); }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().write("hello MyServlet");
    }}

@WebServlet("/myServlet"):用于声明该类为自定义Servlet让启动类扫描,并定义虚拟路径
②创建一个ServletConfig用于注册Servlet组件

@Configuration
public class ServletConfig {
    /*
     * servlet组件的注册
     * */
    @Bean//把当前方法返回值存到Bean
    public ServletRegistrationBean getServlet(MyServlet myServlet){
        ServletRegistrationBean<MyServlet> myServletServletRegistrationBean
                = new ServletRegistrationBean<>(myServlet, "/myServlet");
        return myServletServletRegistrationBean;
    }}

运行一下看一下效果
在这里插入图片描述

自定义Fifiter

步骤①:创建一个自定义过滤器(fifiter)类MyFilter

@Component
public class MyFilter implements Filter {
    //初始化
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    //业务
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse
            servletResponse, FilterChain filterChain) throws IOException,
            ServletException {
        System.out.println("myFilter执行了。。。。");
//放行
        filterChain.doFilter(servletRequest,servletResponse);
    }
    //注销
    @Override
    public void destroy() {
    }
}

@WebFilter(value = {"/toLoginPage","/abc"}):声明该类为过滤器可以被扫描到

步骤②:注册组件
在ServletConfig中添加注册过滤器方法

 @Bean
    public FilterRegistrationBean getFilter(MyFilter myFilter){
        FilterRegistrationBean<MyFilter> filterFilterRegistrationBean = new
                FilterRegistrationBean<>(myFilter);
        filterFilterRegistrationBean.setUrlPatterns(Arrays.asList("/toLoginPage"));
        return filterFilterRegistrationBean;
    }

测试
在这里插入图片描述
当我们进行网站访问时,过滤器起到作用进行判断打印

自定义Listenner

步骤①:创建自定义监听器类MyListener

@Component
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized执行了");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed执行了");
    }
}

步骤②:注册组件
在ServletConfig中注册监听器

@Bean
    public ServletListenerRegistrationBean getListener(MyListener myListener){
        ServletListenerRegistrationBean<MyListener> myListenerServletListenerRegistrationBean = new ServletListenerRegistrationBean<>(myListener);
        return myListenerServletListenerRegistrationBean;
    }

三.通过扫描的方式使用Servlet三大组件

在上面的基础上
我们可以简化,不自己注册,用相应的组件注解,并开启启动类的组件扫描功能

注意:要把先前自定的的注解@Component注释,以及注册组件config类的@Configuration进行注解

例:在刚刚的自定义Servlet组件中
步骤①:开启组件路径扫描功能@WebServlet("/myServlet")

@WebServlet("/myServlet")
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doPost(req, resp); }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().write("hello MyServlet");
    }}

步骤②:在启动类开启扫描组件功能

@ServletComponentScan

同上

@WebListener
public class MyListener  implements ServletContextListener{}

@WebFilter
public class MyFilter implements Filter{}

三.文件上传

浏览器通过表单形式将文件以流的形式传递给服务器,服务器对上传的数据解析处理

表单格式三要素

1.文件上传项

例:

<div id="file" style="margin-top: 10px;" th:value="文件上传区域">  </div>

2.提交方式必须是POST(只有post提交才有请求体)

3.enctype属性需要进行修改:enctype=“multipart/form-data”:文件上传有内容,多步上传

<form th:action="@{/uploadFile}" method="post" enctype="multipart/form-data">
    上传文件:&nbsp;&nbsp;<input type="button" value="添加文件" onclick="add()"/>
    <div id="file" style="margin-top: 10px;" th:value="文件上传区域">  </div>
    <input id="submit" type="submit" value="上传"
           style="display: none;margin-top: 10px;"/>
</form>

全局配置文件添加关键字段:

# thymeleaf页面缓存设置(默认为true)
spring.thymeleaf.cache=false
# 配置国际化文件基础名
spring.messages.basename=i18n.login

# 单个上传文件大小限制(默认1MB)
spring.servlet.multipart.max-file-size=10MB
# 总上传文件大小限制(默认10MB)
spring.servlet.multipart.max-request-size=50MB

配置一个Controller类
toUpload()方法处理路径为“/toUpload”的GET请求,向文件上传页面upload.html跳转;

uploadFile()方法处理路径为“/uploadFile”的POST请求,对上传文件进行处理。文件上传处理过程中,对文件名进行重命名并存放在“C:/file/”目录下,并封装了返回结果。

其中,处理上传文件的请求方法中,使用了“MultipartFile[] fileUpload”参数处理单个或多个上传文件(也可以使用单列集合参数),fileUpload参数名必须与upload.html页面中上传文件框中的name属性值一致。

@Controller
public class FileController {
    /*
    * 跳转到upload.html
    * */
    //表示@RequestMapping加上请求方式必须是get请求
    @GetMapping("/toUpload")
    public String toUpload(){
        //因为全局配置文件设置了默认路径,直接简写
        return "upload";
    }
    /*
    实现文件上传
    * */
    @PostMapping("/uploadFile")
    public String uploadFile(MultipartFile[] fileUpload, Model model){
    //返回上传成功状态信息
        model.addAttribute("uploadStatus","上传成功");
    //上传文件逻辑开始
        for(MultipartFile file:fileUpload){
            //获取上传文件名称及后缀名 a.txt
            String fileName = file.getOriginalFilename();
            //重新生成文件名
            fileName = UUID.randomUUID()+"_"+fileName;
            //设置存储目录
            String dirPath = "C:/file/";
            //如果文件不存在还要创建
            File filePath = new File(dirPath);
            if(!filePath.exists()){
                filePath.mkdirs();
            }
            try {
                file.transferTo(new File(dirPath+fileName));
            } catch (Exception e) {
                e.printStackTrace();
                model.addAttribute("uploadStatus","上传失败: "+e.getMessage());}
        }
        return "upload";
        }
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值