ssm框架-2

ssm框架

  • 完成后源码及文件目录
  • 注解方式访问controller
    • pom.xml
  • 如何返回json,前提pom.xml要引用jackson
    • 使用jackson
    • 直接响应出一个json字符串
  • 前后端数据如何传值
    • 中文乱码问题,配置编码格式过滤器
    • 前端的数据传入后端
      • 最原始的方式传值
      • springMVC的方式传值-1
      • springMVC的方式传值-2
      • 如果有两个对象需要封装,且两个对象的属性名是相同的,如何处理呢?
        • 错误演示:
        • 解决方法:
    • 后端的值传入前端
      • 后端的值传入前端方式1-使用HttpServletRequest
      • 后端的值传入前端方式2-使用ModelAndView
      • 后端的值传入前端方式3-使用Model
      • 后端的值传入前端方式4-使用ModelMap
      • 使用Model与ModelMap的区别演示
      • 场景演示:user.jsp页面的数据传送到后台,数据处理后,在返回到index.jsp页面
        • 效果展示:
        • 代码
      • 后端的值传入前端方式总结

完成后源码及文件目录

源码已经上传到了gitHub,点击这里去gitHub下载或者查看源码
在这里插入图片描述
在这里插入图片描述

注解方式访问controller

首先在spring-mvc.xml里配置开启MVC框架的所有注解,配置要扫描的包
spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--凡是在com.mvc.demo包下标注了@Controller注解的类都可以被spring容器管理--><!--扫描多个包-->
<context:component-scan base-package="com.torey.controller,com.torey.translate"/><!--开启MVC框架的所有注解方式,将文件spring-webmvc-4.3.14.RELEASE.jar!/org/springframework/web/servlet/DispatcherServlet.properties 中的交给spring容器管理--><mvc:annotation-driven></mvc:annotation-driven>
</beans>

pom.xml

    <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.3.14.RELEASE</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.7</version></dependency>

如何返回json,前提pom.xml要引用jackson

使用jackson

首先在pom.xml文件中引入jackson包

   <!-- jackson  json处理--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version></dependency>

返回json有两种方式:

  1. 直接响应出一个json字符串
  2. 使用jackson将对象转换为json字符串后再返回

直接响应出一个json字符串

**controller是单例类
在Controller类的方法中加上@ResponseBody注解,示例如下:
TestController1.java

package  com.torey.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.Map;
@Controller //标注@Controller注解的类会被spring容器管
@RequestMapping("test1")
public class TestController1 {public TestController1 (){System.out.println("TestController1 tomcat启动时,构造函数实例化");
}@RequestMapping("/index")public String index(){System.out.println("=========ddsss========");return "redirect:/index.jsp";}//返回json,有两种方式 1 直接响应出一个json字符串 2  使用jackson//1 直接响应出一个json字符串//@ResponseBody  返回的数据会自动转换为json//@RequestMapping("/json.do")//@RequestMapping("/json.action") 后缀建议是.do或者.action,不可以是.html@RequestMapping("/json")public @ResponseBody Map<String,Object> mapJson(){//前提pom.xml文件中一定要引用jackson-databindMap<String,Object> map=new HashMap<>();map.put("name","torey");map.put("sex","男");map.put("birth","1988.10.05");return  map;}
}

在这里插入图片描述sss

前后端数据如何传值

中文乱码问题,配置编码格式过滤器

spring容器有一个现有的过滤器:org.springframework.web.filter.CharacterEncodingFilter
在这里插入图片描述
CharacterEncodingFilter类成员如下:
在这里插入图片描述
CharacterEncodingFilter类重写了doFilterInternal方法,源码如下:

	@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {String encoding = getEncoding();if (encoding != null) {if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {request.setCharacterEncoding(encoding);}if (isForceResponseEncoding()) {response.setCharacterEncoding(encoding);}}filterChain.doFilter(request, response);}

doFilterInternal方法里有String encoding = getEncoding();getEncoding() 方法如下:

	public String getEncoding() {return this.encoding;}
	public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {Assert.hasLength(encoding, "Encoding must not be empty");this.encoding = encoding;this.forceRequestEncoding = forceRequestEncoding;this.forceResponseEncoding = forceResponseEncoding;}

根据CharacterEncodingFilter类的构造函数,只需要在web.xml里配置编码格式过滤器,即可
在这里插入图片描述
在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>forceRequestEncoding</param-name><param-value>true</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>

前端的数据传入后端

最原始的方式传值

springMVC的方式传值-1

springMVC的方式传值-2

如果有两个对象需要封装,且两个对象的属性名是相同的,如何处理呢?

错误演示:

User .java,(工具生成Get/Set方法组,重写toString方法,这里就不贴代码了)

package com.mvc.deme;
public class User {private Long userId;private String userName;private String remark;}

Account.java,(工具生成Get/Set方法组,重写toString方法,这里就不贴代码了)

package com.mvc.deme;
public class Account {private String userName;private String passWord;
}
<h5>使用springMVC获取前端参数-3演示,有两个对象,但这两个对象的同时都有userName这个属性,错误演示:</h5>
<form action="user/springMvcSetUser3" method="post"><p>编号:<input type="text" name="userId"></p><p>用户名:<input type="text" name="userName"></p><p>备注:<input type="text" name="remark"></p><p>账号名:<input type="text" name="userName"></p><p>密码:<input type="text" name="passWord"></p><p><input type="submit" value="提交" ></p>
</form>

在这里插入图片描述
ValueController.java

  /***如果有两个对象需要封装,且两个对象的属性名是相同的,如何处理呢?* 错误演示:*/@RequestMapping(value = "springMvcSetUser3")public String setUser(User user, Account account){System.out.println("springMvcSetUser3:"+user.toString());System.out.println("springMvcSetUser3:"+account.toString());return  "/index.jsp";}

执行结果如下:会将两个userName的数据以逗号形式拼接在一起
在这里插入图片描述

解决方法:

利用数据传输层,界面与业务层的数据传输,也就是DTO层,注意:DTO层最好只放对象,不要放属性
新建DTO包,在该包下新建BaseDTO 类,(工具生成Get/Set方法组,重写toString方法,这里就不贴代码了)如下:

package com.mvc.DTO;
import com.mvc.deme.Account;
import com.mvc.deme.User;
/*** DTO数据传输层(要求:只能提供自定义对象,不能放包装类和基本数据类型)* DTO与VO的区别:* VO:既可以放属性(也就是包装类和基本数据类型),也可以放对象*/
public class BaseDTO {private User user;private Account account;}

user.jsp页面

<h5>使用springMVC获取前端参数-3演示,有两个对象,但这两个对象的同时都有userName这个属性,解决方法:</h5>
<form action="user/springMvcSetUser4" method="post"><p>编号:<input type="text" name="user.userId"></p><p>用户名:<input type="text" name="user.userName"></p><p>备注:<input type="text" name="user.remark"></p><p>账号名:<input type="text" name="account.userName"></p><p>密码:<input type="text" name="account.passWord"></p><p><input type="submit" value="提交" ></p>
</form>

ValueController.java

  /***如果有两个对象需要封装,且两个对象的属性名是相同的,如何处理呢?* 解决方法:*/@RequestMapping(value = "springMvcSetUser4")public String setUser(BaseDTO baseDTO){System.out.println("springMvcSetUser4:"+baseDTO.toString());return  "/index.jsp";}

在这里插}入图片描述

后端的值传入前端

后端的值传入前端方式1-使用HttpServletRequest

ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {@RequestMapping(value = "front")public String requestTest(HttpServletRequest request){request.setAttribute("name","小明");//注意:这里一定是转发,不然数据传不到前台return "/index.jsp";}}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
注解方式
<hr>
name:${name}
</body>
</html>

效果如下:
在这里插入图片描述

后端的值传入前端方式2-使用ModelAndView

ModelAndView有3种添加值的方法,使用时可以根据需求选择相应的方法
在这里插入图片描述
ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {//后端的值传入前端方式2-使用ModelAndView@RequestMapping(value = "getNameByModelAndView")public ModelAndView modelAndViewTest(){ModelAndView mv=new ModelAndView();mv.addObject("name","小明,使用ModelAndView从后台传值");mv.setViewName("/index.jsp");return mv;}}

index.jsp页面的内容保持不变
效果如下:
在这里插入图片描述

后端的值传入前端方式3-使用Model

Model有4种添加值的方法,使用时可以根据需求选择相应的方法
在这里插入图片描述
ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {//后端的值传入前端方式3-使用Model@RequestMapping(value = "getNameByModel")public  String modelTest(Model model){model.addAttribute("name","小明,使用Model从后台传值");return  "/index.jsp";}}

index.jsp页面的内容保持不变
效果如下:
在这里插入图片描述

后端的值传入前端方式4-使用ModelMap

通过查看ModelMap的源码得知:ModelMap继承于LinkedHashMap,ModelMap就是Map集合,如下:
在这里插入图片描述
在这里插入图片描述
ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {
//后端的值传入前端方式4-使用ModelMap@RequestMapping(value = "getNameByModelMap")public  String modelMapTest(ModelMap modelMap){modelMap.addAttribute("name","小明,使用ModelMap从后台传值");return "/index.jsp";}}

index.jsp页面的内容保持不变
效果如下:
在这里插入图片描述

使用Model与ModelMap的区别演示

Model与ModelMap的区别:Model接口有一个Map集合,ModelMap继承于LinkedHashMap,也是一个map集合,这两个没有太大的区别
ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {
@RequestMapping(value = "getNameByModel2")public  String modelTest(Model model,User user){System.out.println("Model:" + model);model.addAttribute("name","小明,使用Model从后台传值");return  "/index.jsp";}@RequestMapping(value = "getNameByModelMap2")public  String modelMapTest(ModelMap modelMap,Account account){System.out.println("ModelMap:" + modelMap);modelMap.addAttribute("name","小明,使用ModelMap从后台传值");return "/index.jsp";}}

index.jsp页面的内容保持不变
效果如下:
在这里插入图片描述

场景演示:user.jsp页面的数据传送到后台,数据处理后,在返回到index.jsp页面

效果展示:

在这里插入图片描述
在这里插入图片描述

代码

user.jsp

<h5>将本页面的数据传送到后台,数据处理后,在返回到index.jsp页面</h5>
<form action="user/getNameByModelMap3" method="post"><p>baseDTO.user.userName用户名:<input type="text" name="user.userName"></p><p>baseDTO.account.userName账号名:<input type="text" name="account.userName"></p><p><input type="submit" value="提交" ></p>
</form>

ValueController.java

@Controller //Controller 是单例的
@RequestMapping(value = "user")//@RequestMapping 根的访问路径
public class ValueController {
//演示将user.jsp页面的数据传送到后台,数据处理后,在返回到index.jsp页面@RequestMapping(value = "getNameByModelMap3")public  String modelMapTest(ModelMap modelMap,BaseDTO baseDTO){baseDTO.getUser().setUserName(baseDTO.getUser().getUserName()+"数据处理了");baseDTO.getAccount().setUserName(baseDTO.getAccount().getUserName()+"数据处理了");return "/index.jsp";}}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
baseDTO.account.userName:${baseDTO.account.userName}<p></p>
baseDTO.user.userName:${baseDTO.user.userName}<p></p>
</body>
</html>

后端的值传入前端方式总结

现在一般传值方式都是将 对象数据转换为Json格式,返回到前端,以上四种方式都可以将转换后的json数据返回到前端,使用时可以根据业务需求使用合适的