Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就已包含在 Spring Framework 中。正式名称“ Spring Web MVC”来自其源模块的名称(spring-webmvc)。
DispatcherServlet
:请求分发器,前端控制器,调用前端控制器。HandlerMapping
,HandlerMapping
的两个主要实现是BeanNameUrlHandlerMapping
和SimpleUrlHandlerMapping
(将 URI 路径模式的显式注册维护到处理程序)。InternalResourceViewResolver
,一般用来解析前端跳转页面url的前后缀。BeanNameUrlHandlerMapping
中对应的url路径的bean。web.xml:
<!-- 配置DispatcherServlet:请求分发器,前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 绑定spring的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 配置启动等级 数字越小越早启动--> <load-on-startup>1</load-on-startup> </servlet> <!-- /:不匹配+.jsp /*:匹配加上 .jsp --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
spring.xml:
<!-- 映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 设配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- BeanNameUrlHandlerMapping对应的url路径 --> <bean id="/test" class="com.vxzx.controller.Testcontroller"/>
Contorller:
public class Testcontroller implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView view = new ModelAndView(); String result = "hello!"; view.addObject("msg",result); view.setViewName("test"); return view; } }
jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
1、用户发送请求到DispatcherServlet。
2、DispatcherServlet收到请求,访问HandlerMapping映射器。
3、映射器查找具体的处理器,生成具体对象。
4、将映射器找到的具体信息一并返回给DispatcherServler。
5、DispatcherServlet调用设配器。
6、设配器会执行具体的Controller层业务工作。
7、将执行完的Controller层,返回具体的信息(ModelAndView)。
8、将设配器获取到的ModelView返回给DispatcherServlet。
9、DIspatcherServlet将获取到的ModelView发送给ViewResolve视图解析器---进行解析。
10、ViewResolve解析完ModelView,返回视图逻辑名。
11、DispatcherServlet通过view渲染到前端,最后返回给客户端界面。
以上的这些都是都是SpringMVC帮我们做好的,我们不需要自己手动去实现。
使用注解必须记住:@Controller
、@RequestMapping
....等词。
使用步骤:
Controller:
@Controller public class ControllerTest { @RequestMapping("/h1") //在页面上输入的url public String test(Model model){ model.addAttribute("msg",“ControllerTest1”); return "test"; //需要跳转到的页面 }
springmvc.xml
<!-- 扫描该包 --> <context:component-scan base-package="com.vxzx.controller"/> <!-- 静态资源过滤 --> <mvc:default-servlet-handler/> <!-- mvc注解开启 --> <mvc:annotation-driven/> <!-- 视图解析器: --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
扩展:
RequestMapping:在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求。
@RequestMapping 中的 value 和 path 属性(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,用来实现url跳转的。)
@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。一共有这几种请求:
@PostMapping @GetMapping @DeleteMapping @PatchMapping @PutMapping
通过 @RequestMapping(value="/login",method=RequestMethod.GET) 来指定 login()方法 仅处理通过 GET 方式发来的请求:
@RequestMapping(value = "h1",method = RequestMethod.GET) public String test2(Model model){ model.addAttribute("msg","HelloMVC" ); return "test"; }
由于在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式。
在springmvc我们可以实现转发和重定向,不过在此之前我们需要先关闭视图解析器,不然会出错。
MVC框架中使用forward:forward后面传递的是页面或者服务器端其他url地址,不经过视图解析器。
@RequestMapping("/t2") public String test02(Model model){ model.addAttribute("msg","1234567"); return "forward:/login.jsp"; }
MVC框架中使用redirect:实现路径重定向。
@RequestMapping("/t1") public String test01(Model model){ model.addAttribute("msg","123456"); return "redirect:/login.jsp"; }
使用SpringMVC来了获取前端数据:@RequestParam;
// 方式一:获取前端输入的数据,前提是:后端获取数据的名字要与前端数据的名字一致,不然就获取不到。 @RequestMapping("/h1") public String test(String username,String password){ System.out.println(username + "=====>" + password); return "test"; }
//方式二:如果前后端数据不一致,可以使用@RequestParam定义使用取前端的数据名字,然后进行输出 // 而且使用该方法,如果数据不一致则不会显示null,而会显示405错误. @RequestMapping("/h2") public String test01(@RequestParam("username")String name,@RequestParam("password")String pwd){ System.out.println(name + "=======>" + pwd); return "test"; }
实体类:需要get、set;
private int id; private String name; private int age;
//方式三:如果提交的一个对象,则可以封装成一个对象,然后再进传值,但必须保证对象的名字一致. @RequestMapping("/h3") public String test02(User user){ System.out.println(user); return "test"; }
SpringMVC给我们提供了一个过滤器,可以在web.xml中配置,修改xml文件后需要重启服务器。使用CharacterEncodingFilter
<!-- springmvc提供的避免乱码的过滤器:CharacterEncodingFilter --> <filter> <filter-name>encoding</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> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
还可以使用@RequestMapping中的produce,将数值设置为utf-8就好了。
@RequestMapping(value = "/h4",produces = "application/json;charset=utf-8")
JSON乱码问题解决:
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <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>
JSON简单来说就是字符串,可以让前后端进行完美匹配的字符串。 ```html <script> var test0 = { id : 1, name : "vxzx", age : 1 } // JSON.stringify : 将普通字符串转化成为JSON字符串 var test01 = JSON.stringify(test0); console.log(test01); //JSON.parse将JSON字符串转化成为普通字符串 var test02 = JSON.parse(test01); console.log(test02); </script>
### 2.7.1 jackson的使用 Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。 使用时需要导入jar包: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.3</version> </dependency>
实体类:需要get、set方法;
private int id; private String name;
controller实现类:
@Controller //@RestController //不走视图解析器,该类下的所有方法直接返回接口数据字符串; public class JsonController { @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8") @ResponseBody //不会走视图解析器,直接解析到前端返回一个字符串 public String test(){ User user1 = new User(1,"貔貅"); return user1.toString(); } // 可以在配置文件中 <mvc:annotation-driven> 解决json乱码问题: @RequestMapping("/j2") @ResponseBody public String test01(){ User user = new User(2,"睚眦"); //使用jackson中的包,新建一个类: ObjectMapper mapper = new ObjectMapper(); //writeValueAsString 将字符串转换为json: String str = null; try { str = mapper.writeValueAsString(user); } catch (JsonProcessingException e) { e.printStackTrace(); } return str; } @RequestMapping("/j3") @ResponseBody public String test02() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); // 多个对象可以将其存放在一个list里面,然后在进行输出。 ArrayList<User> list = new ArrayList<User>(); User user1 = new User(1,"狴犴!"); User user2 = new User(3,"狴犴!"); User user3 = new User(2,"狴犴!"); User user4 = new User(4,"狴犴!"); list.add(user1); list.add(user2); list.add(user3); list.add(user4); String str = mapper.writeValueAsString(list); return str; } //JSON的时间会生成时间戳,如果想使用就先将时间戳转换成对应的时间类型; @RequestMapping("/h4") @ResponseBody public String test04() throws JsonProcessingException { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = sdf.format(date); return new ObjectMapper().writeValueAsString(format); }
扩展:将JSON的转换方法封装成一个工具类,在需要使用的时候调用就可以了。
public class JsonUtils { // 实现工具类的重载复用: public static String getJson(Object object){ return getJson(object,"yyyy-MM-dd HH:mm:ss"); } // 将获取JSON的方法封装成一个工具类: public static String getJson(Object object,String dateFormat){ ObjectMapper mapper = new ObjectMapper(); //设置不使用时间戳: mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); //自定义时间格式: SimpleDateFormat sfd = new SimpleDateFormat(dateFormat); mapper.setDateFormat(sfd); try { return mapper.writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } }
调用工具类:
@RequestMapping("/h5") @ResponseBody // 使用工具类: public String test05(){ Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return JsonUtils.getJson(date); }
Fastjson 是一个来自于阿里的JSON解析库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象;Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
使用时需要导入jar包:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency>
实体类:需要get、set方法;
private int id; private String name;
controller实现类:
@RequestMapping("/h6") @ResponseBody // 使用fastjson: public String test06(){ ArrayList<User> list = new ArrayList<User>(); User user1 = new User(1,"狴犴!"); User user2 = new User(3,"狴犴!"); User user3 = new User(2,"狴犴!"); list.add(user1); list.add(user2); list.add(user3); //java对象 转换为 JSON字符串 String str1 = JSON.toJSONString(list); System.out.println("JSON.toJSONString ===>" + str1); String str2 = JSON.toJSONString(user1); System.out.println("JSON.toJSONString =====>" + str2); //JSON字符串 转换为 java对象 User user = JSON.parseObject(str2, User.class); System.out.println("JSON.parseObject ===>" + user); //Java对象 转换为 JSON对象 JSONObject json = (JSONObject) JSON.toJSON(user2); System.out.println("JSON.toJSON ===>" + json); //JSON对象 转换为 Java对象 User u1 = JSON.toJavaObject(json,User.class); System.out.println("JSON.toJavaObject ===>" + u1); return str1; }
使用fastjson有这几个常用的方法:
JSON. 方法 | 作用 |
---|---|
toJSONString | java对象 转换为 JSON字符串 |
JSON.parseObject | JSON字符串 转换为 java对象 |
JSON.toJSON | Java对象 转换为 JSON对象 |
JSON.toJavaObject | JSON对象 转换为 Java对象 |