SpringMVC — 控制器

SpringMVC — 控制器

  • 创建一个 Controller 控制器:使用 @Controller 对类进行注解,将被标注的类设置为一个控制器
  • 使用 @RequestMapping 对类或方法进行注解,用来映射一个请求和请求的方法。
    • 属性 value 指请求的 url
    • method 可指明 RequestMethod.POST 即表单必须要是 method=”post” 请求方法
    • params 属性指明表单内容限制 {“name”=zyz, “pwd”} — 即表单 name 处值必须要是 zyz,pwd 随意不加以要求
  • 返回值类型:void、String、ModelAndView
  • 参数列表:
    • 简单数据绑定:
      • 绑定默认数据类型:HttpServletRequest、HttpServletResponse、HttpSession、Model
      • 绑定简单数据类型:除了上述四种默认,再添加新的参数就需要保证传递一个名字相同的形参
    • 复杂数据绑定:
      • 绑定POJO类型:可嵌套
      • 绑定数组
      • 绑定集合

常用返回值

  • 返回值为 String —— 直接字符串路径

    • 方法里单纯返回一串页面路径的字符串 ”/.....”
    • 也可以将一串路径字符串改为单 jsp 名,前提是 xml 中加视图解析器添前后缀拼接
    • 参数为 Model m:m.addAttribute (“xx”, “yy”) 方式存储 ( 内部方式似请求式 ) —— 前端代码 ${xx} 方式,显示得 yy。返回值为页面路径字符串
    • 在一个方法里进行存储数据后,再 return 一个指向其他方法的字符串
      • 转发到为 f1 的方法:“forward: /f1”,可再对值进行存储
      • 重定向到 f1 方法:”redirect: /f1”,无法 req 携参,Model 也不行
  • 返回值为 void —— 写到前端用 res.getWriter().write()

    • HttpServletReuqest、HttpServletResponse 与 HttpSession 参数

      • req.getParameter (“表单name”) 获取前端值

      • res.getWriter().write (“完成操作后直接显示在空白页面的字符串”)

      • req.setAttribute (“一次请求方式获取名”, “存放内容”)

      • req.getSession ()

      • s.setAttribute (“session方式获取名”, “存放内容”)

      • 存到请求中后可以 req.getRequestDispatcher ("/WEB-INF/jsp/3.jsp").forward(req, res); 携参转发

      • 存到 session 中 res.sendRedirect("/WEB-INF/jsp/3.jsp"); 重定向方式携参,WEB-INF 里面的 jsp 不能访问

  • 返回值为 ModelAndView —— mv.setViewName 跳转

    // 例:
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg","lalala"); // 请求域中存值
    mv.setViewName("/WEB-INF/jsp/x.jsp");
    return mv;
    

对返回值无要求

  • 参数列表:(@RequestBody String v) 的话,控制台直接输出 v 就是 ( 例 ):name=zyz&pwd=123456

  • 参数列表:用于表单 name 属性对应的值来接收,即为 springmvc 的方法绑定

    • 如:(int a, int b, HttpServletResponse res)

      通过 url 传递参数,前端:< a href="f8?a=1&b=2" > 用 ?开头 & 拼接 —— 注意,这样的话,a 与 b 就需要准确获取,不能空

    • 如:(@RequestParam(value=”name”) int a) —— 将前端的 name 传来,于方法中用 a 来获取并操作

  • 参数列表随意,存储到 session 中

    • 存到 session 的方式一:s.setAttribute
    • 请求转 session 的方式二:例如 ModelAndView 存储到请求域中 (“msg”, “xxxxx”),然后在类前加注解 @SessionAttributes(“msg”) —— 把请求域中的 msg 存到 session 中
  • 参数列表用POJO 方式,get 方式获取同属性名的值:(String name, String email)——> (User u)

    • 其中有一属性为另一类对象的话 ( 嵌套情况 —— 如:HomeTown ht ),前端 input 的 name = ”ht.privance”
  • 参数列表随意,可获取内容但拿不到 id:@ModelAttribute 注解处理 ( id 非自动递增时 ) —— 注解作用:将请求参数绑定到 Model 对象

    // 如果@ModelAttribute注解到了方法前就是,此方法先执行
    @ModelAttribute
    public User2 fxy(){
    User2 u = new User2();
    u.setId(10000); // 给f23的对象里给id赋了值
    //    ......
    //    此时fxx再用User2在前端接收信息时,User2 u就是已经包含了id和name两个值的对象了
    //    重复的属性部分就被f23传来的值给覆盖了
    return u;
    }
    // fxy 也可以把开头注解放进方法定义里:
    // 即:public @ModelAttribute User2 fxy() { }
    
    // 然后再执行前端指定url的类:
    public String fxx(User2 u){
    // 内含的User2 是已经在fxy执行过的,有了id属性的 —— 若是有属性重复的就直接用fxx里新的替换旧的 
    }
    
  • 参数列表为数组

    public String fxxy(String[] hobby){
    	System.out.println(Arrays.toString(hobby)); // 注意获取的写法
    	m.addAttribute("msg", Arrays.toString(hobby));
    // ...
    }
    
    // 前端
    <a href="fxxy?hobby=sing&hobby=dance&hobby=rap">数组_多数据</a>
    // 单数据的话同上,只写一个就可
    
  • 参数列表为 pojo —— 其中绑定有数组

    String id1 = "id1:" + Arrays.toString(u.getId1());
    
  • 参数列表为集合,就必须加注解

    • List,如:(@RequestParam List< String > id1 ... )
    • Map,如:(@RequestParam Map<String, String> map ... )
      • 前端表单:input 内有 name 与 value,后端直接 map 获取,前端超链接:< a href="f30?k1=20&k2=21&k3=22" >

参数列表含 Date

创建新类在 xml 里形成 bean ( 新建手写 )

  • 新类:

    public class MyDateConverter implements Converter<String, Date> { // 传进String,传出Date
    
        public Date convert(String str) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  // String接收后,由SimpleDateFormat来进行解析
                return sdf.parse(str);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    
  • xml:

    <!--  方案一:自定义日期类型转换器,并在 SpringMvc的配置文件中注册bean  -->
    <!--  属性conversion-service:转换服务  -->
        <bean id="myConverterService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
    <!--        把自定义的转换器加进来,只改变类所在        -->
                    <bean class="com.qut._20.convert.MyDateConverter"></bean>
                </list>
            </property>
        </bean>
                        
        <mvc:annotation-driven conversion-service="myConverterService"></mvc:annotation-driven>
    

新建无需自己手写类

  • xml:

    <!--  方案二:使用Spring的日期格式化器,并在SpringMVC的配置文件中注册bean  -->
        <mvc:annotation-driven conversion-service="myConverterService"></mvc:annotation-driven>
        <bean id="myConverterService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="formatters">
                <list>
                    <bean class="org.springframework.format.datetime.DateFormatter" p:pattern = "yyyy-MM-dd" />
                </list>
            </property>
    </bean>
    

使用注解的方式

  • xml:

    // @DateTimeFormat
    @RequestMapping(value = "/f33")
    public String f33(String name, String pwd, @DateTimeFormat(pattern = "yyyy-MM-dd")Date birthday, Model m) {}
    

JSON、JS、Java 字符串

  • JSON 与 String 字符串转换
// 规定的JSON字符串,此格式发到前台,JavaScript会将其解析成对象,并将其写到前台
   String str1 = "{\"name\":\"zyz\",\"email\":\"123@163.com\"}";  // 后台打入规定的JSON字符串
   res.getWriter().write(str1);  // 再写到前端,成:{"name":"zyz","email":"123@163.com"} —— ajax提交json方式。(表单方式是:name=zyz&pwd=123)
  • @RequestMapping (value="/f13_1",consumes="application/json")

    • consumes 属性表明只能用 json 来提交请求,即只能用 ajax 方式 ( 表单不可 )
  • 提交数据两种大的方式

    • HTML 方式:表单、超链接
    • JavaScript 方式:ajax
  • ajax 中 ( JS 转 JSON )

    // 此处是JavaScript(js)对象,不是json
    let x = {name:'admin_b2',pwd:"123"} // 从前端发送给后端的一种方式
    
    // $.ajax({  }) 里:
    type:"POST",
    // url后面的方法对应@的value值
    url:"http://localhost:8080/fxx", 
    // 设置发送类型(application/json就与RequestMapping的consumes属性匹配了)
    contentType:"application/json;charset=UTF-8",
    
    // 把js对象转成json,后台接收(JSON.stringify(x)得到json字符串) — 前端往后端发json
    data:JSON.stringify(x),
    
    // result(自定义) 收到后台 write 传来的数据信息(后台传来的字符串)
    // JSON.parse:将后台的json字符串解析为js对象(json格式得对)
    // .email信息弹窗:123@163.com
    success:function(result) {alert((JSON.parse(result)).email)}, // ajax回调函数—后端向前台传json(然后被解析指定输出)————注意不能直接alert了result,需要做解析
    error:function(e){alert(e.status + e.responseText)}
    
  • 后端 —— @RequestMapping + @RequestBody 放参数列表用来接收数据 ( ajax 的方式 ) + json 式字符串 String str1 = "{\"name\":\"zyz\",\"email\":\"123@163.com\"}";

    • 返回值 void:(@RequestBody String v, HttpServletResponse res)

      • 可用 res.getWriter().write(str1); 的传统方式写到前台 ( JSON.parse(result)).email ) 接收
    • 返回值 String:(@RequestBody String v),MVC方式,返回 json 字符串

      • 方法前用 @ResponseBody 注解 ( 表明不返回视图,而是向前台写,可写于 @RequestMapping 下)( JSON.parse(result)).email —— 直接 result 是 json 对象 )
    • 返回一个类对象 ( 如:user ):@ResponseBody 注解,set 存值后,返回一个对象,( 以 toString 的格式,无需 JSON.parse,可以直接 result.属性的前提 — 需要导入 jackson-databind 的 jar 包,前台 json 字符串 <——> java 对象 )

      • 前台发 json 可在后台 User 对象获取,然后 get 取出

补充注解

  • @PathVariable 注解,前端接口用 href=”fx/100”,后端映射时 ( value=”/fx/{id}” ),参数列表 ( @PathVariable String id ) 接收

  • @CookieValue 注解:参数列表 (@CookieValue("JSESSIONID") String str) 得自己的 cookie

  • JS 做到异步刷新 ( 页面部分刷新 —— 每次点击按钮都会新添 span )

    	<script>
    	<%-- 加载完成后ready --%>
            $(document).ready(function(){
                //选择给id为b1的按钮设置一个点击事件
                $("#b1").click(function(){
                    // 键值对定义一个对象
                    x = {name:"admin",pwd:"123"}
                    // ajax方法:异步请求,只刷新部分
                    $.ajax({
                        //请求方式
                        type : "POST",
                        //请求地址
                        url : "http://localhost:8080/fxx",
                        //请求数据
                        data : x,
                        // //如果使用json字符串,则要修改请求类型
                        // contentType: "application/json;charset=UTF-8",
                        // data : JSON.stringify(x),
                        //请求成功
                        success : function(result) {
                            // alert(result);  //result值为从后端传来的receive ajax
                            // si是span标签的id
                            var t = document.getElementById("s1").innerHTML;
                            // alert(t); // span标签内显示的文字数据(最初是空白)
                            
                            // 获取 Id 所在标签对其进行html操作
                            document.getElementById("s1").innerHTML = t + result;
                        },
                        //请求失败,包含具体的错误信息
                        error : function(e){
                            console.log(e.status + e.responseText);
                        }
                    });
                });
            });
        </script>
    

代码

  • 后端直接发 json 字符串 — ( JavaScript 解析 ) —> ajax

    // result(自定义) 收到后台 write 传来的数据信息(后台传来的字符串)
    // success:function(result){  } 里: 
    alert(result), // json形式
    alert((JSON.parse(result)).email)}, // 将json字符串解析为js对象,取单值
    // alert(JSON.parse(result)), // [object Object] 无值
    
  • 后端 @ResponseBody + jackson-databind 的 jar 包,直接发一个对象 —— ajax

    • 对象 User{name='zhangsan', email='123@163'} 格式,前台无法解析,所以要加依赖 jackson-databind
    success:function(result) {alert(result.email)}, // 可以直接获取属性值
    success:function(result) {alert(result)}, // [object Object] 无值
    
posted @ 2023-06-18 16:58  朱呀朱~  阅读(45)  评论(0编辑  收藏  举报