springmvc参数处理
在前一篇文章中,已经简单介绍了springmvc的入门,了解了如何去配置请求路径以及如何进行简单的视图页面跳转,在这篇文章中,会着重介绍如何接收不同类型的参数,以及怎么返回值和返回值的不同处理
数据响应
首先呢,先来说说springmvc对于数据响应的处理,springmvc对于参数的接收分为两大类:
- 页面跳转
- 直接返回字符串
- 通过模型和视图对象返回
- 回写数据
- 直接返回字符串
- 返回对象或集合
- 页面跳转-直接返回字符串
@RequestMapping(value = "/quick")
public String test01() {
System.out.println("controller is running");
// 直接返回一个字符串,跳转到error页面,若没有该页面,则报404错误!
return "error.jsp";
}
- 这里要注意一个问题,如果你的类上也加了
@RequestMapping("/xxx")
,那在返回的时候必须是"/error.jsp"
,因为如果写成上面代码那样,就会报404错误,具体原因呢,其实很简单,因为你在web.xml
中配置前端控制器时的映射路径是/
,是相对访问路径的,访问的时候路径就是/xxx/error.jsp
,如果是"/error.jsp"
,是相对项目路径的,访问路径就是"/error.jsp"
- 每次我们需要跳转时,都需要写xxx.jsp或者/xxx.jsp,我们可以通过配置视图解析器,加上默认的前后缀进行简化我们的处理
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
- 上述跳转页面代码可以写成
return "error";
- 其实这种配置我们可以通过阅读官方提供的配置文件即可进行简单配置
- 在spring-webmvc这个包下,org/springframeword/web/servlet中,有个叫DispatcherServlet.properties的配置文件,里面就有一些对于springmvc各个组件的默认配置,我们可以通过在spring-mvc.xml中进行配置,覆盖掉原有配置
- 页面跳转-通过模型和视图对象
@RequestMapping(value = "/quick")
public ModelAndView test02() {
// 创建模型和视图对象
ModelAndView modelAndView = new ModelAndView();
// 给对象添加数据模型,这句话简单理解其实就是把username保存到reqeuest域中,jsp页面可以直接通过el或jstl表达式获取
modelAndView.addObject("username", "itCast");
// 给对象添加视图对象,就是要跳转的页面
modelAndView.setViewName("error.jsp");
return modelAndView;
}
@RequestMapping("/quick")
public String test03(HttpServletRequest request){
// 也可以使用原来的方式进行存放数据,当然,这种做法并不推荐
request.setAttribute("name","zhangsan");
return "index";
}
- 回写数据-直接返回字符串
@RequestMapping("/quick")
public void test04(HttpServletResponse response) throws
IOException {
// 这种方式其实也是利用了原来的servlet对象,并不推荐
response.getWriter().print("hello world");
}
@RequestMapping("/quick")
// 该注解的作用就是让返回的字符串不进行跳转,而是放在响应体中返回
@ResponseBody
public String test05() throws IOException {
return "hello springMVC!!!";
}
- 在开发中,我们常常要使用json格式的字符串进行交互,简单的我们当然可以手动拼接,但是一般都数据量比较大,必须借助工具来简化我们的重复操作,这里介绍了jackson的使用
- 导入jackson坐标
<!--jackson-->
<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>
- 通过jackson将数据对象转换为json字符串
@RequestMapping("/quick")
// 因为json也是一个字符串数据,因此这里也需要加此注解
@ResponseBody
public String test06() throws IOException {
Person person = new Person();
person.setUsername("zhangsan");
person.setAge(18);
ObjectMapper objectMapper = new ObjectMapper();
String res = objectMapper.writeValueAsString(person);
return res;
}
- 回写数据-返回对象或集合
我们可以通过对springmvc提供的处理器适配器进行简单的配置,指定使用jackson进行转换替代上述操作
<bean class="org.springframework.web.servlet.mvc.method.annotation
.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
@RequestMapping("/quick")
@ResponseBody
public User test07() {
Person person = new Person();
person.setUsername("zhangsan");
person.setAge(18);
return person;
}
- 上述配置稍显麻烦,这里呢,提到一个概念,springmvc三大组件,分别的处理器映射器、处理器适配器、视图解析器,为了简化开发,springmvc提供了一个注解驱动
<mvc:annotation-driven/>
- 这个注解驱动可以帮我们自动加载处理器映射器和处理器适配器,也就是说我们不用像上面一样,自己去查看配置文件,还得亲自配置jackson。
- 同时呢,注解驱动底层自动帮我们继承了jackson,以此来进行对象和json字符串的格式转换,是不是非常nice
获得请求数据
springmvc 支持接收以下几种数据类型:
- 基本类型参数
- POJO类型参数
- 数组类型参数
- 集合类型参数
- 获取基本参数
- 请求url:
localhost:8001/web/quick?username=zhangsan
- 接收username
@RequestMapping("/quick")
@ResponseBody
public void test08(String username) {
System.out.println(username);
}
- 注意:这里的请求参数名称要和形参名称一致,否则会找不到
- 获取POJO类型参数
- 请求url
localhost:8001/web/quick?name=zhangsan&age=18
- 接收参数
public class User {
private String name;
private int age;
getter/setter…
}
@RequestMapping("/quick")
@ResponseBody
public void test09(User user) {
System.out.println(user.getName() + "----" + user.getAge());
}
- 注意:同样要求请求的参数名和POJO的属性名一致,参数值会自动根据名称映射匹配
- 获取数组类型参数
- 请求url
localhost:8001/web/quick?str=aaa&str=bbb&str=ccc
- 接收参数
@RequestMapping("/quick")
@ResponseBody
public void test10(String[] str) {
System.out.println(Arrays.toString(str));
}
- 注意:要求数组名和参数名称一致,参数值会自动根据名称映射匹配
- 获取集合类型参数-通过VO类
- 该方式和其他三种方式不一样,获取集合参数需要将集合封装到一个VO类中,此处呢,使用一个表单提交来演示
<form action="${pageContext.request.contextPath}/quick8" method="post">
<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" value="提交">
</form>
public class User {
private String name;
private int age;
getter/setter…
}
public class VO {
private List<User> userList;
getter/setter...
}
@RequestMapping("/quick")
@ResponseBody
public void test11(VO vo) {
System.out.println(vo);
}
- 表单name属性要求与集合名称一致,且集合对象中封装的对象的属性要和其请求的参数名一致,也就是集合.参数的参数名称
- 获取集合类型参数-通过异步提交方式
- 当使用异步提交方式时,可以指定contentType为json形式,且在参数位置加上@RequestBody可以直接接收集合数据类型而无需POJO进行包装
<script src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script>
let userList = [];
userList.push({name: "张三", age: 18});
userList.push({name: "李四", age: 28});
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/quick",
data: JSON.stringify(userList),
contentType: "application/json;charset=utf-8"
});
</script>
@RequestMapping("/quick")
@ResponseBody
public void test12(@RequestBody List<User> userList) {
System.out.println(userList);
}
- nice的一件事情发生了,报错了,来来来,看看报错原因,打开开发者工具,发现jQuery.js文件没有加载,为啥嘞,因为前端控制器的配置中,DispatcherServlet的urlpattern是"/",表示对所有资源请求进行过滤操作,大概意思就是前端控制器收到客户端的请求后要帮你进行虚拟路径的匹配,也就是
@RequestMapping("xxx")
,但是我们可以明显看到jquery.js不是一个请求映射,所以前端控制器找不到,就报了404错误 - 解决方式有两种,一种是针对某个文件或者文件夹进行静态资源的放行,另一种是当前端控制器没有找到对应路径时,交给默认的容器去找该资源,这里呢其实就是交给了tomcat这个容器
- 第一种-有针对性的放行
<!--配置对js文件夹下所有的静态资源放行-->
<mvc:resources mapping="/js/**" location="/js/"/>
- 第二种-找不到就不管了
<!--交由tomcat容器去找-->
<mvc:default-servlet-handler/>
绳锯木断、水滴石穿