Spring应用之MVC

1. 构建SpringMVC项目

1.1 通过Maven构建一个web项目

在这里插入图片描述

1.2 添加相关的依赖

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.7.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <!-- Tomcat插件 --->
  <build>
    <finalName>spring-mvc-demo</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>8082</port>
          <path>/</path>
          <uriEncoding>utf-8</uriEncoding>
        </configuration>
      </plugin>
    </plugins>
  </build>

1.3 创建Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- 映射器 -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <!-- 适配器 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
</beans>

1.4 在web.xml中配置DispatchServlet

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

1.5 创建自定义的Controller

package com.wxw.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        System.out.println("HelloController执行了!!!");
        ModelAndView view = new ModelAndView();
        view.setViewName("/index.jsp");
        return view;
    }

}

1.6 在Spring配置文件中配置Controller

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 映射器 -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <!-- 适配器 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <bean class="com.wxw.controller.HelloController" name="/hello" />

</beans>

1.7 运行测试

启动Tomcat
在这里插入图片描述
访问接口
在这里插入图片描述

2. 基于注解的方式

2.1 修改Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 开启扫描 -->
    <context:component-scan base-package="com.wxw.controller" />
    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven />

</beans>

2.2 创建自定义的Controller

package com.wxw.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("/query")
    public String query(){
        System.out.println("执行【HelloController】的【query】方法!!!");
        return "/index.jsp";
    }

}

2.3 运行测试

在这里插入图片描述

3. SpringMVC中响应请求的方式

3.1 不响应

如果用户提交了请求后服务端不需要给客户端一个响应,那么我们可以指定返回类型为void同时在方法头部添加@ResponseBody注解即可

    @RequestMapping("/save")
    @ResponseBody
    public void add(){
        System.out.println("执行【HelloController】的【save】方法!!!");
    }

3.2 通过字符串返回指定页面

我们可以在处理方法的最后返回一个要跳转的页面地址”/“不要漏了

    @RequestMapping("/query")
    public String query(){
        System.out.println("执行【HelloController】的【query】方法!!!");
        return "/index.jsp";
    }

3.2.1 通过视图解析器添加前后缀

在Spring配置文件中添加视图解析器

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/" />
    </bean>

响应页面时,可以用以下方式简写

    @RequestMapping("/query")
    public String query(){
        System.out.println("执行【HelloController】的【query】方法!!!");
        return "index";
    }

3.3 通过ModelAndView返回

ModelAndView是SpringMVC自带的组件,通过该组件可以返回指定的页面,并且可以绑定返回的参数。

    @RequestMapping("/delete")
    public ModelAndView delete(){
        System.out.println("执行【HelloController】的【delete】方法!!!");
        ModelAndView mm = new ModelAndView();
        mm.setViewName("/index.jsp");
        return mm;
    }

3.4 通过重定向跳转

    @RequestMapping("/update")
    public String update(){
        System.out.println("执行【HelloController】的【update】方法!!!");
        return "redirect:/hello/query";
    }

3.5 通过HttpServletResponse响应

    @RequestMapping("/fun1")
    public void fun1(HttpServletRequest request,
                     HttpServletResponse response) throws Exception {
        System.out.println("执行【HelloController】的【fun1】方法!!!");
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

4. SpringMVC接收请求数据

4.1 基本数据类型

直接在形参中声明要接收的数据,默认情况下前台传来的参数名必须和形参的名称保持一致,可以使用@RequestParam注解指定相关的属性。

    @RequestMapping("/query")
    public String query(@RequestParam(value = "ids",required = true,defaultValue = "123")Integer id,
                        String name){
        System.out.println("执行【HelloController】的【query】方法!!!");
        System.out.println("接收到的参数ids:" + id + ",name:" + name);
        return "index";
    }

4.2 对象接收

使用自定义对象接收时,参数的名称需要与对象的名称保持一致,并且需要提供对应的setter方法。

    @RequestMapping("/save")
    @ResponseBody
    public void add(UserPojo userPojo){
        System.out.println("执行【HelloController】的【save】方法!!!");
        System.out.println("接收到的参数:" + userPojo);
    }

4.3 通过数组接收

http://localhost:8082/hello/delete?ids=1,2,3,4

    @RequestMapping("/delete")
    public ModelAndView delete(String[] ids){
        System.out.println("执行【HelloController】的【delete】方法!!!");
        System.out.println("接收到的参数:" + Arrays.toString(ids));
        ModelAndView mm = new ModelAndView();
        mm.setViewName("index");
        return mm;
    }

4.4 通过集合接收

在形参中不能使用集合接收参数,但是可以把集合封装在自定义对象中用来接收。

package com.wxw.pojo;

import java.util.List;

@Data
public class UserPojo {

    private String name;
    private Integer age;
    private List<String> catNames;

    @Override
    public String toString() {
        return "UserPojo{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", catNames=" + catNames +
                '}';
    }
}
    @RequestMapping("/update")
    public String update(UserPojo userPojo){
        System.out.println("执行【HelloController】的【update】方法!!!");
        System.out.println("接收到的参数:" + userPojo);
        return "redirect:/hello/query";
    }
执行【HelloController】的【update】方法!!!
接收到的参数:UserPojo{name='wangmian', age=20, catNames=[溜溜, 琉璃]}

4.5 自定义转换器

如果客户端传入的是特殊类型的数据,SpringMVC默认提供的转换器无法支持,则可以使用自定义转换器。

package com.wxw.convert;

import org.springframework.core.convert.converter.Converter;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义日期转换器
 */
public class DateConvert implements Converter<String, Date> {

    @Override
    public Date convert(String s) {
        System.out.println("进入【DateConvert】自定义转换器!!!");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sf.parse(s);
        } catch (Exception e){
            System.out.println("日期类型格式错误!!!");
            e.printStackTrace();
        }
        return null;
    }
}

修改配置文件

    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven conversion-service="dateConvert" />

    <!-- 配置自定义转换器 -->
    <bean id="dateConvert" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.wxw.convert.DateConvert"/>
            </set>
        </property>
    </bean>

5. SpringMVC返回响应数据

5.1 ModelAndView返回数据

    @RequestMapping("/hello")
    public ModelAndView hello(String name) {
    	System.out.println("进入【HelloController】的【hello】方法!!!");
        ModelAndView mv = new ModelAndView();
        // 指定返回的页面名称
        mv.setViewName("user");
        // 添加返回的数据
        mv.addObject("msg",name);
        return mv;
    }

返回的页面使用EL表达式绑定返回的数据

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello<br>
${msg}
</body>
</html>

5.2 Map对象返回数据

    @RequestMapping("mapHello")
    public String mapHello(Map<String,Object> map,String name){
    	System.out.println("进入【HelloController】的【mapHello】方法!!!");
        map.put("msg",name);
        return "user";
    }

5.3 Model对象返回数据

    @RequestMapping("modelHello")
    public String modelHello(String name, Model model){
    	System.out.println("进入【HelloController】的【modelHello】方法!!!");
        model.addAttribute("msg",name);
        return "user";
    }

5.4 ModelMap对象返回数据

    @RequestMapping("modelMapHello")
    public String modelMapHello(String name, ModelMap modelMap){
        System.out.println("进入【HelloController】的【modelMapHello】方法!!!");
        modelMap.put("msg",name);
        return "user";
    }

5.5 返回响应数据的作用域

默认情况下返回的数据都是保存在request作用域中的,如果需要将数据保存在session作用域中,只需要在类的头部添加@SessionAttributes注解即可。

@Controller
@RequestMapping("/hello")
@SessionAttributes({"msg"})
public class HelloController {
}

5.6 响应数据乱码问题

  <filter>
    <filter-name>encodeFiletr</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodeFiletr</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

6. SpringMVC文件上传

6.1 引入依赖

    <!-- fileUpload 解析上传的文件用到的jar -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>

6.2 上传页面

文件上传必须使用multipart方式提交

<html>
<body>
<h2>Hello World!</h2>
    <form action="/user/save" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="name"><br>
        头像:<input type="file" name="file"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

6.3 处理器

提交的文件我们可以通过 MultipartFile 类型来接收

    @RequestMapping("fileUpload")
    public String fileUpload(MultipartFile file,String name) throws IOException {
        System.out.println(name);
        System.out.println("文件名称:" + file.getOriginalFilename());
        file.transferTo(new File("d:/" + file.getOriginalFilename()));
        return "index";
    }

6.4 Spring配置文件

    <!--  文件上传的解析器-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

7. SpringMVC文件下载

    @RequestMapping("fileDownload")
    public void fileDownload(HttpServletRequest request,
                               HttpServletResponse response) {
        File file = new File("d://IMG_4942.JPG");
        // 设置响应的头和客户端保存文件名
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition","attchement;filename=" + file.getName());

        try {
            // 打开本地文件流
            InputStream in = new FileInputStream(file);
            // 激活下载的流
            ServletOutputStream out = response.getOutputStream();
            byte[] b = new byte[1024];
            int num = 0;
            while ((num = in.read(b)) != -1){
                out.write(b,0,num);
            }
            out.close();
            in.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

8. SpringMVC访问静态资源

8.1 重新制定Servlet

默认情况下SpringMVC只能访问jsp页面,其他的都会被DispatchServlet拦截,是因为DispatchServlet配置的时候用的/ 覆盖掉了defaultServlet所做的工作,所以我们只需要重新制定即可。

  <filter-mapping>
    <filter-name>encodeFiletr</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

8.2 在配置文件中指定映射规则

<mvc:resources mapping="/img/**" location="/img/"  />

9. SpringMVC中处理JSON数据

9.1 添加依赖

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.8</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.8</version>
    </dependency>

9.2 返回JSON数据

返回JSON数据的方法必须使用@ResponseBody注解修饰

    @RequestMapping("/queryList")
    @ResponseBody
    public List<String> queryList(){
        System.out.println("queryList....");
        return Arrays.asList("111","222","333");
    }

9.3 接收JSON数据

页面提交请求必须为Post,控制器接收的参数必须使用@RequestBody注解修饰

    @RequestMapping("/getJson")
    @ResponseBody
    public UserPojo getJson(@RequestBody UserPojo userPojo){
        System.out.println(userPojo);
        return userPojo;
    }

10. SpringMVC拦截器

自定义拦截器,实现HandlerInterceptor接口

package com.wxw.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    /**
     * 在自定义控制器执行之前执行
     * @param request
     * @param response
     * @param handler
     * @return
     *    false  拦截
     *    true 放过
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        return true;
    }

    /**
     * 自定义控制器执行后执行
     *      在返回ModelAndView之前执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    /**
     * 自定义控制器执行后执行
     *     在返回ModelAndView之后执行
     * @param request
     * @param response
     * @param handler
     * @param ex
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

在Spring配置文件中注册拦截器

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.wxw.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值