Spring MVC数据绑定和响应学习笔记

news2024/11/15 8:17:42

学习视频:12001 数据绑定_哔哩哔哩_bilibili

目录

1.数据绑定

简单数据绑定

默认类型数据绑定

简单数据类型绑定的概念

参数别名的设置

  @PathVariable注解的两个常用属性

POJO绑定

自定义类型转换器

xml方式 

注解方式

数组绑定

集合绑定

复杂POJO绑定

属性为对象类型的数据绑定

属性为List类型的数据绑定

属性为Map类型的数据绑定

消息转换器—HttpMessageConverter接口

JSON转换器配置和静态资源访问配置

2.页面跳转

返回值为void类型的页面跳转到默认页面

返回值为String类型的页面跳转(不携带数据)

返回值为String类型的页面跳转(携带数据)

返回值为ModelAndView类型的页面跳转

3.数据回写

普通字符串的回写 

JSON数据的回写

@ResponseBody注解


1.数据绑定

        数据绑定的概念

          在程序运行时,Spring MVC接收到客户端的请求后,会根据客户端请求的参数和请求头等数据信息,将参数以特定的方式转换并绑定到处理器的形参中。Spring MVC中将请求消息数据与处理器的形参建立连接的过程就是Spring MVC的数据绑定。

Spring MVC数据绑定的过程图


Spring MVC数据绑定中的信息处理过程

  Spring MVC数据绑定中的信息处理过程的步骤描述如下。

(1)Spring MVC将ServletRequest对象传递给DataBinder。

(2)将处理方法的入参对象传递给DataBinder。

(3)DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中。

(4)调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验。

(5)校验完成后会生成数据绑定结果BindingResult对象,Spring MVC会将BindingResult对象中的内容赋给处理方法的相应参数。


简单数据绑定

默认类型数据绑定

当使用Spring MVC默认支持的数据类型作为处理器的形参类型时,Spring MVC的参数处理适配器会默认识别这些类型并进行赋值。Spring MVC常见的默认类型如下所示。     HttpServletRequest:获取请求信息。

HttpServletResponse:处理响应信息。    

HttpSession:获取session中存放的对象。    

Model/ModelMap:Model是一个接口,ModelMap是一个类,Model的实现类对象和ModelMap对象都可以设置model数据,model数据会填充到request域。

@Controller
public class UserController {
    /**
     *  默认参数类型:
     *          HttpServletRequest:请求
     *          HttpServletResponse:响应
     *          HttpSession:session对象
     *          Model:模型,用于存放页面需要的数据的
     * @return
     */

    @RequestMapping("/findById")
        public String findById(HttpServletRequest request,
                            HttpServletResponse response,
                               HttpSession session,
                               Model model
    )
        {
            System.out.println(response);
            System.out.println(session);

            //向模型中存放数据
            model.addAttribute("msg","你好");

            //获取请求中参数
          String userid=request.getParameter("userid");

            System.out.println("根据id查询用户信息:"+userid);
            return "success";
        }




}
<body>
        <h1>hello springMVC!!!</h1>
        ${msg}
</body>


简单数据类型绑定的概念

        简单数据类型的绑定,就是指Java中基本类型(如int、double、String等)的数据绑定。在Spring MVC中进行简单类型的数据绑定,只需客户端请求参数的名称和处理器的形参名称一致即可,请求参数会自动映射并匹配到处理器的形参完成数据绑定。

@RequestMapping("/getUsername")
        public String getUsername(String username)
        {
            System.out.println("用户名:"+username);
            return "success";
        }

这时候没有接收到 

参数别名的设置

         需要注意的是,有时候客户端请求中参数名称和处理器的形参名称不一致,这就会导致处理器无法正确绑定并接收到客户端请求中的参数。为此,Spring MVC提供了@RequestParam注解来定义参数的别名,完成请求参数名称和处理器的形参名称不一致时的数据绑定。

@RequestParam注解的属性

@RequestMapping("/getUsername")
        public String getUsername(@RequestParam(value = "name",defaultValue = "it")String username)
        {
            System.out.println("用户名:"+username);
            return "success";
        }

去掉s的时候用户名为默认值 it


  @PathVariable注解的两个常用属性

        当请求的映射方式是REST风格时,上述对简单类型数据绑定的方式就不适用了。为此,Spring MVC提供了@PathVariable注解,通过 @PathVariable注解可以将URL中占位符参数绑定到处理器的形参中。@PathVariable注解有以下两个常用属性。    

        value:用于指定URL中占位符名称。    

        required:是否必须提供占位符,默认值为true。

@PathVariable注解的使用


        @RequestMapping("/user/{name}")
        public String getpPathVariable(@PathVariable("name") String username)
        {
            System.out.println("路径中的参数:"+username);
            return "success";

        }


POJO绑定

POJO数据绑定的概念 

POJO类型的数据绑定就是将所有关联的请求参数封装在一个POJO中,然后在方法中直接使用该POJO作为形参来完成数据绑定。

POJO数据绑定的使用场景

         在使用简单数据类型绑定时,可以很容易的根据具体需求来定义方法中的形参类型和个数,然而在实际应用中,客户端请求可能会传递多个不同类型的参数数据,如果还使用简单数据类型进行绑定,那么就需要手动编写多个不同类型的参数,这种操作显然比较繁琐。为解决这个问题,可以使用POJO类型进行数据绑定。

public class User {

    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

<%@ page contentType="text/html;charset=gb2312"%>
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"
            method="post">
    用户名:<input type="text" name="username" /><br />
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password" /><br />
    <input type="submit" value="注册"/>
</form></body>
</html>
      @RequestMapping("/registerUser")
        public String registerUser(User user)
        {
            System.out.println("user信息:"+user);


            return "success";

        }

这里的参数name的名字和实体类User的属性名一样。可以直接映射


自定义类型转换器

自定义类型转换器使用场景

        Spring MVC默认提供了一些常用的类型转换器,这些类型转换器,可以将客户端提交的参数自动转换为处理器形参类型的数据。然而默认类型转换器并不能将提交的参数转换为所有的类型。此时,就需要开发者自定义类型转换器,来将参数转换为程序所需要的类型。

   @RequestMapping("/getBirthday")
        public String getBirthday(Date birthday)
        {
            System.out.println("出生日期:"+birthday);
            return "success";
        }

 

类型转换失败,这时候就需要类型转换器 


xml方式 

Converter接口的使用

public class DateConverter implements Converter<String, Date> {


    @Override
    public Date convert(String s) {
            String dateFormatPattern = "yyyy-MM-dd";
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormatPattern);
            Date date = null;
        try {
            date = sdf.parse(s);
        } catch (ParseException e) {
           e.printStackTrace();
            System.out.println("请采用正确的格式:"+dateFormatPattern);
        }


        return date;
    }


}
 @RequestMapping("/getBirthday")
        public String getBirthday(Date birthday)
        {
            System.out.println("出生日期:"+birthday);
            return "success";
        }
    <!--配置格式转换器的工厂-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <array>
                <bean class="com.it.convert.DateConverter"></bean>
            </array>
        </property>

    </bean>
    <!--注解驱动-->
    <mvc:annotation-driven conversion-service="conversionService"/>

注意:“yyyy-MM-dd”这里的dd后面不要有空格,不然写2021-01-01会得不到正确结果

         在上述案例中,日期类型的格式转换是基于XML配置自定义转换器实现的。除了XML方式之外,还可以通过@DateTimeFormat注解来简化日期类型的格式转换。使用@DateTimeFormat注解完成日期类型的格式转换无需自定义转换器,也无需在配置文件中定义转换器工厂或格式化工厂,只需将@DateTimeFormat定义在方法的形参前面或成员变量上方,就可以为当前参数或变量指定类型转换规则。

注解方式

    @RequestMapping("/getBirthday")
        public String getBirthday(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday)
        {
            System.out.println("出生日期:"+birthday);
            return "success";
        }
 <mvc:annotation-driven></mvc:annotation-driven>

数组绑定

数组绑定的使用场景

          在实际开发中,可能会遇到客户端请求需要传递多个同名参数到服务器端的情况,这种情况采用前面的简单数据绑定的方式显然是不合适的。此时,可以使用数组来接收客户端的请求参数,完成数据绑定。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<html><head><title>提交商品</title></head><body>
<form action="${pageContext.request.contextPath }/getProducts"method="post">
    <table width="220px" border="1">
        <tr><td>选择</td><td>商品名称</td></tr>
        <tr>
            <td>
                <input name="proIds" value="1" type="checkbox">
            </td>
                <td>SSM框架实战</td>
        </tr>
        <tr>
            <td>
                <input name="proIds" value="2" type="checkbox">
            </td>
            <td>JavaWeb案例</td>
        </tr>
    </table>
    <input type="submit" value="提交商品"/>
</form></body></html>
public class Product {
    private String proId;
    private String proName;

    @Override
    public String toString() {
        return "Product{" +
                "proId='" + proId + '\'' +
                ", proName='" + proName + '\'' +
                '}';
    }

    public String getProId() {
        return proId;
    }

    public void setProId(String proId) {
        this.proId = proId;
    }

    public String getProName() {
        return proName;
    }

    public void setProName(String proName) {
        this.proName = proName;
    }
}
@Controller
public class ProductController {

    @RequestMapping("/getProducts")
    public String getProducts(String[] proIds)
    {
        for (String proId : proIds)
        {
            System.out.println("商品的id为"+proId);
        }
            return "success";
    }
}

注意:String[] 后面的proIds要和input里面的name的值一样 


集合绑定

        集合中存储简单类型数据时,数据的绑定规则和数组的绑定规则相似,需要请求参数名称与处理器的形参名称保持一致。不同的是,使用集合绑定时,处理器的形参名称需要使用@RequestParam注解标注。

   如果getProducts( )方法中不使用@RequestParam注解,Spring MVC默认将List作为对象处理,赋值前先创建List对象,然后将proIds作为List对象的属性进行处理。由于List是接口,无法创建对象,所以会出现无法找到构造方法异常。如果将类型更改为可创建对象的类型,如ArrayList,可以创建ArrayList对象,但ArrayList对象依旧没有proIds属性,因此无法正常绑定,数据为空。此时需要告知Spring MVC的处理器proIds是一组数据, 而不是一个单一数据。通过@RequestParam注解,将参数打包成参数数组或集合后,Spring MVC才能识别该数据格式,并判定形参类型是否为数组或集合,并按数组或集合对象的形式操作数据。   

    @RequestMapping("/getProducts")
    public String getProducts(@RequestParam("proIds") List<String> proIds)
    {
        for (String proId : proIds)
        {
            System.out.println("商品的id为"+proId);
        }
        return "success";
    }


复杂POJO绑定

属性为对象类型的数据绑定

public class Order {
    private String orderId;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}
public class User {

    private String username;
    private String password;
    private Order order;

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }
    @RequestMapping("/findOrderWithUser")
        public String findUserWithOrder(User user)
        {
            System.out.println("用户名:"+user.getUsername());
            System.out.println("订单号:"+user.getOrder().getOrderId());
            return "success";
        }

<%@ page language="java" contentType="text/html;
	charset=UTF-8" pageEncoding="UTF-8"%>
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>订单信息</title></head><body><form
        action="${pageContext.request.contextPath }/findOrderWithUser"method="post">
    所属用户:<input type="text" name="username" /><br />
    订单编号:<input type="text" name="order.orderId" /><br />
    <input type="submit" value="查询" />
</form>	</body></html>


属性为List类型的数据绑定

public class User {

    private String username;
    private String password;
    private List<Order> orders;
    private List<String> address;

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public List<String> getAddress() {
        return address;
    }

    public void setAddress(List<String> address) {
        this.address = address;
    }
public class Order {
    private String orderId;
    private String orderName;


    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}
    @Controller("/showOrders")
    public class OrderController{


        @RequestMapping("/showOrders")
        public String showOrders(User user){
            List<Order> orders = user.getOrders();
            List<String> address=user.getAddress();

            for (int i=0;i<orders.size();i++){
                Order order = orders.get(i);
                address.get(i);
                System.out.println("订单编号:"+order.getOrderId()+" 地址是:"+address);

            }
            return "success";
        }

    }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html><head><title>订单信息</title></head><body>
<form action="${pageContext.request.contextPath }/showOrders"method="post">
    <table width="220px" border="1">
        <tr><td>订单号</td><td>订单名称</td><td>配送地址</td></tr>
        <tr><td><input name="orders[0].orderId" value="1" type="text"></td>
               <td><input name="orders[0].orderName" value="Java基础教程"type="text"></td>
               <td><input name="address" value="北京海淀" type="text"></td></tr></table>
    <input type="submit" value="订单信息"/>
</form> </body></html>


属性为Map类型的数据绑定

public class Order {
    private String orderId;
    private HashMap<String,Product>productInfo;

    public HashMap<String, Product> getProductInfo() {
        return productInfo;
    }

    public void setProductInfo(HashMap<String, Product> productInfo) {
        this.productInfo = productInfo;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}
public class Product {
    private String proId;
    private String proName;

    @Override
    public String toString() {
        return "Product{" +
                "proId='" + proId + '\'' +
                ", proName='" + proName + '\'' +
                '}';
    }

    public String getProId() {
        return proId;
    }

    public void setProId(String proId) {
        this.proId = proId;
    }

    public String getProName() {
        return proName;
    }

    public void setProName(String proName) {
        this.proName = proName;
    }
}
 @RequestMapping("/orderInfo")
        public String getOrderinfo(Order order)
        {
            //遍历订单中的商品信息
            System.out.println("订单的编号:"+order.getOrderId());

            HashMap<String, Product> productInfo=order.getProductInfo();
            Set<String> keys=productInfo.keySet();
            for (String key:keys)
            {
              Product product=productInfo.get(key);
                System.out.println("类型:"+key+"商品名称:"+product.getProName());
            }

            return "success";
        }
    }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<form action="${pageContext.request.contextPath}/orderInfo"method="post">
    <table border="1"><tr><td colspan="2" >
订单id:<input type="text" name="orderId" value="1"></td></tr>
<tr><td>商品Id</td><td>商品名称</td></tr>
<tr>
    <td><input name="productInfo['生鲜'].proId" value="1"type="text"></td>
    <td><input name="productInfo['生鲜'].proName" value="三文鱼" type="text"></td>
</tr>
        <tr>
            <td><input name="productInfo['酒水'].proId" value="2"type="text"></td>
            <td><input name="productInfo['酒水'].proName" value="红牛" type="text"></td>
        </tr></table>
<input type="submit" value="提交"/>
</form>


消息转换器—HttpMessageConverter接口

         客户端不同的请求,HttpServletRequest中数据的MediaType可能会不同,如果想将HttpServletRequest中的数据转换成指定对象,或者将对象转换成指定格式的数据,就需要使用对应的消息转换器来实现。Spring中提供了一个HttpMessageConverter接口作为消息转换器。因为数据的类型有多种,所以Spring中提供了多个HttpMessageConverter接口的实现类,其中MappingJackson2HttpMessageConverter是HttpMessageConverter接口的实现类之一,在处理请求时,可以将请求的JSON报文绑定到处理器的形参对象,在响应请求时,将处理器的返回值转换成JSON报文。

HttpMessageConverter与Converter类型转换器的区别

         需要注意的是,HttpMessageConverter消息转换器和之前所学习的Converter类型转换器是有区别的。HttpMessageConverter消息转换器用于将请求消息中的报文数据转换成指定对象,或者将对象转换成指定格式的报文进行响应;Converter类型转换器用于对象之间的类型转换。

   由于本次演示的是异步数据提交,需要使用jQuery,所以需要将jQuery文件导入到项目中,以便发送ajax请求。在项目的/webapp文件夹下创建名称为js的文件夹,在js文件夹中导入jQuery文件。  

public class Product {
    private String proId;
    private String proName;

    @Override
    public String toString() {
        return "Product{" +
                "proId='" + proId + '\'' +
                ", proName='" + proName + '\'' +
                '}';
    }

    public String getProId() {
        return proId;
    }

    public void setProId(String proId) {
        this.proId = proId;
    }

    public String getProName() {
        return proName;
    }

    public void setProName(String proName) {
        this.proName = proName;
    }
}
public class Order {
    private String orderId;
    private HashMap<String,Product>productInfo;

    public HashMap<String, Product> getProductInfo() {
        return productInfo;
    }

    public void setProductInfo(HashMap<String, Product> productInfo) {
        this.productInfo = productInfo;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
    <head>
        <title>
        异步提交商品
        </title>
        <script type="text/javascript"
            src="${pageContext.request.contextPath}/js/jquery-3.4.1.min.js"
        ></script>
    </head>
</html>
<form id="products">
    <table border="1">
        <tr>
            <th>商品id</th>
            <th>商品名称</th>
            <th>提交</th>
        </tr>
        <tr>
            <td>
                <input name="proId" value="1" id="proId" type="text">
            </td>
            <td>
                <input name="proName" value="三文鱼" id="proName" type="text">
            </td>
            <td>
                <input type="button" value="提交单个商品"
                    onclick="sumbmitProduct()">
            </td>
        </tr>
        <tr>
            <td>
                <input name="proId" value="2" id="proId2" type="text">
            </td>
            <td>
                <input name="proName" value="红牛" id="proName2" type="text">
            </td>
            <td>
                <input type="button" value="提交多个商品"
                       onclick="sumbmitProducts()">
            </td>
        </tr>


    </table>


</form>
<script type="text/javascript">
    function sumbmitProduct() {
        var proId = $("#proId").val();
        var proName = $("#proName").val();
        $.ajax({ url: "${pageContext.request.contextPath }/getProduct",
            type: "post",
            data: JSON.stringify({proId: proId, proName: proName}),
            contentType: "application/json;charset=UTF-8",
            dataType: "json",
            success: function (response) {alert(response);}  });		}
    function sumbmitProducts() {
        var pro1={proId:$("#proId").val(),proName:$("#proName").val()}
        var pro2={proId:$("#proId2").val(),proName:$("#proName2").val()}
        $.ajax({ url: "${pageContext.request.contextPath }/getProductList",
            type: "post",
            data: JSON.stringify([pro1,pro2]),
            contentType: "application/json;charset=UTF-8",
            dataType: "json",
            success: function (response) {alert(response);}  });		}
</script>
</script>
    <mvc:annotation-driven></mvc:annotation-driven>
   <!-- 配置静态资源的访问-->
    <mvc:resources mapping="/js/**" location="/js/" />
    @RequestMapping("/getProduct")
    public String getProduct(@RequestBody Product product)
    {
        System.out.println("单个商品:"+product);
        return "success";
    }

    @RequestMapping("/getProductList")
    public String getProductList(@RequestBody List<Product> productList)
    {
        System.out.println("多个商品:");
        productList.forEach(product -> {
            System.out.println(product);
        });

        return "success";
    }


JSON转换器配置和静态资源访问配置

        JSON转换器配置和静态资源访问配置,除了之前讲解的配置方案之外,还可以通过其他方式完成,下面讲解两种配置方式,使用<bean>元素配置JSON转换器和静态资源访问的配置方式。

使用<bean>元素配置JSON转换器

<!-- 使用<bean>元素配置注解方式的处理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method
	.annotation.RequestMappingHandlerMapping" />
<!-- 使用<bean>元素配置注解方式的处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.method
	.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters"><list><!-- 配置JSON转换器 -->
            <bean  class="org.springframework.http.converter.json
	.MappingJackson2HttpMessageConverter"/></list></property>
</bean>

静态资源访问的配置方式

使用<mvc:default-servlet-handler>配置静态资源

<mvc:default-servlet-handler />

激活Tomcat默认的Servlet来处理静态资源访问

<servlet-mapping>
      <servlet-name>default</servlet-name><url-pattern>*.js</url-pattern>
</servlet-mapping><servlet-mapping>
	<servlet-name>default</servlet-name><url-pattern>*.css</url-pattern>
</servlet-mapping>

2.页面跳转

返回值为void类型的页面跳转到默认页面

        当Spring MVC方法的返回值为void类型,方法执行后会跳转到默认的页面。默认页面的路径由方法映射路径和视图解析器中的前缀、后缀拼接成,拼接格式为“前缀+方法映射路径+后缀”。如果Spring MVC的配置文件中没有配置视图解析器,则会报HTTP Status 500错误。

代码演示

 @RequestMapping("/register")
    public void showPageByVoid()
    {
        System.out.println("showPageByVoid running");

    }
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"
            method="post">
    用户名:<input type="text" name="username" /><br />
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password" /><br />
    <input type="submit" value="注册"/>
</form></body>
</html>


返回值为String类型的页面跳转(不携带数据)

  @RequestMapping("/showPageByString")
    public String showPageByString()
    {
        System.out.println("showPageByString running");
        return "register";
    }

注意:void类型默认映射路径名就是视图名称

        string返回值默认直接是视图名称


返回值为String类型的页面跳转的转发方式

          当方法的返回值为普通的字符串时,Spring MVC在方法执行后会默认以转发的方式响应给客户端。除了这种默认的转发方式,还可以返回指定前缀的字符串,来设定处理器执行后对请求进行转发还是重定向,设定转发和重定向的字符串格式如下所示。

  • forward:需要转发到的资源路径
  • redirect:需要重定向到的资源路径
   @RequestMapping("/showPageByForward")
    public String showPageByForward() {
        System.out.println("showPageByForward running");
        return "forward:order.jsp";	}
    @RequestMapping("/showPageByRedirect")
    public String showPageByRedirect() {
        System.out.println("showPageByRedirect running");
        return "redirect:http://www.itheima.com";	}

以及把showPageByRedirect复制过去也是可以访问到的 


返回值为String类型的页面跳转(携带数据)

  @RequestMapping("/showPageByRequest")
    public String showPageByRequest(HttpServletRequest request) {
        System.out.println("showPageByRequest running");
        request.setAttribute("username","request"); 
        return "register";

    }
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"
            method="post">
    用户名:<input type="text" name="username" value="${username}" /><br />
    密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password" /><br />
    <input type="submit" value="注册"/>
</form></body>
</html>


另一种

@RequestMapping("/showPageByModel")
    public String showPageByModel(Model model) {
        System.out.println("showPageByRequest running");
        //传递数据
       model.addAttribute("username","model");
        return "register";

    }


返回值为ModelAndView类型的页面跳转

ModelAndView对象组成部分

        使用方法的返回值可以设定跳转的逻辑视图名称,使用Model等对象实现页面跳转时传输数据。除此之外,Spring MVC还提供了兼顾视图和数据的对象ModelAndView,ModelAndView对象包含视图相关内容和模型数据两部分,其中视图相关的内容可以设置逻辑视图的名称,也可以设置具体的View实例;模型数据则会在视图渲染过程中被合并到最终的视图输出。

ModelAndView设置视图和数据模型的方法

ModelAndView方法说明

         setViewName()方法setView()方法都是为ModelAndView对象设置视图的方法,其中前者使用更方便,因此setViewName()方法比较常用。后3个方法都是向ModelAndView对象中添加模型数据的,其中addObject(Object attributeValue)方法添加的attributeValue,默认名称为attributeValue类型全限定名的最后一个单词且首字母小写;addObject(String attributeName, Object attributeValue)方法可以在页面上以${attributeName}方式取出attributeValue。

 @RequestMapping("/showModelAndView")
    public ModelAndView showModelAndView() {
        ModelAndView modelAndView = new ModelAndView();
        //数据设置
        modelAndView.addObject("username","santi");
        User user = new User();	user.setPassword("password");
        modelAndView.addObject("user",user);
        //视图设置
        modelAndView.setViewName("register");
        return modelAndView;
    }


3.数据回写

普通字符串的回写 

@Controller
public class DataController {

    @RequestMapping("/showDataByResponse")
    public void showDataByResponse(HttpServletResponse response)
    {
        try {
            response.getWriter().write("success");
        } catch (IOException e) {
           e.printStackTrace();
        }

    }

}


JSON数据的回写

 @RequestMapping("showDataByJSON")
    public void showDataByJSON(HttpServletResponse response)  {
        try {	ObjectMapper om = new ObjectMapper();
            //创建user对象
            User user = new User();user.setUsername("santi");	user.setPassword("666");
            //转换成json字符串
            String ujson = om.writeValueAsString(user);
            response.getWriter().print(ujson);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

        


@ResponseBody注解

        @ResponseBody注解可以标注在方法和类上,当标注在类上时,表示该类中的所有方法均应用@ResponseBody注解。如果需要当前类中的所有方法均应用@ResponseBody注解,也可以使用@RestController注解

@ResponseBody注解的2个使用要求

        使用@ResponseBody注解,项目至少需要符合2个要求,分别如下所示。    

                1.项目中有转换JSON相关的依赖。    

                2.可以配置转换JSON数据的消息类型转换器。      

  针对上述两个要求,chapter12项目都已经满足,项目的pom.xml文件中引入了Jackson相关的依赖,可以用于转换JSON;Spring MVC的配置文件中配置的<mvc:annotation-driven />元素默认注册了Java数据转JSON数据的消息转换器。

    @RequestMapping("/showDataByJSON")
    @ResponseBody
    public User showDataByJSON()  {

            //创建user对象
            User user = new User();user.setUsername("santi");	user.setPassword("666");
            //转换成json字符串
           return user;

    }


通过一个案例演示使用@ResponseBody注解回写JSON格式的对象数据和集合数据

 @RequestMapping("/getUser")
    @ResponseBody
    public User getUser()
    {
        User user = new User();
        user.setUsername("abc");
        user.setPassword("213");
        return user;
    }

    @RequestMapping("/addProducts")
    @ResponseBody
    public List<Product> addProducts()
    {
        List<Product> productList=new ArrayList<>();

        Product p1=new Product();
        p1.setProId("p01");
        p1.setProName("三文鱼");

        Product p2=new Product();
        p2.setProId("p02");
        p2.setProName("茅台");
        productList.add(p1);
        productList.add(p2);
        return productList;

    }


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2038778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣面试经典算法150题:最长公共前缀

最长公共前缀 今天的题目是力扣面试经典150题中的数组的简单题: 最长公共前缀 题目链接&#xff1a;https://leetcode.cn/problems/longest-common-prefix/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 编写一个函数来查找字符串数组中的最长公…

修改OpenSSH服务版本号

前言 这几年信息安全要求很高&#xff0c;奈何口号响亮掩盖不了我们技术基础依然很低的事实&#xff0c;加上风口烧钱和政绩工程等因素&#xff0c;于是就诞生了一些乱象&#xff0c;其中一个就是安全扫描胡乱标记&#xff0c;这里面的典型就是OpenSSH的漏洞扫描报告。 比如&…

人工智能小车——智能车臂控制平台

随着机器人技术的不断发展 &#xff0c;各行业对机器人应用人才的需求也随之增加&#xff0c;培养符合行业发展需求的机器人技术专业人才成为了高校的重要任务。 基本介绍 智能车臂控制平台&#xff08;ZI-AutoRB&#xff09;是一套用以机器人控制技术学习和研究的软硬件系统。…

米联客-FPGA程序设计Verilog语法入门篇连载-10 Verilog语法_一般设计规范

软件版本&#xff1a;无 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用所有系列FPGA 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑&#xff01; 1概述 本小节讲解Verilog语法的一般…

照片回收利器:最新数据恢复软件推荐

照片回收利器&#xff1a;最新数据恢复软件推荐 在今天的数字化时代&#xff0c;我们将大量珍贵的照片和个人数据存储在电脑、手机和其他设备中。然而&#xff0c;由于各种原因&#xff0c;这些数据可能会意外删除或丢失&#xff0c;这对我们来说是一个巨大的损失。因此&#…

【Redis】List类型

目录 List列表 命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP RPOP LINDEX LINSERT LLEN lrem ltrim lset 阻塞版本命令 BLPOP BRPOP 内部编码 使用场景 消息队列 分频道的消息队列 作为栈或者队列 List列表 列表类型是⽤来存储多个有序的字符串&…

5 大场景上手通义灵码企业知识库 RAG

大家好&#xff0c;我是通义灵码&#xff0c;你的智能编程助手&#xff01;最近我又升级啦&#xff0c;智能问答功能全面升级至 Qwen2&#xff0c;新版本在各个方面的性能和准确性都得到了显著提升。此外&#xff0c;行间代码补全效果也全面优化&#xff0c;多种编程语言生成性…

python-小理和他的猫(赛氪OJ)

[题目描述] 今天小理又要为他的猫小咪准备好吃的猫粮了&#xff0c;你愿意帮助一下他们么&#xff1f; 小理现在拥有的金钱数为 N &#xff0c;有 M 种小咪喜欢的猫粮从左到右排列&#xff0c;已知每种猫粮的价格 ai​ &#xff0c;他的购买规则如下&#xff1a; 1.必须按照从左…

数据结构与算法--图的存储与遍历

文章目录 回顾提要图的定义和表示图的表示完全图和子图顶点的度路径与回路连通图 邻接矩阵权和网 邻接表示例 深度优先遍历 (DFS)广度优先遍历 (BFS)广度优先遍历过程总结邻接矩阵存储结构邻接表存储结构 回顾 线索化二叉树&#xff1a;在某种次序遍历过程中创建线索&#xff…

简单数学运算(c语言)

1.描述 //牛牛最近学会了一些简单的数学运算&#xff0c;例如 //∑i1 ∑i 1 //请你帮他模拟一下这个运算。 &#xff08;即 1 2 3.... n - 1 n) //输入描述&#xff1a; //输入仅一个正整数 n //输出描述&#xff1a; //请你计算 //∑i1n 2.就是递归函数 方法一&#xf…

40.【C语言】指针(重难点)(E)

目录 13.指针的使用和传址调用 14.数组名的理解 *数组名就是数组首元素的地址 *两个例外 *使用指针访问数组 *一维数组的传参本质 往期推荐 承接上篇39.【C语言】指针&#xff08;重难点&#xff09;&#xff08;D&#xff09; 13. 指针的使用和传址调用 见29.【C语言】函数系…

Linux系统编程(9)

一、wait函数 1.wait函数 #include <sys/wait.h> pid_t wait(int *status);wait函数有两个作用&#xff1a; 1.获取子进程 的退出状态 当父进程要获取子进程的退出状态时&#xff0c;子进程里需要使用exit函数&#xff08;exit&#xff08;退出状态值&#xff09;退出…

10:【stm32】USART与串口通信一:USART(上)

USART&#xff08;上&#xff09; 1、串口通信1.1、简介1.2、数据帧1.2.1、简介1.2.2、校验规则1.2.3、停止位的长度 1.3、异步通信的波特率1.3.1、同步通信1.3.2、异步通信1.3.3、硬件流控 2、USART2.1、简介2.2、工作的原理2.3、相关寄存器 3、标准库编程3.1、编程接口USART_…

day16-测试自动化之selenium的PO模式

一、PO模式介绍 PO&#xff08;Page Object&#xff09;模式是一种在自动化测试中常用的设计模式&#xff0c;将页面的每个元素封装成一个对象&#xff0c;通过操作对象来进行页面的交互。 一般分为六个版本&#xff0c;现在大部分企业都用的V4版本&#xff0c;三层结构…

redis面试(十六)公平锁释放和排队加锁

锁释放 RedissonFairLock.unlockInnerAsync()方法 这和加锁的逻辑没有太大区别 也就是说在客户端A他释放锁的时候&#xff0c;也会走while true的脚本逻辑&#xff0c;看一下有序集合中的元素的timeout时间如果小于了当前时间&#xff0c;就认为他的那个排队就过期了&#xf…

Spring自动注册-<bean>标签和属性解析

xml文件中最常见也最核心的就是<bean>,<Import>,<beans>,<alias>标签,关于它们的解析主要是BeanDefinitionParserDelegate类中.<bean>标签的解析最为复杂和重要. <bean>标签 processBeanDefinition(ele, delegate)方法中,主要是是对…

数据库管理-Redis

数据库管理-Redis 一、关系型数据库和非关系型数据库1、关系型数据库&#xff08;Relational Database Management System, RDBMS&#xff09;&#xff1a;2、非关系型数据库&#xff08;NoSQL Database Management System&#xff09;&#xff1a; 二、redis简述 redis是把数据…

苦WPS云盘已久矣

主要因为软件更新后&#xff0c;设置位置都会跑到其他地方 打开wps客户端后&#xff0c;点击电脑底部任务栏的云朵图标。 2. 找到存储位置后&#xff0c;点击“更换位置”。 来自https://www.wps.cn/mlearning/question/detail/id/333165.html

Java | Leetcode Java题解之第328题奇偶链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode oddEvenList(ListNode head) {if (head null) {return head;}ListNode evenHead head.next;ListNode odd head, even evenHead;while (even ! null && even.next ! null) {odd.next even.nex…

编程学习笔记秘籍:开启高效学习之旅

引言&#xff1a; “计算机科学教育不能使人成为程序员&#xff0c;就像学画笔和颜料不能使人成为画家一样。”——埃里克雷蒙德。在当今数字化的时代&#xff0c;编程如同一把神奇的钥匙&#xff0c;能够打开无数机遇的大门。然而&#xff0c;编程知识的海洋广阔无垠&#xff…