栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring MVC开发实战SSM环境搭建及后端接口简单实例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring MVC开发实战SSM环境搭建及后端接口简单实例

Spring MVC环境部署 maven新建web-MVC项目,pom.xml中导入核心依赖包:

      org.springframework
      spring-context
      5.2.19.RELEASE
    

    
      org.springframework
      spring-aop
      5.2.19.RELEASE
    

    
      org.springframework
      spring-aspects
      5.2.19.RELEASE
    

    
      org.springframework
      spring-jdbc
      5.2.19.RELEASE
    

    
      org.springframework
      spring-context
      5.2.19.RELEASE
    

    
      org.springframework
      spring-web
      5.2.19.RELEASE
    

    
      org.springframework
      spring-webmvc
      5.2.19.RELEASE
    
spring-mvc.xml核心文件配置



	
    
    
    
    
    
    


web.xml核心文件的配置






  
    SpringMVC
    org.springframework.web.servlet.DispatcherServlet



    1


  
  
    SpringMVC
    /
  


DispatcherServlet负责管理和分发控制器,除了两个注释是最核心的配置。具体看之前的文章Spring MVC框架基础知识注释二作用是引入spring MVC的配置文件初始化配置参数。DispatcherServlet 的工作流程 :
1、向服务器发送 HTTP 请求,请求被前端控制器 DispatcherServlet 捕获。
2、 DispatcherServlet 根据 WEB-INF下的xxx-servlet.xml中的配置对请求的 URL 进行解析,得到请求资源标识符(URI)。然后根据该 URI,调用 HandlerMapping获得该 Handler(控制器) 配置的所有相关的对象(包括 Handler 对象以及 Handler 对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。
3、DispatcherServlet 根据获得的 Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(…)方法)。
4、提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler( Controller)。在填充 Handler 的入参过程中,根据你的配置,Spring 将帮你做一些额外的工作:

数据转换:对请求消息进行数据转换。如 String 转换成 Integer等。

HttpMessageConveter:将请求消息(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息。

数据格式化化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。

数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult 或 Error 中。

Handler(Controller)执行完成后,向 DispatcherServlet 返回一个ModelAndView 对象。

根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到 Spring 容器中的 ViewResolver)返回给 DispatcherServlet。

ViewResolver 结合 Model 和 View,来渲染视图。

视图负责将渲染结果返回给客户端。

spring配置文件一般会放在Maven的resources目录下,但DispatcherServlet默认再WEB-INF目录下寻找,通过注释二的初始化配置路径。当然如果直接放在WEB-INF目录下就不需要配置了。

静态资源放行

完成上面的配置后启动服务器,上下文连接是根项目名,web资源的上下文配置maven自动配置了上下文连接:

只需要对应webapp下的目录即可,但是会发现路径对应了仍然找不到文件css,html,js等静态资源:

原因在于web.xml配置的DispatcherServlet的/为/表示DispatcherServlet会拦截除jsp的所有资源并解析(css/" />

在实际开发中@ExceptionHandler注解的功能最强大。异常处理

文件上传

Spring MVC的文件上传十分方便不同于于Servlet上传需要写大量配置,因为它直接提供了对文件上传的直接支持即MultipartResolver接口。该接口用于处理上传请求,并将上传的数据包装成可以直接获取的文件。

MultpartiResolver接口有以下两个实现类:

StandardServletMultipartResolver:使用了 Servlet 3.0 标准的上传方式。CommonsMultipartResolver:使用了 Apache 的 commons-fileupload commons-io=来完成具体的上传操作。

MultpartiResolver接口具有以下方法。

使用 CommonsMultipartResolver来完成文件上传,分为单文件上传和多文件上传两部分介绍:

单文件上传

    导入依赖

    commons-io
    commons-io
    2.4


    commons-fileupload
    commons-fileupload
    1.2.2

    配置 MultipartResolver

    
    




resolveLazily:延迟解析,默认为false--立即解析multipart request;

defaultEncoding:解析请求的默认字符编码 ; 默认值为"ISO-8859-1"。通常设置为"UTF-8";

maxUploadSize:文件上传最大值; 默认值为 -1(表示没有限制);

maxUploadSizePerFile:每个文件上传最大值;默认值为 -1(表示没有限制);

maxInMemorySize:存储在内存的最大值;默认值为10240B(10KB);

uploadTempDir:上传文件的临时目录;默认值为WEB应用程序的临时目录;

servletContext:the servletContext to use;

    文件上传表单页面

表单的文件上传需要使用 enctype 属性,并将它的值设置为 multipart/form-data,同时将表单的提交方式设置为 post。




    
    Title


    创建文件的映射对象POJO类

在该 POJO 类中声明一个 MultipartFile即(前端的uplaodaFile)类型的属性封装被上传的文件信息,属性名与前端页面 的name属性的相同,代码如下:

import org.springframework.web.multipart.MultipartFile;

public class File {
    private String description;
    private MultipartFile fileInfo;
}
    编写文件上传的控制器
//测试是否可以传递到后端
@PostMapping("/getFile")
    protected String uploadFile(String description, MultipartFile fileInfo){
        System.out.println(description);
        System.out.println(fileInfo);
        return "success";
    }


如图所示文件成功传递到后端,调用MultpartiResolver接口的方法对其解析和转存即可。



File类型是java内置处理文件的。

解析并存储的代码:

@PostMapping("/getFile")
@ResponseBody
    protected String uploadFile(String description, MultipartFile fileInfo, HttpServletRequest request) {
        //System.out.println(description);
        //System.out.println(fileInfo);
        //获取原始名,目的时获取后缀名
        String originalFileName=fileInfo.getOriginalFilename();
        //获取后缀名
        String extensionName=originalFileName.substring(originalFileName.lastIndexOf("."));

        System.out.println(extensionName);

        //生成随机文件名,避免上传的文件同名,时间戳加随机数
        //String.valueOf(new Date().getTime());
        //String.valueOf(Math.random()*100);
        String newName=String.valueOf(new Date().getTime())+String.valueOf(Math.random()*100);

        System.out.println(newName);

        //生成完整文件名,如:23482493242.jpg
        String finallyName=newName+extensionName;

        System.out.println(finallyName);

        //获取需要转存的位置即服务器的路径
        //controller继承的HttpServlet携带两个基本参数(res,resp)
        //spring MVC默认的路径时WEB-INF,如果没有会向上查找
        String dirname=request.getServletContext().getRealPath("imgs");

        String savePath=dirname+"/"+finallyName;
        
        System.out.println(savePath);
        //保存文件
        try {
            fileInfo.transferTo(new File(savePath));
        }catch (IOException e){
            e.printStackTrace();
            System.out.println("save error");
        }

        return "success";
    }


后台输出结果:


处理处理文件解析与保存的过程中除了Spring MVC提供的接口的方法外主要就是String dirname=request.getServletContext().getRealPath("imgs");请求中的这个方法了,看源代码配置:

private File getCommondocumentRoot() {
		for (String commonDocRoot : COMMON_DOC_ROOTS) {
			File root = new File(commonDocRoot);
			if (root.exists() && root.isDirectory()) {
				return root.getAbsoluteFile();
			}
		}
		return null;
	}
private static final String[] COMMON_DOC_ROOTS = { "src/main/webapp", "public",
			"static" };

request.getServletContext().getRealPath()返回的是一个临时文件夹的绝对地址,会根据服务器地址变化,例如,小编在调用是获取的本机地址是E:JavaWebxxx...webappimgs如上面dirname传递的参数是imgs那么就会映射到该目录(首先要存在)。正如源代码配置的一样该地址默认映射到项目的webapp目录。

简单说该临时地址由三部分组成:项目所在位置的绝对地址+src/main/webapp+参数。第一部分随项目部署的位置改变。

文件下载

浏览器支持多种文件的解析和存储,因此下载文件只需要接口提供数据流。(以图片文件为例)

文件下载只能是异步请求,通过Ajax发送请求获取服务器图片目录下所有图片地址,显示在前端页面上:

获取服务器文件名


    
    Title
    


bookShow

//文件下载
    @GetMapping("/download")
    @ResponseBody
    protected String[] downloadFile(HttpServletRequest request,HttpServletResponse response){
        //从imgs目录下获取所有图片,并响应前端
        String dirname=request.getServletContext().getRealPath("imgs");

        //img是一个目录本身也是java的File对象,通过该对象的接口获取所有图片的名称
        File imgFileName=new File(dirname);

        //返回文件夹下所有图片名称
        String [] nameList=imgFileName.list();
        return nameList;
    }

返回图片名称与服务器目录下一致:


前端能够拿到数据后,将数据可视化,并为每个图片提供下载按钮,这个按钮发送异步请求,这时返回的就是数据流了,由浏览器解析。

可视化图片并提供下载功能
//使用bootstrap框架对数据解析



    
    Title
    
    
    
    




    

下载功能实现

浏览器可以自主解析图片文件,后端接口提供图片的数据流即可,也是异步请求:

如上面的gif中上传后鼠标移动到下载后左下角地址的变化,将图片名称通过url传递给后端接口。
在可视化图片时已经获取了图片名称,将图片名称传到下载API通过名称找到图片传回数据流:

//传输图片数据流
@GetMapping("/imgbases")
public void imgbase(@RequestParam("img") String imgName ,HttpServletRequest request,HttpServletResponse response){
    //获取图片目录
    String dirname=request.getServletContext().getRealPath("imgs");
    //获取图片文件路径
    String filePath=dirname+"/"+imgName;

    //图片的输出流(内存中)
    try{
        FileInputStream inputStream=new FileInputStream(filePath);

        //图片数据流浏览器可以直接识别,设置响应头,让浏览器无法识别,从而调用保存接口
        response.setContentType("application/unknown");
        //把文件名也传递过去,保存的时候需要,专门接口的响应头,不是普通响应头
        response.addHeader("Content-Disposition","attachment;filename="+imgName);

        //使用commons-io的流处理将数据流写入响应体
        IOUtils.copy(inputStream,response.getOutputStream());

    }catch (IOException e){
        e.printStackTrace();
    }


}

上面的代码已经将图片数据流发送给前端,response.setContentType()方法将响应内容设置为浏览器无法解析的对象,这样就会调用保存的系统接口,同时把文件名也传过去,便于保存。(如果没有两步设置,点击下载会发现图片会打开而不是调用保存接口,这是由于浏览器能够解析图片文件,不会直接调用系统保存文件接口。在响应头设置其为无法识别的接口就可以直接存储了。

拦截器

Servlet中存在过滤器,Spring IoC容器中存在拦截器,它们有很大差异:

    过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射。Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在Spring的任何情况下使用。Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

在Servlet开发中,每个请求对应一个Servlet,因此可以通过Filter管理;但在Spring MVC中,只有一个DispatcherServlet,通过映射来访问Filter不再满足需求,需要通过Ierceptor(拦截器来实现)。

在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,主要有以下 2 种方式。

    通过实现HandlerInterceptor接口或继承 HandlerInterceptor接口的实现类(例如
    HandlerInterceptorAdapter)来定义;
//首先是实现接口
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class TestInterceptor implements HandlerInterceptor {

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
    }
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle方法在控制器的处理请求方法调用之前执行");
        return true;
    }   
    
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
    }
}


//控制器映射
@RequestMapping(value = "/three",produces = "application/html;charset=utf-8")
    protected String eight(Model model){
        model.addAttribute("name","张三");

        return "/index.jsp";
    }


        
            
            
        
    


结果:


    
     
    
        
        
        
        
        
        
    
    
        
        
        
        
    

    通过实现WebRequestInterceptor接口或继承WebRequestInterceptor接口的实现类来定义。

WebRequestInterceptor和HandlerInterceptor接口中定义的方法作用也是一样的。不同点是
WebRequestInterceptor的入参WebRequest是包装了HttpServletRequest 和HttpServletResponse的,通过WebRequest获取Request中的信息更简便。其次preHandle是没有返回值的,说明该方法中的逻辑并不影响后续的方法执行,所以这个接口实现就是为了获取Request中的信息,或者预设一些参数供后续流程使用。

SSM整合 Maven创建web项目,并配置Tomcat。

添加war的打包依赖,导入servlet和jsp依赖:



    4.0.0

    org.example
    ssm
    1.0-SNAPSHOT
    war

    
        8
        8
    

    
        
            javax.servlet
            javax.servlet-api
            3.1.0
        
		
            javax.servlet.jsp
            jsp-api
            2.2
        
    


Mybatis配置

添加持久层框架时不要忘了对应的数据库驱动工具包。

导入mybatis依赖


    mysql
    mysql-connector-java
    8.0.11



    org.mybatis
    mybatis
    3.5.5

创建mybatis-config.xml用于创建SqlSessionFactory

文件不需要任何配置,在IoC容器中通过MapperScannerConfigurer对象配置




	
	

Spring MVC整合Mybatis依赖于Ioc容器,像DataSource,SqlSessionFactory,SqlSession,Mapper等对象都可以交给IoC容器管理。同时Spring AOP提供了声明式事务管理,更加方便。

部署Spring、Spring MVC

添加依赖

    
      org.springframework
      spring-context
      5.1.19.RELEASE
    

    
      org.springframework
      spring-aspects
      5.1.19.RELEASE
    

    
    
      org.springframework
      spring-jdbc
      5.1.19.RELEASE
    

    
      org.springframework
      spring-test
      5.1.19.RELEASE
    

    
      org.springframework
      spring-web
      5.1.19.RELEASE
    

    
      org.springframework
      spring-webmvc
      5.1.19.RELEASE
    

	
    
      com.fasterxml.jackson.core
      jackson-databind
      2.12.3
    


创建配置文件

如果所有配置文件都集中在一个xml中会过于冗余,使用多配置文件分开管理(并不是独立的分工合作):

beans.xml配置注解声明,以及bean管理。





        
        

spring-servlet.xml文件进行mvc相关配置,如静态资源,拦截器,视图解析器,异常处理等。




    
    


mybatis-config.xml进行Mybatis的配置。






spring-mybatis.xml进行spring于mybatis整合配置。





web.xml配置Spring MVC的控制器。




  Archetype Created Web Application


  
    SpringMVC
    org.springframework.web.servlet.DispatcherServlet

    
        
          contextConfigLocation
          classpath:spring-*.xml
        
    


    1


  
  
    SpringMVC
    /
  

在web.xml中配置contextConfigLocation对象并配置路径,就会加载配置文件并启动IoC容器,不需要再java代码中通过ClassPathApplicationContext等上下文对象再次加载。

Spring整合Mybatis

上面的配置实现了spring配置文件到控制器的整合,接下来实现spring于mybatis的整合。

导入mybatis-spring依赖

 
    
      org.mybatis
      mybatis-spring
      1.3.1
    

配置连接池,这里使用druid

    
      com.alibaba
      druid
      1.2.6
    

配置基于jdbc的连接池的参数

druid.driver=com.mysql.cj.jdbc.Driver
druid.url=jdbc:mysql://localhost:3306/${数据库名}?characterEncoding=utf-8
druid.username=${username}
druid.password=${password}

#连接处参数
druid.pool.init=1
druid.pool.minIdle=3
druid.pool.maxActive=20
druid.pool.timeout=30000

在spring-mybatis.xml文件配置数据源

    
    
    
        
        
        
        

        
        
        
        
    
    

在spring-mybatis.xml文件配置SqlSessionFactory

 
    
        
        
        
        
        
    

	 
    
        
        
    

在spring-mybatis.xml文件配置事务管理

 
    
        
    
    
    

将配置文件交给sping加载,最好不要交给springMVC加载 避免出现错误,因为web.xml配置时spring的监听先启动,springMVC的Dispatcherservlet接收到请求时初始化springMVC的配置文件。

测试是否配置成功

resources的mapper中创建UserMapper.xml




     
        select *
        from user
  

dao中创建UserMapper.java的映射接口

public interface UserMapper {
    List allUser();
}

基于spring test创建单元测试

在test目录下创建UserMapperTest的测试文件,内容如下

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml","classpath:spring-mybatis.xml","classpath:spring-servlet.xml"})
public class UserMapperTest {

    @Resource
    private UserMapper userMapper;
    @Test
    public void allUser() {
        List list=userMapper.allUser();
        System.out.println(list);
    }
}

数据表:

测试的时候遇到如下错误:

在properties文件url后添加&useSSL=false&serverTimezone=GMT%2B8

druid.url=jdbc:mysql://localhost:3306/db1?characterEncoding=utf-8

druid.url=jdbc:mysql://localhost:3306/db1?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8

主要原因式数据库驱动版本过低,mysql8.0Driver变更由com.mysql.jdbc.Driver更新为com.mysql.cj.jdbc.Driver,更改连接URL,设置useSSL=false。更改连接URL,增加服务器时区值配置serverTimezone=GMT%2B8GMT%2B8表示时区东八区

开始也是这个问题看了这个博客的解析,更改后就没问题了。初始化数据库错误,init datasource error, url: jdbc:mysql://localhost:3306/


需要注意的是测试类中需要使用注解加载spring及spring mvc相关文件,当配置了Tomcat后配置文件在web.xml中就加载了,由Tomcat初始化。

配置Tomcat实现后端后端接口

编写控制器

@Controller
public class Login {
    @Resource
    private UserMapper userMapper;

    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String identify(Model model){
        List list=userMapper.allUser();
        model.addAttribute("list",list);
        return "index.jsp";
    }
}

jsp作为显示页面

<%@ page isELIgnored="false" %>


Hello World!

${list}

配置并启动服务器,浏览器访问接口

案例解压后直接运行,免费下载!有一个对象相信会更快搭建ssm环境。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759745.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号