SpringMVC前后端数据交互

前端到后端

1、占位符

原始方式:/deleteUser?id=1
rest方式:/deleteUser/1
SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参

<a th:href="@{/testRest/1/admin}">测试路径中的占位符-->/testRest</a><br>
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id") String id,
@PathVariable("username") String username){ System.out.println("id:"+id+",username:"+username);
return "success"; }//最终输出的内容为-->id:1,username:admin

2、通过ServletAPI获取

将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象
直接构造指令

@RequestMapping("/test")
public String testParam(HttpServletRequest request)
{ 
String username = request.getParameter("username"); 
String password = request.getParameter("password"); 
System.out.println("username:"+username+",password:"+password);
 return "success"; }
<a th:href="@{/test(username="wpp",password="1234"}">测试路径servlet获取参数>/testRest</a><br>

占位符方式与这种方式不能一起使用

3、通过控制器方法的形参获取请求参数

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参

    @RequestMapping(value = "first2")
    public String first2(String username,String password,String hobby){
        System.out.println(username+"\n"+password+"\n"+hobby);
        return "first";
    }
<form th:action="@{/first2}" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    爱好:<input type="checkbox" name="hobby" value="a">a
    <input type="checkbox" name="hobby" value="b">b
    <input type="checkbox" name="hobby" value="c">c<br>
    <input type="submit" value="登录">
</form>

登录发送的请求

http://localhost:8080/SpringMVC/first2?username=admin&password=12&hobby=a&hobby=b

输出:

admin
12
a,b

注意:
发送页面会对密码明文显示,可以将前端发送方法改为post;
String hobby 也可以根据实际为字符串数组的方式变为 String[] hobby;
若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串;
数组或者字符串类型的形参接收此请求参数;
若使用字符串数组类型的形参,此参数的数组中包含了每一个数据;
若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果。

4、@RequestParam、@RequestHeader、@CookieValue

@RequestParam是将请求参数和控制器方法的形参创建映射关系
@RequestParam注解一共有三个属性:
value:指定为形参赋值的请求参数的参数名
required:设置是否必须传输此请求参数,默认值为true
若设置为 true 时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置
defaultValue 属性,则页面报错400:Required String parameter ‘xxx’ is not present;若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null
defaultValue :不管required属性值

    @RequestMapping(value = "first3")
    public String first3(@RequestParam(value = "username", required = false, defaultValue = "hehe") String username,
                         String password,
                         String[] hobby,
                         @RequestHeader(value = "Host", required = false, defaultValue = "header") String header,
                         @CookieValue(value = "JSESSIONID", required = false, defaultValue = "default_session") String Jsessionid){
        System.out.println(username+"\n"+password+"\n"+ Arrays.toString(hobby));
        System.out.println("JSESSIONID:"+Jsessionid+"\nheader"+header);
        return "first";
    }
    }

@RequestHeader是将请求头信息和控制器方法的形参创建映射关系
@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
@CookieValue是将cookie数据和控制器方法的形参创建映射关系
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
获取 Cookie 和 Header 实际上也可以用HttpServletRequest的方法获取。

5、通过实体类获取请求参数

可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值

<form th:action="@{/first4}" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    性别:<input type="radio" name="sex" value=""><input type="radio" name="sex" value="">女
    邮箱:<input type="email" name="email"><br>
    <input type="submit" value="登录">
</form>

如果参数太多可以采用实体类的方式

public class User {
   private String username;
   private String password;
   private String sex;
   private String email;
   。。。。。省略getter、setter、构造方法及toString等方法
   }
    @RequestMapping(value = "first4")
    public String first4(User user){
        System.out.println(user);
        return "first";
    }

得到结果
User{username=‘11’, password=‘22’, sex=’??·’, email=‘w2@qq.com’}
会发现有 sex 的乱码,因此需要解决乱码问题
这个可以在tomcat里设置utf-8的编码方式,不过在这里将会使用过滤器的方式来解决这个问题。
通过在web.xml配置的拦截器的方式能够很好的解决这个问题。

    <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>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

域对象共享数据(四种)

Request域对像

生命周期:一次请求

利用ServletAPIRequest

    @RequestMapping(value = "/testServletRequest")
    public String testServletRequest(HttpServletRequest request){
        request.setAttribute("test","value");
        return "success";
    }
   

利用ModelAndView

    @RequestMapping(value = "/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("test","modelandview");
        Map<String,Integer> map = new HashMap<>();
        map.put("test1",1);
        map.put("test2",2);
        mv.addObject("test","modelandview");
        mv.addObject("map",map);
        mv.setViewName("success");
        return mv;
    }
   

利用Model

   @RequestMapping("/testModel")
    public String testModel(Model model) {
        model.addAttribute("test", "hello,Model");
        return "success";
    }

利用Map

   @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map) {
        map.put("map", "hello,Map");
        return "success";
    }
   

利用ModelMap

    @RequestMapping("/testModelMap")
    public String testModelMap(ModelMap modelMap){
        modelMap.addAttribute("testScope", "hello,ModelMap");
        return "success";
    }

分别对应的前端读取方法

ServletAPIRequest共享数据:<p th:text="${test}"></p>
ModelAndView共享数据:
<p th:text="${test}"></p>
<p th:text="${map}"></p>
Model共享数据:
<p th:text="${test}"></p>
Map共享数据:
<p th:text="${map}"></p>
ModelMap共享数据:
<p th:text="${testScope}"></p>

分析:
分别对上面四种 ModelView,Model,Map,ModelMap 的实现类进行分析
依次将代码放入显示

System.out.println(mv.getClass().getName());
System.out.println(model.getClass().getName());
System.out.println(map.getClass().getName());
System.out.println(modelMap.getClass().getName());
org.springframework.web.servlet.ModelAndView
org.springframework.validation.support.BindingAwareModelMap 		
org.springframework.validation.support.BindingAwareModelMap
org.springframework.validation.support.BindingAwareModelMapp)

发现 Model,Map,ModelMap 是一个实现类,他们本质上使用时一回事
需要注意,Model 与 Map 是一个接口,ModelMap 继承了 LinkedHashMap;ExtendedModelMap 继承了 ModelMap ,同时实现了Model,最终 BindingAwareModelMap 实现了 ExtendedModelMap ,因此可知他们本质上是一个东西,能够互相影响。

public interface Model{} 
public class ModelMap extends LinkedHashMap<String, Object> {} 
public class ExtendedModelMap extends ModelMap implements Model {}
 public class BindingAwareModelMap extends ExtendedModelMap {}

更有趣的时 ModelView,ModelView 是 SpringMVC 前后端能够共享数据的的核心,上面的几种方式实际上都会通过返回 ModelView 的方式来返回到前端数据,因此他们的数据实际上是共享的。
作为 request,最终实现本质上是 request.setAttribute(“test”,“value”); 这种方式的不同表现,内部数据在一次请求是共享的。

Session 域对象

Session 对象一次会话有效

    @RequestMapping("/testSession")
    public String testSession(HttpSession session){
        session.setAttribute("test","hello,session");
        return "success";
    }

前端:

session共享数据
<p th:text="${session.test}"></p>

Application 域对象

整个项目有效

    @RequestMapping("/testApplication")
    public String testApplication(HttpSession session){
        ServletContext context = session.getServletContext();
        context.setAttribute("test","hello,Context");
        return "success";
    }

前端:

application共享数据
<p th:text="${application.test}"></p>

还有一个域对象仅在page页面有效,是一个作用范围最小的域对象,因为在前端页面中共享数据应用较多,本篇不再赘述。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值