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\":\"[email protected]\"}"; // 后台打入规定的JSON字符串
res.getWriter().write(str1); // 再写到前端,成:{"name":"zyz","email":"[email protected]"} —— 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信息弹窗:[email protected] 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\":\"[email protected]\"}";
-
返回值 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)}, // 可以直接获取属性值