SpringMvc的请求和响应
SpringMvc的数据响应
1.springmvc的数据相应方式
(1)页面跳转
直接返回字符串
通过ModelAndView对象返回
(2)回写数据
直接返回字符串
返回对象或集合
页面跳转
jsp页面
<%@ 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>
1.返回字符串形式
最出始的写法
@RequestMapping("/quick")public String save(){System.out.println("Controller running ...");return "/jsp/success.jsp";}
由于比较繁琐每次都要加上/jsp/ .jsp,于是直接返回字符串:此种方式将返回字符串与试图解析器的前后缀拼接后跳转
在springmvc.xml配置
<!--配置内部资源解释器--><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/jsp/"></property><property name="suffix" value=".jsp"></property></bean>
@RequestMapping("/quick")public String save(){System.out.println("Controller running ...");return "success";}
2.返回ModelAndView对象
自己手动创建ModelAndView对象,并且设置相应的值
@RequestMapping("/quick2")public ModelAndView save2(){/** model:模型 作用封装数据* view:视图 作用展示数据* */ModelAndView modelAndView = new ModelAndView();//设置模型数据modelAndView.addObject("username","wukd");//设置试图名称modelAndView.setViewName("success");return modelAndView;}
通过框架调用该方法时,传参时传ModelAndView对象
@RequestMapping("/quick3")public ModelAndView save3(ModelAndView modelAndView){//设置模型数据modelAndView.addObject("username","wukd2");//设置试图名称modelAndView.setViewName("success");return modelAndView;}
单独传入model对象
@RequestMapping("/quick4")public String save4(Model model){model.addAttribute("username","你好!");return "success";}
3.向request域中存入对象
(1)通过springmvc框架注入的request对象setAttribute()方法设置
@RequestMapping("/quick5")public String save(HttpServletRequest request){//将数据存储到request域中request.setAttribute("username","lisi");return "success";}
(2)通过ModelAndView的addObject()方法设置
@RequestMapping(value = "/quick5")public ModelAndView save5(){ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("username","klc");modelAndView.setViewName("success");return modelAndView;}
回写数据
1.直接返回字符串
(1)通过springmvc框架注入的response.getWriter().print()回写数据,此时不需要试图跳转,业务方法返回值为void
@RequestMapping("/quick6")public void save6(HttpServletResponse response) throws IOException {response.getWriter().print("kl");}
(2)将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMvc框架,方法返回的字符串不是跳转是直接在http响应体中返回
@ResponseBody//告知Springmvc框架该方法不进行页面视图跳转直接进行页面数据响应(以Http响应体)@RequestMapping(value = "/quick7")public String save7(HttpServletResponse response) throws IOException {return "hellonk";}
(3)在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时可以动手拼接json字符串返回
@ResponseBody()//告知Springmvc框架该方法不进行页面视图跳转直接进行页面数据响应(以Http响应体)@RequestMapping(value = "/quick8")public String save8(HttpServletResponse response) throws IOException {return "{\"username\":\"lisi\",\"age\":18}";}
上述方式手动拼接json格式字符串很麻烦,可以使用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>
@ResponseBody()//告知Springmvc框架该方法不进行页面视图跳转直接进行页面数据响应(以Http响应体)@RequestMapping(value = "/quick9")public String save9(HttpServletResponse response) throws IOException {User user=new User();user.setAge(12);user.setUsername("fhds");//使用json的转换工具将对象转换为json的数据格式ObjectMapper objectMapper = new ObjectMapper();String s = objectMapper.writeValueAsString(user);return s;}
(4)通过springmvc帮助去我们对对象或集合进行json字符串的转换并回写,为处理器配置消息转换参数,指定使用jackson进行对象或集合的转换,在spring-mvc中进行如下配置:
<!--配置处理器映射器--><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>
@ResponseBody()//告知Springmvc框架该方法不进行页面视图跳转直接进行页面数据响应(以Http响应体)@RequestMapping(value = "/quick10")//期望springmvc自动将User转换成json格式public User save10(HttpServletResponse response) throws IOException {User user=new User();user.setAge(13);user.setUsername("fhds");return user;}
在方法上添加@ResponseBody就可返回json格式的字符串,但比较繁琐
可以用mvc的注解驱动代替
<!--mvc的注解驱动 可以将对象转换为json格式--><mvc:annotation-driven conversion-service="conversionService"/>
在SpringMvc的各个组件中,处理器映射器、处理器适配器、试图解析器称为SpringMvc的三大组件 使用<mvc:annotation-driven>自动加载 RequestMappingHandlerMapping(处理映射器)和 RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用 <mvc:annotation-driven>替代注解处理器和适配器的配置。 同时使用<mvc:annotation-driven>默认底层就会集成jackson进行对象或集合的json格式字符串的转换。
springmvc请求数据
1.获得请求参数
服务器端获得请求参数,有时还需要进行数据的封装,springmvc可以接收如下类型的参数:
基本类型
pojo类型参数
数组类型参数
集合类型参数
2.获得基本类型参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配
@ResponseBody()@RequestMapping(value = "/quick11")public void save11(String username,int age) throws IOException {System.out.println(username);System.out.println(age);}
3.获得POJO类型参数
controller中的业务方法的POJO参数的属性名与请求参数的name一致参数值会自动映射匹配
@ResponseBody()@RequestMapping(value = "/quick12")public void save12(User user) throws IOException {System.out.println(user);}
4.获得数组类型的参数
@ResponseBody()@RequestMapping(value = "/quick13")public void save13(String []strs) throws IOException {//将数组转为集合System.out.println(Arrays.asList(strs));}
5.获得集合类型的参数
获得集合类型的参数,要将集合参数封装到POJO中才可以
<%--Created by IntelliJ IDEA.User: dellDate: 2023/2/10Time: 13:17To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<html>
<head><title>Title</title>
</head>
<body><form action="${pageContext.request.contextPath}/userController/quick14" method="post"><%--表明是第几个user对象的usernamr age--%><input type="text" placeholder="姓名" name="userList[0].username"><br/><input type="text" placeholder="年龄" name="userList[0].age"><br/><input type="submit" title="提交"/></form>
</body>
</html>
package com.lin.domain;import java.util.List;public class Vo {private List<User>userList;public List<User> getUserList() {return userList;}public void setUserList(List<User> userList) {this.userList = userList;}@Overridepublic String toString() {return "vo{" +"userList=" + userList +'}';}
}
@ResponseBody()@RequestMapping(value = "/quick14")public void save14(Vo vo) throws IOException {System.out.println(vo);}
当使用ajax提交时,可以指定contextType为json形式,那么在方法参数位置使用
@ResponseBody可以直接接收集合数据而无需使用POJO进行包装
<%--Created by IntelliJ IDEA.User: dellDate: 2023/2/11Time: 12:19To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<html>
<head><title>Title</title><%--导入jquery--%><script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script><script>var userList=new Array();userList.push({username:"张三",age:15});userList.push({username:"lisi",age:15});$.ajax({type:"POST",url:"${pageContext.request.contextPath}/userController/quick15",data:JSON.stringify(userList),contentType:"application/json;charset=utf-8"});</script>
</head>
<body></body>
</html>
注意:如果浏览器抓包工具发现,没有加载jquery文件,原因时springmvc的前端控制器DispatcherServlet的url-pattern配置的时/,代表所有的资源都进行过滤操作我们可以通过以下两种方式放行静态资源
1.在spring-mvc.xml配置问件中指定的放行资源
<!--开放资源的访问权限--><!--mapping 映射地址--><!--location 那个目录下的资源对外开放--><!--<mvc:resources mapping="/js/**" location="/js/"/>-->
2.使用标签
<!--springmvc如果帮你找不到资源就交给原始的的容器Tomcat--><mvc:default-servlet-handler/>
6.当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码过滤
<!--配置全局过滤的filter 解决乱码--><filter><filter-name>CharacterEncodingFilter</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></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
7.参数绑定注解@requestParam
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示绑定
@ResponseBody()@RequestMapping(value = "/quick16")/** @RequestParam参数* value:与请求参数名称* required:在此指定的请求参数是否必须包括,默认值是true,提交时如果没有此参数报错* defaultValue:当没有前指定请求参数时,则使用指定的默认参数值* */public void save16(@RequestParam("name") String username) throws IOException {System.out.println(username);}
8.
@ResponseBody()@RequestMapping(value = "/quick17/{username}")public void save17(@PathVariable("username") String username) throws IOException {System.out.println(username);}
9.自定义类型转换器
自定义类型转换器的开发步骤:
1.定义转换器实现Converter接口
package com.lin.converter;import org.springframework.core.convert.converter.Converter;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class DataConvert implements Converter<String,Date> {@Overridepublic Date convert(String dateStr) {//将日期的字符串转换成日期对象SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");Date date=null;try {date = format.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return date;}
}
2.在配置文件中声明转换器
<!--声明转换器--><bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><list><bean class="com.lin.converter.DataConvert"/></list></property></bean>
3.在<annotation-driver>中引用转换器
<mvc:annotation-driven conversion-service="conversionService"/>
10.文件上传
(1)文件上传客户端的三要素
表单项type="file"
表单的提交方式post
表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”
(2)单文件上传的步骤
导入fileupload和io坐标
<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></dependencies>
配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="defaultEncoding" value="utf-8"></property><property name="maxUploadSize" value="6000000"></property></bean>
编写文件上传代码
@ResponseBody()@RequestMapping(value = "/quick23")public void save23(String username, MultipartFile upload1,MultipartFile upload2) throws IOException {System.out.println(username);//获得上传文件名称String originalFilename1= upload1.getOriginalFilename();upload1.transferTo(new File("C:\\upload\\",originalFilename1));String originalFilename2= upload2.getOriginalFilename();upload1.transferTo(new File("C:\\upload\\",originalFilename2));}
<%--Created by IntelliJ IDEA.User: dellDate: 2023/2/12Time: 11:41To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<html>
<head><title>Title</title>
</head>
<body><form action="${pageContext.request.contextPath}/userController/quick22" method="post" enctype="multipart/form-data">名称<input type="text" name="username"><br/>文件1<input type="file" name="upload"><br/>文件2<input type="file" name="upload"><br/><input type="submit" value="提交"></form><%--enctype:规定了form表单在发送到服务器时候编码方式,有如下的三个值。application/x-www-form-urlencoded:默认的编码方式。但在用文本的传输和MP3等大型文件的时候,使用这种编码就显得效率低下。multipart/form-data:指定传输数据为二进制类型,比如图片,mp3,文件text/plain:纯文本的传输。空格转换为"+"号,但不对特殊字符编码。--%><%--<form action="${pageContext.request.contextPath}/userController/quick22" method="post" enctype="multipart/form-data">名称<input type="text" name="username"><br/>文件1<input type="file" name="upload1"><br/>文件2<input type="file" name="upload2"><br/><input type="submit" value="提交"></form>--%>
</body>
</html>
多文件上传方式的实现
@ResponseBody()@RequestMapping(value = "/quick22")public void save22(String username, MultipartFile[] upload) throws IOException {System.out.println(username);//获得上传文件名称for (MultipartFile multipartFile:upload){String originalFilename = multipartFile.getOriginalFilename();multipartFile.transferTo(new File("C:\\upload\\",originalFilename));}}