Spring框架(五)SpringMVC高级

超详细的Java知识点路线图


概述

本文接上篇SpringMVC基础,主要介绍拦截器的使用和文件上传下载功能,以及RESTFul接口设计的规范,这些都是Web应用开发必备的技能点。

1、拦截器

1.1 拦截器概念

类似于JavaWeb中的Filter过滤器,用于过滤请求,可以对不符合要求的请求进行拦截

拦截器和过滤器的区别:

1)过滤器的使用范围比拦截器大,JavaWeb项目都可以使用,拦截器只能在SpringMVC使用

2)拦截器效率高于过滤器

1.2 拦截器的使用

1) 实现HandlerInterceptor接口

2)实现方法

  • preHandle 前置处理
  • postHandle 后置处理
  • afterCompletion 完成后处理
/**
 * 登录拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 前置处理
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //查询session是否保存用户
        User user = (User) request.getSession().getAttribute("user");
        if(user == null){
            //没有登录,重定向到login页面
            response.sendRedirect("/pages/login");
            //返回false,拦截
            return false;
        }
        //返回true,放行
        return true;
    }
}

3) 配置拦截器

	<!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--配置拦截的URL请求路径 /**代表所有请求-->
            <mvc:mapping path="/**"/>
            <!--配置不拦截的请求路径-->
            <mvc:exclude-mapping path="/**/login"/>
            <mvc:exclude-mapping path="/**/*.css"/>
            <mvc:exclude-mapping path="/**/*.js"/>
            <mvc:exclude-mapping path="/**/*.png"/>
            <mvc:exclude-mapping path="/**/*.jpg"/>
            <!--配置class-->
            <bean class="com.blb.bookms.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

# 2、文件上传下载

2.1 文件上传

文件上传分为两种方式:

  • 传统的Servlet文件上传
  • SpringMVC文件上传

2.1.1 传统的Servlet文件上传

1)导入依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

2)编写表单

表单文件上传的三个要素:

  1. form标签要添加enctype=“multipart/form-data”
  2. 提交方法为post
  3. input类型为file
<form  action="/upload" method="post" enctype="multipart/form-data">
    ...
    <input type="file" name="file" >
    ...
</form>

2)上传方法

@Controller
public class UploadController {

    @RequestMapping("/upload")
    public String fileupload(HttpServletRequest request) throws Exception {
        //获取项目的upload目录路径
        String path= request.getSession().getServletContext().getRealPath("/upload/");
        File file=new File(path);
        //判断文件夹是否存在
        if (!file.exists()){
            //创建文件夹
            file.mkdirs();
        }
        //创建上传对象
        ServletFileUpload upload=new ServletFileUpload(new DiskFileItemFactory());
        //获得文件列表
        List<FileItem> fileItems= upload.parseRequest(request);
        for (FileItem item:fileItems){
            //判断文件是不是普通表单项
            if (item.isFormField()){
                //如果是普通表单项,打印表单项名和值
                System.out.println(item.getFieldName());
                System.out.println(item.getString());
            }else{
                //如果是文件,截取后缀名
                String filename= item.getName();
                String suffix = filename.substring(filename.lastIndexOf("."));
                //创建唯一的文件名
                String uuid= UUID.randomUUID().toString().replace("-","");
                filename = uuid + suffix;
                //完成文件上传
                item.write(new File(path,filename));
                System.out.println("上传完毕");
            }
        }
        //跳转到success页面
        return "success";
    }

2.1.2 SpringMVC文件上传

依赖和表单和上面一样

上传方法中使用MultipartFile参数获得上传文件

@RequestMapping("/upload")
public String fileupload(HttpServletRequest request, MultipartFile upload) throws Exception {
    //获取项目目录下的upload目录路径
    String path = request.getSession().getServletContext().getRealPath("/upload/");
    System.out.println(path);
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
    }
    //获取上传文件名字
    String filename = upload.getOriginalFilename();
    String suffix = filename.substring(filename.lastIndexOf("."));
    //创建唯一的文件名
    String uuid= UUID.randomUUID().toString().replace("-","");
    filename = uuid + suffix;
    //完成文件上传
    upload.transferTo(new File(path,filename));
    return "success";
}

需要在springmvc的配置中添加上传处理器

<!--上传处理器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
    <!--上传文件最大字节数-->
    <property name="maxUploadSize" value="10485760"/>
</bean>

2.1.3 SpringMVC多文件上传

给表单添加多个文件项

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploads">
    <input type="file" name="uploads">
    <input type="file" name="uploads">
    <input type="submit" value="MVC多文件上传">
</form>

添加MultipartFile数组为参数,参数名和表单name一致

@RequestMapping("/upload3")
public String fileupload3(HttpServletRequest request, MultipartFile[] uploads) throws Exception {
    //获取tomcat项目目录下的upload目录路径
    String path = request.getSession().getServletContext().getRealPath("/upload/");
    System.out.println(path);
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
    }
    for(MultipartFile upload : uploads) {
        //获取上传文件名字
        String filename = upload.getOriginalFilename();
        String suffix = filename.substring(filename.lastIndexOf("."));
        //创建唯一的文件名
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid + "-" + suffix;
        //完成文件上传
        upload.transferTo(new File(path, filename));
    }
    return "success";
}

2.1.4 SpringMVC其它上传类

SpringMVC还提供了其它API支持上传:

  • CommonsMultipartResolver 多部分解析器,用于判断请求是否存在上传文件
  • MultipartHttpServletRequest 多部分请求,用于获得文件相关信息

具体用法:

@RequestMapping("upload4")
public String  fileupload4(HttpServletRequest request) throws IllegalStateException, IOException
{
    String path = request.getSession().getServletContext().getRealPath("/upload/");
    //创建多部分解析器
    CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver(
            request.getSession().getServletContext());
    //检查表单是否支持文件上传
    if(multipartResolver.isMultipart(request)){
        //将请求转换为多部分请求,支持上传
        MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
        //获取请求中所有的文件名
        Iterator iter=multiRequest.getFileNames();
        while(iter.hasNext()) {
            //遍历所有文件
            MultipartFile file=multiRequest.getFile(iter.next().toString());
            if(file!=null) {
                //获取上传文件名字
                String filename = file.getOriginalFilename();
                String suffix = filename.substring(filename.lastIndexOf("."));
                //创建唯一的文件名
                String uuid = UUID.randomUUID().toString().replace("-", "");
                filename = uuid + suffix;
                //上传
                file.transferTo(new File(path,filename));
            }
        }
    }
    return "success";
}

2.2 文件下载

/**
 * 下载控制器
 */
@Controller
public class DownloadController {

    @RequestMapping("download")
    public void download(String file,  HttpServletResponse response) throws IOException {
        //下载文件的路径
        String path = "D:\\install\\";
        File downFile = new File(path+file);
        if(downFile.exists()){
            //设置浏览器下载内容类型,响应头
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition","attachment;filename="+file);
            //通过流发送文件
            Files.copy(downFile.toPath(),response.getOutputStream());
        }
    }
}

3、RestFul

3.1 前后端分离

3.1.1 前后端分离是什么

前端项目(html5、小程序、移动端),后端项目(java、数据库、tomcat)分开开发和部署

3.1.2 前后端分离优势

1)开发分工明确,前端团队和后端团队同时分工合作开发

2)项目分开部署不同的服务器,如:Tomcat适合部署动态资源,Nginx适合部署静态资源

3)便于测试和维护

3.1.3 前后端开发人员的交互方式

1)设计人员根据需求设计接口,提供接口文档

1)后端根据接口文档开发后台接口

2)前端通过接口请求数据,渲染页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5TpfgxFJ-1608513277531)(SpringMVC.assets/clipboard-1608100199709.png)]

3.2 RESTFul

3.2.1 RESTFul是什么

RESTFul是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。适用于移动互联网厂商作为业务使能接口的场景,实现第三方调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。

RESTful架构,是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

3.2.2 RESTFul架构的特点

  1. 每一个URI对应服务器上的一个资源(数据库数据、方法等)

  2. 通过不同Http请求方法来区别增删改查操作

  • GET --> 查询
  • POST --> 添加
  • PUT --> 更新
  • DELETE --> 删除
  1. 通信的格式是JSON

3.2.3 RESTFul风格的API

传统API设计,常用动词定义API,如:find、get、save、update、delete等

查询所有书籍:
http://域名/book/findAll
查询一本书:
http://域名/book/findById?id=1
添加书籍:
http://域名/book/saveBook
更新书籍:
http://域名/book/updateBook
删除书籍:
http://域名/book/deleteBook?id=1

RESTFul风格API设计,只使用名词,使用不同的请求方法来区别增删改查

查询所有书籍: 	GET
http://域名/books
查询一本书:		GET
http://域名/book/1
添加书籍:		POST
http://域名/book
更新书籍:		PUT
http://域名/book
删除书籍:		DELETE
http://域名/book/1

Restful风格的控制器的实现

@RestController
public class BookController {

    @Autowired
    private BookService bookService;
    
    @GetMapping("/books")
    public JsonResult findAll(){
        try {
            List<Book> list = bookService.list();
            return new JsonResult(1,list);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonResult(0,null);
        }
    }
    
    @GetMapping("/book/{id}")
    public JsonResult findById(@PathVariable("id")Integer id){
        try {
            Book book = bookService.getById(id);
            return new JsonResult(1,book);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonResult(0,null);
        }
    }


    @PostMapping("/book")
    public JsonResult saveBook(@RequestBody Book book){
        try {
            bookService.save(book);
            return new JsonResult(1,null);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonResult(0,null);
        }
    }


    @PutMapping("/book")
    public JsonResult updateBook(@RequestBody Book book){
        try {
            bookService.updateById(book);
            return new JsonResult(1,null);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonResult(0,null);
        }
    }


    @DeleteMapping("/book/{id}")
    public JsonResult delBook(@PathVariable("id")Integer id){
        try {
            bookService.removeById(id);
            return new JsonResult(1,null);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonResult(0,null);
        }
    }
}

3.2.4 浏览器支持DELETE和PUT

浏览器默认只支持GET和POST请求,如果要表单提交DELETE或PUT请求,需要通过SpringMVC的过滤器来实现

web.xml添加:

<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

HiddenHttpMethodFilter过滤器的作用是:过滤表单中名称为_method的隐藏域,如果值是DELETE就将请求方法转换为DELETE,是PUT就将请求方法转换为PUT。

表单

<form action="/testDelete" method="post">
    <input name="name" placeholder="输入姓名"><br>
    <input type="hidden" name="_method" value="DELETE"/>
    <input type="submit" value="提交">
</form>

结束


大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒哥~Bingo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值