SpringMVC学习笔记(2)

SpringMVC学习笔记(2)

一、请求参数绑定

处理提交数据

提交数据:http://localhost:8080/index.jsp?username=zhangsan&password=123

处理方法

//使用Servlet原生API实现
@RequestMapping("/g1")
public String getParam1(HttpServletRequest request, Model model) {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String msg = username + ":" + password;
    model.addAttribute("msg", msg);
    return "hello";
}

//使用同名匹配规则
@RequestMapping("g2")
public String getParam2(String username, String password, Model model) {
    String msg = username + ":" + password;
    model.addAttribute("msg", msg);
    return "hello";
}

//提交的参数名称和处理方法的参数名不一样
@RequestMapping("g3")
public String getParam3(@RequestParam("username") String name, @RequestParam("password") String password, Model model) {
    String msg = name + ":" + password;
    model.addAttribute("msg", msg);
    return "hello";
}

//提交的是一个对象
//前端传递的参数名必须和对象名一致,否则为null
@RequestMapping("g4")
public String getParam4(User user) {
    System.out.println(user);
    return "hello";
}

//实体类
public class User {
    private String username;
    private String password;
    /*getter and setter*/
}

请求参数绑定集合类型

List:表单里的name写 list[i].属性

Map:name写 map['key'].属性

自定义类型转换器

​ 如果字符串是2021-4-14这样的类型。SpringMVC不能自动进行类型转换,需要自定义类型转换器。

​ 写一个类实现 org.springframework.core.convert.converter.Converter 接口,并且实现 convert 方法

public class StringToDateConverter implements Converter<String, Date> {
    /**
     * 字符串转成日期
     * @param source 传进来的字符串
     * @return date日期对象
     */
    @Override
    public Date convert(String source) {
        if (source.isEmpty()) {
            return null;
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //把字符串转成日期
            return df.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

​ 在springmvc.xml注册自定义类型转换器

<!--配置自定义类型转换器-->
<bean class="org.springframework.context.support.ConversionServiceFactoryBean"
      id="conversionService">
    <property name="converters">
        <set>
            <bean class="com.hzj.utils.StringToDateConverter"/>
        </set>
    </property>
</bean>

二、响应数据和结果类型

转发和重定向

@RequestMapping("/f1/t2")
public String test2() {
    //转发 路径必须写成实际视图 url,不能写逻辑视图。
    return "forward:/WEB-INF/jsp/test.jsp";
}

@RequestMapping("/f1/t3")
public String test3() {
    //重定向 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。
    return "redirect:/index.jsp";//不用加项目名
}

数据显示到前端

第一种:通过ModelAndView

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response){
    //返回一个模型视图对象
    return new ModelAndView("test");
}

第二种:通过ModelMap

@RequestMapping("/hello")
public ModelAndView handleRequest(ModelMap modelMap){
    //封装要显示到视图中的数据
    //相当于request.addAttribute
    modelMap.addAttribute("attributeName","attributeValue");
    //返回一个模型视图对象
    return new ModelAndView("test");
}

第三种:通过Model

@RequestMapping("/hello")
public ModelAndView handleRequest(Model model){
    //封装要显示到视图中的数据
    //相当于request.addAttribute
    model.addAttribute("attributeName","attributeValue");
    //返回一个模型视图对象
    return new ModelAndView("test");
}

对比

  • Model 只有几个方法只适合于储存数据,简化了对Model对象的操作
  • ModelMap 继承了LinkedMap,除了自身实现了的一些方法,同样的继承LinkedMap的方法和特性
  • ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转

返回值分类

字符串

controller 方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

指定逻辑视图名,经过视图解析器解析为 jsp 物理路径:/WEB-INF/pages/success.jsp

void

@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("testVoid执行了");
    //请求转发
    request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request, response);
    //重定向
    response.sendRedirect(request.getContextPath() + "/a.jsp");
}

ModelAndView

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    //创建ModelAndView对象
    ModelAndView mv = new ModelAndView();
    User user = new User("张三","123",12);
    mv.addObject("user",user);
    //要跳转的页面名字 会经过视图解析器
    mv.setViewName("test");
    return mv;
}

JSON

  • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。

要求和语法格式:

  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组
let user = {
        name: "张三",
        age: 3,
        sex: "男"
    }

    //将JavaScript对象转换为JSON对象
    let json = JSON.stringify(user);
    console.log(json);
	//控制台输出
	//{"name":"张三","age":3,"sex":"男"}

    //将JSON对象转换为JavaScript对象
    let obj = JSON.parse(json);
    console.log(obj);
	//控制台输出
	/*{name: "张三", age: 3, sex: "男"}
        age: 3
        name: "张三"
        sex: "男"
        __proto__: Object*/

ResponseBody响应json数据

  • 导入Jackson依赖
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.2</version>
</dependency>
  • 前端页面脚本
$(function () {
    $("#btn").click(function () {
        // 发送ajax请求
        $.ajax({
            url: "testAjax",//请求路径
            method: "POST",//请求方式
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({username: "jack", password: "123", age: 23}),
            success: function (data) {//响应成功后的回调函数
                $("#msg").html(data.username + "," + data.password + "," + data.age);
            },
            dataType: "json"//设置接收到的响应数据的格式
        });
    });
});
  • 对应的Controller
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
    System.out.println("testAjax方法执行了...");
    System.out.println(user);
    user.setUsername("张三");
    user.setAge(3);
    return user;
}

@RestController 注解的类,该类下所有方法都不会走视图解析器。

@ResponseBody 注解的方法,该方法不会走视图解析器,会直接返回一个字符串。

乱码优化

  • 解决中文乱码: @RequestMapping 注解改为
@RequestMapping(value = "/testAjax",produces = "application/json;charset=UTF-8")

乱码统一解决

  • 在springmvc.xml中配置
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

FastJSON

  • 导入fastjson依赖
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

fastjson三个主要的类

  • [JSONObject代表json对象]

    • JSONObject实现了Map接口,猜想JSONObject底层操作是由Map实现的。
    • JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利
      用诸如size(),isEmpty()等方 法获取"键:值" 对的个数和判断是否为空。其本质是通过实现
      Map接口并调用接口中的方法完成的。
  • [JSONArray代表json对象数组]

    • 内部是有List接口中的方法来完成操作的。
  • [JSON代表JSONObject和JSONArray的转化]

    • JSON类源码分析与使用
    • 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象, json字符串之间
      的相互转化。
posted @ 2021-03-02 15:39  夕子学姐  阅读(54)  评论(0)    收藏  举报