SpringMVC —— 响应和请求处理

发布于:2025-09-09 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、前言

本文需要导入的坐标:(SpringMVC框架)

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

请先阅读上一篇:SpringMVC —— Spring集成web环境和SpringMVC快速入门-CSDN博客

二、SpringMVC响应处理

(1)页面跳转测试

1.准备工作

首先需要准备dao层和service层的接口及其实现类:

dao层:

public interface UserDao {
    public void save();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("save running...");
    }
}

service层:

public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {

    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
}

同时需要依赖注入到app配置文件:

        <bean id="userDao" class="com.yds.dao.impl.UserDaoImpl"></bean>

        <bean id="userService" class="com.yds.service.impl.UserServiceImpl">
            <property name="userDao" ref="userDao"></property>
        </bean>

2.字符串转发

首先准备一个跳转的目标JSP文件success:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>

这里我们摒弃掉传统的Servlet类,使用注解来创建高度封装的Controller类

我们希望跳转到webapp中的jsp软件包中的success.jsp文件,可以直接return字符串(上一篇末尾提到的)

@Controller
@RequestMapping("/user")
public class UserController {

@RequestMapping(value = "/quick")
    //返回字符串
    public String save() {
        System.out.println("Controller save running...");
        //在配置内部资源视图解析器后直接使用success:
        return "/jsp/success.jsp";
    }
}

网页和控制台效果如下:

但是每次都需要写前后缀很麻烦,所以我们这里使用配置内部资源视图解析器来统一添加前后缀:

 <!--    配置内部资源视图解析器(自动指定前后缀)-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

所以我们可以将代码优化为:

@RequestMapping(value = "/quick")
    //返回字符串
    public String save() {
        System.out.println("Controller save running...");
        //在配置内部资源视图解析器后直接使用success:
        return "/jsp/success.jsp";
    }

效果当然也是一样的,这里就不赘述了。

3.返回ModelAndView对象

这里达到的效果和字符串转发是一样的,但是引入了ModelAndView类,SpringMVC框架允许通过返回ModelAndView类的对象来进行跳转操作。

@RequestMapping(value = "/quick2")
    //返回ModelAndView对象
    public ModelAndView save2() {
        //Model:模型 作用:封装数据
        //View:视图:展示数据
        ModelAndView modelAndView = new ModelAndView();
        //设置模型数据
        modelAndView.addObject("username", "yds");
        //设置视图名称
        modelAndView.setViewName("success");
        return modelAndView;
    }

这里我们将yds存储在模型中,把JSP文件储存到视图中,为了测试模型数据是否存储成功,我们需要改动JSP文件,添加EL表达式:

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

测试结果如下:

4.使用形参来创建对象

同样使用ModelAndView的办法,唯一的改动就是创建对象可以在形参中创建,这是SpringMVC框架提供的简化办法,也是后面最常用的方法。

@RequestMapping(value = "/quick3")
    //从形参创建一个ModelAndView对象,然后设置数据、设置视图
    public ModelAndView save3(ModelAndView modelAndView) {
        modelAndView.addObject("username", "xzt");
        modelAndView.setViewName("success");
        return modelAndView;
    }

当然是一样的效果:

5.混合使用

@RequestMapping(value = "/quick4")
    //混合使用也可以
    public String save4(Model model) {
        model.addAttribute("username", "印东升");
        return "success";
    }

这里我们不再设置视图,只设置模型中的数据,然后使用字符串转发,这样的方式也可以成功运行:

6.使用request这样的ServletAPI

 @RequestMapping(value = "/quick5")
    //不常用,使用了servlet的东西(尽量使用mvc框架提供的东西)
    public String save5(HttpServletRequest request) {
        request.setAttribute("username", "熊梓彤");
        return "success";
    }

注意:这是以前Servlet设置文本域的方式,尽量使用Springmvc框架提供的东西,所以少用。

当然效果是一样的:

(2)回写数据测试

1.使用Servlet的API回写数据

@RequestMapping(value = "/quick6")
    //和quick5类似,回显数据
    public void save6(HttpServletResponse response) throws IOException {
        response.getWriter().print("hello yds");
    }

效果如下:

2.使用注解@ResponseBody

使用@ResponseBody注解,告诉Springmvc框架,不进行视图跳转,直接进行数据响应,这一个方式很重要!!!后面基本上都是使用这个方式来进行数据回写。

@RequestMapping(value = "/quick7")
    //使用@ResponseBody注解,告诉mvc框架,不进行视图跳转,直接进行数据响应//重要!!!
    @ResponseBody
    public String save7() throws IOException {
        return "hello xzt";
    }

效果如下:

3.回写Json格式字符串

这里我们手写Json格式,当然是最复杂的方式了,这里仅供测试:

@RequestMapping(value = "/quick8")
    //回写Json格式字符串
    @ResponseBody
    public String save8() throws IOException {
        return "{\"username\":\"yds\",\"age\":20}";
    }

效果如下:

4.使用json的转换工具

这里首先需要添加工具坐标,这里我们使用Jackon

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>
 @RequestMapping(value = "/quick9")
    //使用json的转换工具将对象转换成json格式字符串再返回
    @ResponseBody
    public String save9() throws IOException {
        User user = new User();
        user.setName("yds");
        user.setAge("20");
        //使用json的转换工具将对象转换成json格式字符串再返回
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);

        return json;
    }

效果如下:

5.SpringMVC自动转换

要想使用自动转换,首先需要在mvc配置中配置处理器映射器:(也可以用下面的驱动代替,原理是注解@ResponseBody中允许返回Json格式的字符串,使用只要加载处理适配器的驱动就可以实现自动转换)

<!--    配置处理器映射器(可以由下面的驱动替代)-->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
                </list>
            </property>
        </bean>

 <mvc:annotation-driven/>
@RequestMapping(value = "/quick10")
    //mvc将User自动转换为Json格式的字符串(需要在xml中配置)
    @ResponseBody
    public User save10() throws IOException {
        User user = new User();
        user.setName("印东升");
        user.setAge("88");

        return user;
    }

效果如下:

三、SpringMVC请求处理

(1)请求处理

1.获得基本数据类型

//获得基本数据类型
    @RequestMapping(value = "/quick11")
    @ResponseBody//还是要写
    public void save11(String username, int age) throws IOException {
        System.out.println(username);
        System.out.println(age);
    }

注意:这里尽管是处理请求,返回值也是void,但是仍然要写 @ResponseBody来标志不是页面跳转,否则响应体为void,会报404。

拼接参数username和age:

效果如下:

2.获得Pojo类型

这里框架会自动封装参数到Pojo中:

//获得pojo类型 会自动封装
    @RequestMapping(value = "/quick12")
    @ResponseBody
    public void save12(User user) throws IOException {
        System.out.println(user);
    }

效果如下:

3.获得数组类型

注意:这里的参数必须和形参相同,否则会被判定为空

@RequestMapping(value = "/quick13")
    @ResponseBody
    public void save13(String[] strs) throws IOException {
        System.out.println(Arrays.toString(strs));
    }

效果如下:

4.获得集合类型(放pojo中)

获得集合类型有两种方式,第一种需要使用包装对象来实现转换,原因是请求不能是泛型,所以我们这里创建一个VO(valueObject)包装类,用来包装集合,最后只需要将请求参数设置为包装对象即可:

public class VO {

    private List<User> userList;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    @Override
    public String toString() {
        return "VO{" +
                "userList=" + userList +
                '}';
    }
}
@RequestMapping(value = "/quick14")
    @ResponseBody
    public void save14(VO vo) throws IOException {
        System.out.println(vo);
    }

这里为了测试,我们创建一个JSP文件,并且创建一个表单:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/user2/quick14" method="post">
<%--        表明是第几个User对象的username age--%>
      <input type="text" name="userList[0].name"><br/>
      <input type="text" name="userList[0].age"><br/>
      <input type="text" name="userList[1].name"><br/>
      <input type="text" name="userList[1].age"><br/>
        <input type="submit">
    </form>
</body>
</html>

输入后结果如下:

5.获得集合类型(直接转化为json)

这里我们使用注解@RequestBody,可以直接接收集合数据,不需要再包装了。

//获得集合类型(直接转化为json)
    @RequestMapping(value = "/quick15")
    @ResponseBody
    public void save15(@RequestBody List<User> userList) throws IOException {
        System.out.println(userList);
    }

由于是直接转化为Json,使用这里我们需要写一个ajax文件来进行测试:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>Title</title>
  <script src="${pageContext.request.contextPath}/js/jquery.js"></script>
  <script>
    var userList = new Array();
    userList.push({name:"印东升",age:20});
    userList.push({name:"zy",age:19});

    $.ajax({
      type:"POST",
      url:"${pageContext.request.contextPath}/user2/quick15",
      data:JSON.stringify(userList),
      contentType:"application/json;charset=utf-8"
    });

  </script>
</head>
<body>

</body>
</html>

注意:这里ajax无法访问jquery.js,因为是静态资源,所以需要使用以下任意一种方式来开启静态资源的访问。

<!--    开放(静态)资源的访问-->
<mvc:resources mapping="/js/**" location="/js/"/>

<!--    让tomcat去找静态资源-->
<mvc:default-servlet-handler/>

效果如下:

6.参数绑定注解@RequestParam

注解@RequestParam还有如下参数可以使用:  

value: 与请求参数名称

required: 此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错

defaultValue: 当没有指定请求参数时,则使用指定的默认值赋值 

//参数绑定注解@RequestParam(将"name"映射到username)
    @RequestMapping(value = "/quick16")
    @ResponseBody
    public void save16(@RequestParam(value = "name", required = false, defaultValue = "印东升") String username) throws IOException {
        System.out.println(username);
    }

如果我们的请求参数是name,才会赋值给username,否则就采用默认的值。

7.获取Restful风格的参数

//获取Restful风格的参数(http://localhost:8080/spring_mvc_2/user2/quick17/yds)
    @RequestMapping(value = "/quick17/{username}")
    @ResponseBody
    public void save17(@PathVariable("username") String username) throws IOException {
        System.out.println(username);
    }

效果如下:

8.自定义类型转换器

首先我们需要创建一个日期转换器,让我们用一定的格式(yyyy-MM-dd)来将这样的格式字符串转化为Date类型数据:

public class DateConverter implements Converter<String,Date> {
    @Override
    public Date convert(String dateStr) {
        //将日期字符串转换成日期对象,返回
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return date;
    }
}

然后我们需要声明这个转换器并加载驱动:

<!--    声明转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.yds.converter.DateConverter"></bean>
            </list>
        </property>
    </bean>
<!--    转换日期的驱动-->
    <mvc:annotation-driven conversion-service="conversionService"/>
//自定义类型转换器(需要配置声明转换器)
    //http://localhost:8080/spring_mvc_2/user2/quick18?date=2025-9-4
    @RequestMapping(value = "/quick18")
    @ResponseBody
    public void save18(Date date) throws IOException {
        System.out.println(date);
    }

输入网址后效果如下:

9.获取Servlet相关的API

类似用Servlet回写数据,在形参声明这几个对象,框架就可以获取:

//获取Servlet相关的API
    @RequestMapping(value = "/quick19")
    @ResponseBody
    public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
    }

效果如下:

10.获取请求头

使用注解@RequestHeader

@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)

 ● value:请求头的名称

 ● required:是否必须携带此请求头

@RequestMapping(value = "/quick20")
    @ResponseBody                   //这里参数的名称需要和标准请求头参数的名称相同(这里尝试获取浏览器版本)
    public void save20(@RequestHeader(value = "User-Agent", required = false) String user_agent) throws IOException {
        System.out.println(user_agent);
    }

效果如下:

11.获得指定Cookie的值

使用@CookieValue可以获得指定Cookie的值

@CookieValue注解的属性如下:

● value:指定cookie的名称 

● required:是否必须携带此cookie

@RequestMapping(value = "/quick21")
    @ResponseBody
    public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
        System.out.println(jsessionId);
    }

效果如下:

12.单文件上传和下载

首先要配置文件上传解析器:

 <!--    配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="maxUploadSize" value="500000"/>
        <property name="maxUploadSizePerFile" value="500000"/>
    </bean>
@RequestMapping(value = "/quick22")
    @ResponseBody
    public void save22(String username, MultipartFile uploadFile,MultipartFile uploadFile2) throws IOException {
        System.out.println(username);
//        System.out.println(uploadFile);
        //获得上传文件的名称
        String originalFilename = uploadFile.getOriginalFilename();
        uploadFile.transferTo(new File("C:\\upload\\"+ originalFilename));

        //多文件上传(第二个,其实跟第一个也一样)
        String originalFilename2 = uploadFile2.getOriginalFilename();
        uploadFile2.transferTo(new File("C:\\upload\\"+ originalFilename2));

    }

我们创建一个JSP文件用于测试:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/user2/quick22" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="username"><br/>
    文件:<input type="file" name="uploadFile"><br/>
    文件:<input type="file" name="uploadFile2"><br/>
    <input type="submit" value="提交"><br/>
</form>

</body>
</html>

输入后效果如下:

13.多文件上传和下载

更改一下JSP文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>

<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user2/quick23" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="username"><br/>
    文件:<input type="file" name="uploadFile"><br/>
    文件:<input type="file" name="uploadFile"><br/>
    <input type="submit" value="提交"><br/>
</form>
<form action="${pageContext.request.contextPath}/user2/quick22" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="username"><br/>
    文件:<input type="file" name="uploadFile"><br/>
    文件:<input type="file" name="uploadFile2"><br/>
    <input type="submit" value="提交"><br/>
</form>

</body>
</html>

用遍历的方式来循环上传:

@RequestMapping(value = "/quick23")
    @ResponseBody
    public void save23(String username, MultipartFile[] uploadFile) throws IOException {
        System.out.println(username);
        for (MultipartFile multipartFile : uploadFile) {
            String originalFilename = multipartFile.getOriginalFilename();
            multipartFile.transferTo(new File("C:\\upload\\" + originalFilename));
        }

    }

输入后效果如下:


网站公告

今日签到

点亮在社区的每一天
去签到