美文网首页
SpringMVC 原理与实战 (第二篇)

SpringMVC 原理与实战 (第二篇)

作者: 楊柯林 | 来源:发表于2019-07-07 11:07 被阅读0次

2 SpringMVC的请求和响应

2.1 对象及基本数据相应方式

综述

  1. 页面跳转
    • 直接返回字符串
      (与视图解析器前后缀拼接 )
      问题:重定向不加web-inf ?
      (web-inf是安全目录,重定向访问不到web-inf,只能靠转发)
    • 通过ModelAndView对象
  2. 回写数据
    • 直接返回字符串
    • 返回对象或集合
2.1.1 SpringMVC的数据响应返回ModelAndView形式1
@RequestMapping(value="/quick2")
    public ModelAndView save2(){
        /*
            Model:模型 作用封装数据
            View:视图 作用展示数据
         */
        ModelAndView modelAndView = new ModelAndView();
        //设置模型数据
        modelAndView.addObject("username","Colin");
        //设置视图名称
        modelAndView.setViewName("success");

        return modelAndView;
    }
2.1.2 SpringMVC的数据响应返回ModelAndView形式2
@RequestMapping(value='/quick3')
public ModelAndView save3(ModelAndView modelAndView){
    modelAndView.addObject("username","Tom")
    modelANdView.setViewName("success");
    return modelAndView;
}

@RequestMapping("/quick4")
public String save4(Model model){
    model.addAttribute("username","Jerry")
    return "success";
}

2.1.3 SpringMVC的数据响应返回ModelAndView形式3
@RequestMapping("/quick5")
public String save5(HttpServletRequest request){
    request.setAttribute("username","哈哈");
    return "success.jsp"
 }

2.1.4 回写数据

1 不采用spring转换工具直接回写
@RequestMapping("/quick6")
@ResposeBody //告诉springmvc不要进行页面跳转,直接回写数据
public String save() thows IOException{
   return "hello world";
}

@RequestMapping("/quick7")
public void save(HttpServletRequest request) throws IOException{
   response.getWriter().print("hello world")
}

 @RequestMapping("/quick7_1")
public void save(HttpServletRequest request) throws IOException{

  //返回中文必须要加 setContextType
  response.setContextType("text/html;charset=utf-8")
   response.getWriter().print("哈哈")
}

 //返回中文必须要加 produce
 @RequestMapping(values="/quick7_2",produces="text/html;charset=utf-8")
public void save(HttpServletRequest request) throws IOException{
   response.getWriter().print("哈哈")
}

@RequestMapping("/quick8")
@ResponseBody
public String save() throws IOExceptioin{
   //这样写要记得"是要进行转义的
   return "{"username":"zhangsan","age":18}"   
}

@RequestMapping("/quick9")
@ResponseBody
public String save() throws IOExceptioin{
   User user= new User();
   user.setUsername("lisi");
   user.setAge(20);
   //1.使用json转换工具对象转换成json字符串
   //2.导入jackson-core,datablind,annotions 包
   ObjectMapper om= new ObjectMapper();
   String json=om.writeValueAsString(user)
   return json; 
}
2 返回对象和集合

期望SpringMVC自动将User转换成json格式的字符串
(同样要配置jackson的三个包)

增强处理器适配器

mvc注解驱动
在spring-mvc.xml中配置

<mvc:annotation-driven/>

等同与配置处理器映射器和处理器适配器

@RequestMapping("/quick10")
 @ResponseBody
 public User save() throws IOExceptioin{
    User user= new User();
    user.setUsername("lisi");
    user.setAge(20);
    return user; 
 }

注意 modelAndView的setViewName方法只能设置转发路径,不能对重定向,重定向只能通过返回String来设置

2.2 SpringMVC 获得请求参数

2.2.1 获得请求参数
  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型参数
2.2.2 获得基本类型参数

Controller中的业务方法的参数名称要与请求参数的name一致

@RequestMapping("save11")
@ResponseBody
public void save11(String username,int age) throws IOException{
System.out.println(username);
System.out.println(age);
}
2.2.3 获得POJO类型参数

Controller中的业务方法的POJO参数名称要与请求参数的name一致,参数值会自动映射匹配

  • 有实体类
  • 浏览器传奇参数一致
@RequestMapping("save12")
@ResponseBody
public void save12(User user) throws IOException{
System.out.println(user);
}
2.2.4 获得数组类型参数

Controller中的业务方法的数组名称要与请求参数的name一致,参数值会自动映射匹配

?strs=aaa&strs=bbb
//请求参数
@RequestMapping("save12")
@ResponseBody
public void save13(String[] strs) throws IOException{
System.out.println(Arrays.asList(strs));
}
2.2.5 获得集合参数类型

获得集合参数时,要将集合参数包装到一个POJO中才可以。

<form action="${pageContext.request.contextPath}/user/quick14" method="post">
<%--表明是第一个User对象的username age--%>
<input type="text" name="userList[0].username"><br/>
<input type="text" name="userList[0].age"><br/>
<input type="text" name="userList[1].username"><br/>
<input type="text" name="userList[1].age"><br/>
<input type="submit" value="提交">
</form>

一般做实体类型的集合包装对象都以VO命名

package com.itheima.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;
}
@Override
public String toString() {
return "VO{" +
"userList=" + userList +
'}';
}
}
@RequestMapping(value="/quick14")
@ResponseBody
public void save14(VO vo) throws IOException {
System.out.println(vo);
}
2.2.6 异步提交的集合获取

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装
(NOTICE! 需要参数上加注解)

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
<script>
var userList = new Array();
userList.push({username:"zhangsan",age:18});
userList.push({username:"lisi",age:28});
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/user/quick15",
data:JSON.stringify(userList),
contentType:"application/json;charset=utf-8"
});
</script>
@RequestMapping(value="/quick15")
@ResponseBody
public void save15(@RequestBody List<User> userList) throws IOException {
System.out.println(userList);
}

2.3 springmvc传输数据工具类

2.3.1 静态资源访问的开启

当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

  • spring-mvc.xml 下配置
//资源放行,mapping 映射访问的资源字符串,location 为被映射的网站资源路径
<mvc:resources mapping="/js/**" location="/js/"/>
  • spring-mvc.xml 下配置
//采用自带的方法,让前端控制器放行
<mvc:default-servlet-handler/>
2.3.2 SpringMVC的请求-获得请求参数-配置全局乱码过滤器

问题: post请求传输乱码
解决办法: 设置过滤器对编码的过滤

<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>

问题: 以上方法并不能解决get乱码问题
解决办法:在tomcat的service.xml中配置

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
2.3.3 SpringMVC的请求-获得请求参数-参数绑定注解@RequestParam(应用)

问题: 请求的参数名称与Controller的业务方法参数名称不一致时
解决办法: 通过@RequestParam注解显示的绑定

<form action="${pageContext.request.contextPath}/quick16" method="post">
<input type="text" name="name"><br>
<input type="submit" value="提交"><br>
</form>

在参数前绑定@RequestParam

@RequestMapping(value="/quick16")
@ResponseBody
public void save16(@RequestParam(value="name",required = false,defaultValue = "itcast") String username) throws IOException {
System.out.println(username);
}
2.3.4 SpringMVC的请求-获得请求参数-自定义类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
问题: 日期类型的数据就需要自定义转换器。
解决办法: 自己配置自定义转换器
1.定义转换器实现Converter接口

public class DateConverter implements Converter<String,Date>{
public Date convert(String dateStr){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
Date date=format.parse(dateStr);
return date
}
}

2.在配置文件中声明转换器,spring-mvc.xml里声明转换器

<bean id=""conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.itheima.converter.DateConverter"></bean>
</list>
</property>
</bean>
//spring-mvc.xml里
<mvc:annotation-driven conversion-service="conversionService">

2.5 其他

2.5.1 原始ServletAPI注入

同样SpringMvc支持原始ServletAPI对象作为控制器方法的参数进行注入,常用对象如下
HttpServletRequest
HttpServletResponse
HttpSession

2.5.2 获得请求头信息

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
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);
}

使用@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);
}

2.6 Restful风格

2.6.1 restful 风格
  • 架构风格,设计风格
  • GET: 获取资源
  • POST: 新建资源
  • PUT: 更新资源
  • DELETE: 删除资源
    实现: /user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。
    1.地址栏输入
    http://localhost:8080/quick17/zhangsan`
    2.controller下
@RequestMapping(value="/quick17/{name}")
@ResponseBody
public void save17(@PathVariable(value="name") String username) throws IOException {
System.out.println(username);
}

相关文章

网友评论

      本文标题:SpringMVC 原理与实战 (第二篇)

      本文链接:https://www.haomeiwen.com/subject/xskbhctx.html