MVC:模型(model)、视图(view)、控制器(Controller)的简写,是一种软件设计规范,是将业务逻辑、数据、显示分离的方法来组织代码,主要用来降低业务逻辑与视图的双向耦合度,它是一种架构模式。
新建Maven父工程,配置pom依赖
<!--导入依赖--> <groupId>Spring_Mvc</groupId> <artifactId>Spring Mvc</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>SpringMvc_01_Servlet</module> </modules> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> </dependencies>建立一个Moudle:子类项目,添加Web app支持;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZjqzr5A-1599125070776)(C:\Users\暴走小萝莉\AppData\Roaming\Typora\typora-user-images\image-20200709195535667.png)]
新建Moudle的pom中,导入Servlet和jsp的jar依赖
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> </dependencies>[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0oHaJ7AC-1599125070786)(C:\Users\暴走小萝莉\AppData\Roaming\Typora\typora-user-images\image-20200711183744691.png)]
在web.xml中配置:
<!--注册dispatcherServlet--> <servlet> <servlet-name>Springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--关联一个springMvc的配置文件【servlet-name】-Servlet.xml--> <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>方法一:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--添加处理映射器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!--添加处理器适配器--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!--添加视图解析器:dispatcherServlet给他的 Model And View--> <!--作用:1.获取了ModelAndView的数据 2.解析ModelAndView的视图名字 3.并按视图名字找到对应的视图 4.将数据渲染给视图上; --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> <!--handle--> <bean id="/hello" class="com.muzi.Controller.HelloController"/> </beans>方法二:
<?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/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--自动扫描包--> <context:component-scan base-package="com.muzi.Controller"/> <!--忽略静态页面--> <mvc:default-servlet-handler/> <!--加载 处理器映射和处理器适配 在注解模式下--> <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> <!-- 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> </beans>注册DispatcherServlet
关联SpringMvc配置文件【在Resource下创建】【servlet-name】-Servlet.xml
启动级别为1
映射路径为/(/*不建议使用)
<!--配置dispatcherServlet--> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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> <servlet-mapping> <servlet-name>SpringMvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>让IOC注解生效
静态资源过滤:html、css、jsp
mvc注解驱动
配置视图解析
在resource的目录下添加SpringMvc—servlet,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/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--处理器映射--> <!--处理器适配器--> <!--自动扫描包,让指定包下面的注解生效,由ioc容器统一管理--> <context:component-scan base-package="com.muzi.Controller"/> <!--让 SpringMvc不处理静态资源 ,过滤静态资源--> <mvc:default-servlet-handler/> <!--支持Mvc注解驱动 在Spring中一般采用@RequestMapping注解来完成映射关系 要想使注解生效@RequestMapping,必须向上下文中注册defaultAnnotationHandleMapping 和一个AnnotationMethodHandleAdapter实例 这两个实例分别在类级别和方法级别处理 而Annotation-driver帮助我们自动完成两个实例的注入 --> <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> </beans>编写一个Java类 com.muzi.Controller.springcontroller
@Controller //如果在类层写@RequestMapping("/controller")注解需要在请求地址时,在前面加其,在加方法上的mapping名字; //localhost8080:/controller/spring public class SpringController { @RequestMapping("/hello") public String hello(Model model){ //封装书据 model.addAttribute("msg","使用注解成功"); return "hello"; //被视图解析去处理 } } 方法方会的结果是视图的名称(spring),加上视图解析的前后缀就会变成完整的路径“/WEN-INF/jsp/spring.jsp”注:retur返回的字符串必须与创建视图层的jsp页面名字相同el表达式直接取出存放的值
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html> Restfule风格是一种软件架构风格,而不是标准,只是提供了一种设计原则和约束条件。主要适用于客户端和服务器端交互的软件。是基于http协议实现。目的是为了提高系统的可伸缩性,降低应用之间的耦合度,方便框架分布式处理程序。基于这个风格的软件可更加的简单、更有层次,更易于实现缓存的机制。 在resultful风格中,用户请求的url使用同一个URL而用请求方式:get/post/delete/put等方式对请求的处理方法进行区分。这样可以在前后台分离的开发中让前端开发人员不会对请求的资源地址产生混淆,形成一个统一的接口。
地到url的复用
每种url代表了一种资源。
客户端和服务器之间,传递这个资源的某种表现层。
客户端通过四个http动词,对服务器资源进行操作。实现表现层状态的转化。
在方法的传参中需要使用==@pathVariable(路径变量)==来限定
@RequestMapping("/user3/{a}/{b}") public String user3(@PathVariable int a, @PathVariable int b , Model model ){ int res=a+b; model.addAttribute("msg","计算结果:"+res); return "user"; }在SpringMvc中,当视图解析器起作用时,转发和重定向,视图解析是页面的拼接;对于转发我们直接return页面就好,而对于重定向我们要加关键字redirect:页面名.jsp实现重定向;
//转发和重定向 @Controller public class ModelTest { @RequestMapping("/t1") public String Test1(Model model){ //视图解析器起作用 model.addAttribute("msg","测试test1"); return "user";//转发 } @RequestMapping("t2") public String Test2(Model model){ model.addAttribute("msg","重定向看情况"); return "redirect:a.jsp";//重定向 } }需要使用全路径
@Controller public class ModelTest2 { //没有视图转发器 @RequestMapping("/mt") public String myTest1(Model model){ model.addAttribute("msg","mytest测试"); return "/a.jsp"; //转发 //或者使用 return "forward:/a.jsp" } @RequestMapping("/mt2") public String mytest2(Model model){ model.addAttribute("msg","mytest2"); return "redirect:/WEB-INF/jsp/user.jsp";//重定向 } }利用方法的参数接收前端传来的数据,当前端的传值名和接收的参数名不一致时,我们将接收不到信息;
@GetMapping("/usert") public String usertwo( String name, Model model){ //接受前端参数 System.out.println("前端参数为:"+name); //将接受到了结果返回给前端 model.addAttribute("msg",name); //视图跳转 return "user"; }如果传递的是一个对象时,会自动匹配对象中的字段名,如果字段名不一致,则匹配失败
@Controller public class UserModel { //接受前端参数,如果是一个类的话,他就自动匹配 @GetMapping("/usermo") public String user(User user){ System.out.println(user); //返回给视图 return "user"; }自己手动配置filter过滤器请求
先创建一个Filter类实现Filter(javax.servlet)接口,实现方法的重写
package com.muzi.Filter; import javax.servlet.*; import java.io.IOException; public class EncodingFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //改变编码 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); // 让程序继续执行 chain.doFilter(request,response); } public void destroy() { } }在web.xml中手动配置Filter过滤器处理
<!--手动配置--> <filter> <filter-name>encoding</filter-name> <filter-class>com.muzi.Filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>对象表示为键值对,数据由逗号分隔;
花括号保存对象;{}—对象
方括号保存数组;[]—数组
使用JSON.Stringify()方法可以将js对象转化为字符串;
使用JSON.parse()方法可以将json字符串转化为js对象;
<script type="text/javascript"> //定义一个json var user={ name:"木子", sex:"男", age:18 }; //将js对象转化为json字符串 var json=JSON.stringify(user); console.log(json) //将json字符串转化为js对象 var obj=JSON.parse(json); console.log(obj) /*console.log(user)*/ </script>Jackson是应用较为广泛的,用来序列化和反序列json的开源框架,而在SpringMvc中默认的json解析器就是jsckson,Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。
在maven项目中我们可以在其pom.xml中导入依赖的架包,jackson-databind(数据绑定) 提供了基于==“对象绑定”解析的相关API和“树模型”解析的相关API,二者都是依赖基于“流模型”==解析的API;
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.0</version> </dependency>jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core (核心包)和 jackson-annotations(注解包) 也随之添加到 Java 项目工程中。
@Controller是一个控制器类,被他标注的类会被Spring扫描,需要交给spring来托管,在json中需要与使用==@ResponseBody配合==使用来给前端返回一个字符串,而不走视图解析层。
我们也可以直接使用==@RestController在类中其作用与@Controller与@ResponseBody配合使用效果一致==然后再方法上 直接使用@RequestMapping("/")
常规对于类对象字符串的转化
public class JaskSonTest { @RequestMapping("/j1") @ResponseBody//不会走视图解析,直接返回一个字符串 //不使用jaskson的字符串 public String User(){ User user = new User("木子", 18, "男"); return user.toString(); } //使用Jaskson转化字符串 @RequestMapping("/j2") //@ResponseBody//不走视图解析器 public String user2() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); User user = new User("木子", 18, "男"); String str = mapper.writeValueAsString(user); return str; }数组在json中的使用表现
//数组在json中的使用 @RequestMapping("/j3") public String user3() throws JsonProcessingException { //对象绑定 ObjectMapper mapper = new ObjectMapper(); User user = new User("木子号",18,"男"); User user1 = new User("木子1号",18,"男"); User user2= new User("木子2号",18,"男"); User user3= new User("木子3号",18,"男"); ArrayList<User> list = new ArrayList<User>(); list.add(user); list.add(user1); list.add(user2); list.add(user3); String str = mapper.writeValueAsString(list); return str; }时间戳在json中的解决方法
方法一:
//时间戳在json中的使用——纯Java方式 @RequestMapping("/j4") public String User4() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); Date date = new Date(); //自定义时间(纯Java) SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String ts = sdf.format(date); //转化为字符串 String tr = mapper.writeValueAsString(ts); }方法二:
@RequestMapping("/j4") public String User4() throws JsonProcessingException { //对象绑定 ObjectMapper mapper = new ObjectMapper(); Date date = new Date(); //序列化处理 mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS,false); //定义时间格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); mapper.setDateFormat(sdf); //将时间转化输出 String str = mapper.writeValueAsString(date); return str; }在我们使用绑定对象的时候发现有大量重复的代码,我们可以将它们提取出来,封装成工具类在之后的使用我我们可以直接进行使用,减少了代码的重复写,提高了效率;
public class JsonUtil { //实现工具类的复用(需要在return中返回其相同的方法,实现方法的重写) //在对数的工具类中都会遇到这类想法; public static String getJson(Object object){ return getJson(object,"YYYY-MM-dd hh:mm:dd"); } public static String getJson(Object object,String dateformat){ ObjectMapper mapper = new ObjectMapper(); //不使用时间戳 mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS,false); SimpleDateFormat sdf = new SimpleDateFormat(dateformat); mapper.setDateFormat(sdf); try { String str = mapper.writeValueAsString(object); return str; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } }FastJson是一个java库,它可以将java对象转化为json格式,也可以将json字符串转化为Java对象;可以操作任何Java对象,即使是一些预先存在没有源码的对象;
在Maven项目下的pom.xml中我们需要导入FASTJSON的依赖支持;
静态资源导出问题
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>