SpringMVC(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: SpringMVC

SpringMVC.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--     扫描controller-->
    <context:component-scan base-package="com.msb.controller"></context:component-scan>
<!--   开启mvc注解驱动,自动给我们配置好处理器映射器和处理器适配器-->
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    </bean>
<!--&lt;!&ndash;        指定前缀和后缀&ndash;&gt;-->
<!--        <property name="prefix"  value="/WEB-INF/"></property>-->
<!--        <property name="suffix"   value=".jsp"></property>-->
<!--    </bean>-->
<!--    静态资源放行-->
<!--    mapping url中的路径  location=对应的路径到项目-->
<!--    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>-->
</beans>

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>demo1</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ssm02</artifactId>
    <packaging>war</packaging>
    <name>ssm02 Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>
    <dependencies>
       <!-- spring核心容器包       -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.5</version>
        </dependency>
      <!--   spring 切面包     -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.5</version>
        </dependency>
         <!--aop联盟包           -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
          <!--德鲁伊连接池        -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql驱动            -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <!--    springJDBC包    -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.6</version>
        </dependency>
        <!--   spring事务控制包     -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.6</version>
        </dependency>
        <!--spring orm映射依赖        -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.3.5</version>
        </dependency>
<!--        Apache Commons日志包-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
<!--        log4j2-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
            <scope>test</scope>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
<!--        spring test测试支持包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.6</version>
            <scope>test</scope>
        </dependency>
<!--        springmvc支持包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.6</version>
        </dependency>
<!--    mybatis核心jar包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
<!--        spring mybatis整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!--spring核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--servlet核心-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--jsp核心-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!--文件上传依赖-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <!--https://mvnrepoository.com/artifact/com.fasterxml.jackson.core/jackson-databind-->
        <!--json   jackson 阿里巴巴的fastjson-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.1</version>
        </dependency>
        <!--fastJSON-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
        <!--        json格式数据-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.4</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>ssm02</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

log4j2.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="DEBUG">
    <Appenders>
        <Console name="Console" target="SYSTEM_ERR">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
              <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

jdbc.properties:

jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
jdbc_username=root

applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.alibaba.com/schema/stat"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd">
<!--    加载properties配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
<!--    包扫描 仅仅扫描service-->
    <context:component-scan base-package="com.msb.service"/>
<!--    配置数据源-->
    <bean  id="dataSource"  class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc_driver}"></property>
        <property name="url" value="${jdbc_url}"></property>
        <property name="username" value="${jdbc_username}"></property>
        <property name="password" value="${jdbc_password}"></property>
    </bean>
<!--SqlSessionFactoryBean-->
  <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--      配置数据源-->
      <property name="dataSource" ref="dataSource"></property>
        <!-- 实体类别名的包扫描     -->
      <property name="typeAliasesPackage" value="com.msb.pojo"></property>
  </bean>
    <!--    SqlSession获取Mapper-->
    <!--    MapperScanner mapper扫描仪 生成所有的Mapper对象放入容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--        注入factory-->
        <property name="sqlSessionFactoryBeanName" value="factory"></property>
    <!--   扫描所有的mapper接口和映射文件     -->
        <property name="basePackage" value="com.msb.mapper"></property>
    </bean>
<!--    事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"  ref="dataSource"></property>
     </bean>
<!--    开启事务注解-->
    <tx:annotation-driven></tx:annotation-driven>
</beans>

UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.msb.mapper.UserMapper">
<!--    User findUser(String uname, String password);-->
    <select id="findUser" resultType="user">
        select  * from  user where username =#{param1} and password= #{param2}
    </select>
<!--    findAllUser-->
    <select id="findAllUser" resultType="user">
        select * from user
    </select>
</mapper>

SpringMVC作用域传递参数

@Controller
public class ScopeController {
    /**
     *
     * request,session这两个域直接放在参数列表上即可,SpringMVC就可以给我们注入
     * ServletContext对象不能直接放在参数列表上,而是通过请求获取。
     */
    @RequestMapping("/setData")
    public String testScope(HttpRequest req, HttpSession session){
        //向作用域中存放数据
        //可以存放字符串,对象,集合
        session.setAttribute("message","message");
        return "/showData.jsp";
    }
    /**
     * ModelAndView
     * Model数据
     * View 视图
     * @return
     */
    @RequestMapping("setData1")
    public ModelAndView setData1(){
        ModelAndView mv=new ModelAndView();
        Map<String,Object> model=mv.getModel();
        //向request域中存放数据
        model.put("aaa","aaa");
        Model model1=new ConcurrentModel();
        //model对象存放数据,主要是请求域传递数据
        //model中的字符串类型的键值对信息会转换为请求参数,转发给目标组件
        model1.addAttribute("aaa","aa");
        //设置视图
        mv.setViewName("forward:/showDataPage.jsp");
        return mv;
    }
}

分布式:将一个项目分别部署在多个服务器上。

集群:当一个服务器宕机以后,还有另一个服务器来支持。

注意:mapper接口和Mapper配置文件是否要在同一个目录下。

bd334fa21aef43e890efb8295c09f5ea.png

实现效果:实现一个注册功能的表单页,点击立即上传后,图片框会显示出图片,点击注册之后,跳转到所有用户展示页,同时,用户信息也要保存到数据库。


思路:几个文本框就是简单的实体类属性。用户头像用ajax异步请求浏览器,将图片信息保存到服务器上,然后再回显给浏览器。浏览器收到后端响应的数据后,将照片回显。


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="http://lib.sinaapp.com/js/jquery/2.2.4/jquery-2.2.4.min.js"></script>
    <script type="text/javascript">
        $(function (){
            $("#uploadFile").click(function (){
                //获取要上传的文件
                var photoFile=$("#photo")[0].files[0];
                console.log(photoFile)
                if(photoFile==undefined){
                    alert("您还未选中文件")
                    return
                }
                //将文件装入FormData对象
                var formData=new FormData();
                formData.append("headPhoto",photoFile);
                //通过ajax向后台发送文件
                $.ajax({
                    type:"post",
                    data:formData,
                    url:"fileUpload.do",
                    processData:false,
                    contentType:false,
                    success:function (result){
                        //接收后台响应的信息
                       console.log(result);
                        //图片回显
                        $("#headImg").attr("src","upload/"+result.photoName);
                        //设置隐藏域,将文件名和文件类型放入form表单
                        $("#photoInput").val(result.photoName)
                        $("#filetypeInput").val(result.filetype)
                    }
                })
            })
        })
    </script>
</head>
<body>
<form action="addPlayer.do" method="get">
    <p>账号<input type="text" name="name"></p>
    <p>密码<input type="text" name="password" ></p>
    <p>昵称<input type="text" name="nickname"></p>
    <p>头像:
        <br/>
        <input id="photo" type="file">
        <br/>
        <img id="headImg" style="width:200px;height:200px" alt="您还未上传图片">
        <br/>
    </p>
    <a   id="uploadFile" href="javascript:void(0)"> 立即上传</a>
    <%--      使用隐藏输入框存储文件名称和文件类型--%>
    <input id="photoInput" type="hidden" name="photo" >
    <input id="filetypeInput" type="hidden" name="filetype">
    <p><input type="submit" value="注册"></p>
</form>
</body>
</html>
@RestController
@Controller
public class FileUploadController {
    @ResponseBody
    @RequestMapping("fileUpload.do")
    public Map<String,String> fileUpload(MultipartFile headPhoto, HttpServletRequest req) throws IOException {
        //指定文件存储目录为我们项目部署环境下的upload目录
        String realPath=req.getServletContext().getRealPath("/upload");
        System.out.println(realPath);
        //控制文件大小
        if(headPhoto.getSize()>1024*1024*5){
            System.out.println("文件太大了不能上传。");
        }
        //指定文件存储目录
        File dir=new File(realPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        //获取文件名
        String originalFilename=headPhoto.getOriginalFilename();
        //避免文件名冲突,使用uuid替换文件名
       String uuid= UUID.randomUUID().toString();
       //获取拓展名
       String extendsName= originalFilename.substring(originalFilename.lastIndexOf("."));
       //新的文件名
        String newFileName=uuid.concat(extendsName);
        //文件存储位置
        File file=new File(dir,newFileName);
        //将文件名字存到map中
        Map<String,String> map=new HashMap<>() ;
        map.put("photoName",newFileName);
        map.put("filetype",headPhoto.getContentType());
        //文件保存
        headPhoto.transferTo(file);
        return map;
    }
    @ResponseBody
    @RequestMapping("hello.do")
    public String test(){
        return "HelloWorld";
    }
}

注册功能:图片内容类型等信息通过隐藏域表单,封装成一个对象提交给后端,后端通过mybatis框架来将用户的信息保存。

@Controller
public class PlayerController {
    @Autowired
    private PlayerService service;
    @RequestMapping("addPlayer.do")
    public String addPlayer(Player player){
        //调用服务层方法,将数据保存进入数据库
        System.out.println(player);
        //页面跳转至player信息
        service.addPlayer(player);
        System.out.println(player);
        return "redirect:showPlayer.jsp";
    }
    @RequestMapping("getAllPlayer")
    @ResponseBody
    public List<Player> getAllPlayer(){
        return service.getAllPlayer();
    }
}

SpringMVC文件下载功能

8848fccaf11241f89ba0a96fdeb26d37.png

点击下载链接会将对应的图片下载下来。这里我们直接传给后端图片的名字,而不是传给id,这样就不需要后端再去数据库查询一遍。


@Controller
public class FileDownloadController {
    @RequestMapping("fileDownload.do")
    public void fileDownload(String photo, String filetype, HttpServletResponse response) throws IOException {
        //获取下载的文件名  文件类型
        //设置响应头
        response.setHeader("Content-Disposition","attachment;filename="+photo);
        //告诉浏览器要将数据保存到磁盘上,不在浏览器上直接解析
        //告诉浏览器下载的文件类型
        response.setContentType(filetype);
        //获取一个文件的输入流
        InputStream inputStream = new URL("http://localhost:8080/springmvc04_war_exploded/upload/" + photo).openStream();
        //获取一个指向浏览器的输出流
        ServletOutputStream outputStream=response.getOutputStream();
        //向浏览器返回数据即可
        IOUtils.copy(inputStream,outputStream);
    }
}

SpringMVC拦截器

public class MyInterceptor implements HandlerInterceptor {
    /**
     *
     * @param request  请求对象
     * @param response  响应对象
     * @param handler   目标要调用的Handler
     * @return  返回true 为放行,返回false进行拦截
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       /*
         在请求到达我们定义的handler之前工作的,返回的是true,代表放行,可以继续到达handler
        */
        System.out.println("MyInterceptor preHandle");
        /**
         * psot请求编码处理
         */
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        //用户权限控制
        //判断用户有没有登录
        return true;
    }
    /**
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView  controller响应的结果,视图和数据
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor postHandle");
        /*
          handler 处理单元返回ModelAndView的时候进行拦截
         */
        modelAndView.setViewName("");
    }
   /*
     无论是否出现异常都会执行的一个方法
     一般用来做一些资源释放工作
    */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      /*
        页面渲染完毕,但是还没有给浏览器响应数据的时候
       */
        System.out.println("MyInterceptor after Completion");
    }
}

SpringMVC.xml:

  定义拦截器-->
<!--    <mvc:interceptors>-->
<!--        <mvc:interceptor>-->
<!--            <mvc:mapping path="/"/>-->
<!--            <bean class="com.msb.interceptor.MyInterceptor"/>-->
<!--        </mvc:interceptor>-->
<!--    </mvc:interceptors>-->

SpringMVC其他注解

PostMapping:指定当前请求的方式只可以是post请求

GetMapping: 指定当前发送请求的方式只可以是get请求

RestController:书写到类上,代表该类中所有控制单元方法均是ajax响应 相当于@ResponseBody+@Controller

JsonFormat:处理响应json数据的处理

属性: pattern:指定响应时间日期的格式

Timezone:指定响应的时区,否则会有8个小时的时间差

RequestBody:将json字符串转换成一个对象

CrossOrigin:解决ajax请求之间的跨域问题

跨域几个样例:协议不一样,ip不一样,端口不一样,ip不一致

属性:origins:允许可访问的域列表IP,maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
XML JSON fastjson
|
前端开发 JavaScript Java
|
前端开发 Java 网络架构
|
4月前
|
Java API 网络架构
SpringMVC(一)(2)
SpringMVC(一)(2)
25 1
|
5月前
|
JSON 前端开发 Java
|
4月前
SpringMVC(一)(3)
SpringMVC(一)(3)
27 0
|
前端开发 应用服务中间件
SpringMVC4
SpringMVC4
43 0
|
6月前
|
存储 JSON 前端开发
|
6月前
|
XML 前端开发 Java
SpringMvc专题
SpringMvc笔记(持续更新)此方法的执行时机是在控制器方法执行之前,所以我们通常是使用此方法对请求部分进行增强。同时由于结果视图还没有创建生成,所以此时我们可以指定响应的视图。
|
11月前
|
存储 JSON Java
SpringMVC应用
SpringMVC应用
58 0