文章目录

  • 一、MVC架构
    • 1、概念
    • 2、好处
  • 二、SpringMVC的具体实现步骤
    • 1、xml配置版
      • 1.1 在pom.xml文件中添加依赖
      • 1.2 配置web.xml
      • 1.3 配置springmvc.xml
      • 1.4 编写控制层类和方法
    • 2、注解开发版
      • 2.1 在pom.xml文件中添加依赖
      • 2.2 配置web.xml
      • 2.3 配置springmvc.xml
      • 2.4 编写控制层类和方法
    • 3、可能遇到的问题
  • 三、接收请求参数
    • 1、基本类型参数
    • 2、实体接收参数【重点】
    • 3、数组接收参数
    • 4、集合接收参数
      • 错误解决办法:
    • 5、路径携带参数
    • 6、中文乱码解决
  • 四、跳转
    • 1、转发
    • 2、重定向
    • 3、跳转细节
  • 五、传值
    • 1、 Request和Session
    • 2、 JSP中取值
    • 3、 Model
    • 4、 ModelAndView
    • 5、ModelMap
    • 6、 @SessionAttributes
    • 7、对比
  • 六、静态资源
    • 1、 静态资源问题
    • 2、 解决方案1
    • 3、 解决方案2
    • 4、 解决方案3
  • 七、JSON数据的处理
    • 1、导入依赖
    • 2、@ResponseBody
    • 3、@RestController
    • 4、@RequestBody
    • 5、测试
      • 5.1 ajax发送json数据
      • 5.2 postman发送json数据
    • 6、Jackson常用注解
      • 6.1 日期格式化
      • 6.2 属性名修改
      • 6.3 属性忽略
      • 6.4 null和empty属性排除
      • 6.5 自定义序列化
    • 7、 FastJson
      • 7.1 导入依赖
      • 7.2 安装FastJson
      • 7.3 使用
      • 7.4 常用注解
      • 7.5 fastjson和Jackson的区别
  • 八、异常解析器
    • 1、 现有方案,分散处理
    • 2、 异常解析器,统一处理
  • 九、拦截器
    • 1、 作用
    • 2、 定义拦截器
    • 3、 配置拦截路径
  • 十、上传
    • 1、SpringMVC的上传
      • 1.1 导入依赖
      • 1.2 页面表单代码
      • 1.3 在springmvc.xml中配置上传解析器
      • 1.4 Handler
    • 2、七牛云上传
      • 2.1 导入依赖
      • 2.2 页面表单代码
      • 2.3 编写工具类
      • 2.4 Handler
  • 十一、下载
    • 1、 超链
    • 2、 Handler
  • 十二、验证码
    • 1、导入依赖
    • 2、在web.xml中声明验证码组件
    • 3、html页面
  • 十三、REST
    • 1、 开发风格
    • 2、 优点
    • 3、 使用
      • 3.1 定义Rest风格的 Controller
      • 3.2 Ajax请求
  • 十四、跨域请求
    • 1、 域
    • 2、 Ajax跨域问题
    • 3、 解决方案
  • 十五、SpringMVC的执行流程
  • 十六、SSM整合(Spring+Spring MVC+Mybatis)
    • 1、 整合思路
    • 2、整合技巧
    • 3、整合的步骤:
      • 3.1 添加依赖
      • 3.2 整合Spring和Mybatis
      • 3.3 SpringMVC的xml配置
      • 3.4 web.xml配置

一、MVC架构

1、概念

名称 职责
Model 模型:即业务模型,负责完成业务中的数据通信处理,对应项目中的 service和dao
View 视图:渲染数据,生成页面。对应项目中的Jsp
Controller 控制器:直接对接请求,控制MVC流程,调度模型,选择视图。对应项目中的Servlet

2、好处

  • MVC是现下软件开发中的最流行的代码结构形态;
  • 人们根据负责的不同逻辑,将项目中的代码分成 M V C 3个层次;
  • 层次内部职责单一,层次之间耦合度低;
  • 符合低耦合 高内聚的设计理念。也实际有利于项目的长期维护。

二、SpringMVC的具体实现步骤

1、xml配置版

1.1 在pom.xml文件中添加依赖

<!--SpingMVC的依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.5.RELEASE</version>
</dependency>
<!--servlet的依赖-->
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version>
</dependency>

1.2 配置web.xml

<!--配置DispatcherServlet:SpringMVC的核心,请求分发器,前端控制器-->
<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--声明spring配置文件的位置,这个如果不写,默认是在/WEB-INF/springmvc-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--启动级别--><load-on-startup>1</load-on-startup>
</servlet>
<!--在SpringMVC中,/  /* 分别是什么意思:/:   只匹配所有请求,但不会去匹配jsp页面/*:  匹配所有的请求,还有jsp页面
-->
<servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

注:spring的配置文件的位置如果不声明,默认是在/WEB-INF/下查找名为 springmvc-servlet.xml 的文件

1.3 配置springmvc.xml

<!--处理器映射器,有很多种,这个很low,但是用来讲原理很好-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/><!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!--视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--前缀  注意后面的斜杠必须加,不然会找不到--><property name="prefix" value="/WEB-INF/jsp/"/><!--后缀--><property name="suffix" value=".jsp"/>
</bean><!--BeanNameUrlHandlerMapping这个视图解析器根据名字找bean,所以要配置一个bean-->
<bean id="/hello" class="com.mxd.controller.HelloController"/>

1.4 编写控制层类和方法

//控制层要实现Controller接口,注意和注解的区分
public class HelloController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mav = new ModelAndView();//调用业务层代码String res ="Hello SpringMVC!";//假设返回的是这个字符串mav.addObject("msg", res);//视图跳转mav.setViewName("test");//跳转到/WEB-INF/jsp/test.jsp页面return mav;}
}

2、注解开发版

2.1 在pom.xml文件中添加依赖

<!--SpingMVC的依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.5.RELEASE</version>
</dependency>

2.2 配置web.xml

和上面的web.xml配置一样

2.3 配置springmvc.xml

<!--1.自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.mxd.controller"/>
<!--2.让Spring MVC不处理静态资源(.css  .js等等) -->
<mvc:default-servlet-handler /><!--3.注册mvc注解驱动在spring中一般采用@RequestMapping注解来完成映射关系要想使@RequestMapping注解生效,必须向上下文中注册DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例。这两个实例分别在类级别和方法级别处理。而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven /><!--4.视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--前缀  注意后面的斜杠必须加,不然会找不到--><property name="prefix" value="/WEB-INF/jsp/"/><!--后缀--><property name="suffix" value=".jsp"/>
</bean>

2.4 编写控制层类和方法

@Controller//标记这个类是一个控制器 :表现层
@RequestMapping("/my")//访问路径 ,等价于url-pattern
public class HelloController {@RequestMapping("/hello")//请求路径就为 /my/hellopublic String test1(Model model){//向模型中添加属性msg与值,可以在JSP页面中取出并渲染model.addAttribute("msg", "Hello SpringMVC!");return "hello";//在/WEB-INF/jsp/下查找名为hello.jsp的页面}
}

3、可能遇到的问题

可能遇到的问题:访问出现404,排查步骤:

  1. 查看控制台输出,看一下是不是缺少了什么jar包。
  2. 如果jar包存在,显示无法输出,就在IDEA的项目发布中,添加lib依赖!

File → Project Structure → Artifacts 选择你的项目,查看WEB-INF下有没有lib目录,如果没有,新建一个lib文件夹,然后将jar包加入进去即可

  1. 重启Tomcat 即可解决!
  2. 如果在jsp中EL表达式不起作用,在头部添加:[<%@ page isELIgnored=“false” %>

三、接收请求参数

1、基本类型参数

请求的参数名称和方法的形参 同名即可

springMVC默认可以识别的日期字符串格式为: YYYY/MM/dd HH:mm:ss
通过@DateTimeFormat可以修改默认日志格式

如果请求地址中的参数名称和后端方法中的参数名称不一致时使用@RequestParam(“xxxx”)指定参数名称

@Controller
public class HelloController {//处理日期格式用@DateTimeFormat()注解@RequestMapping(value="/hello")public String test1(Model model,@RequestParam("name") String name2, int age, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birth){model.addAttribute("msg", name2+"   "+age+"   "+birth);return "hello";}
}

请求地址为:http://localhost:8080/hello?name=张三&age=23&birth=2021-2-2

2、实体接收参数【重点】

请求的参数名称和实体的属性 同名即可

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birth;
}
@RequestMapping(value = "/hello2")
public String test1(User user, Model model) {System.out.println(user);model.addAttribute("msg", user);return "hello";
}

请求地址为:http://localhost:8080/hello2?name=张三&age=23&birth=2021-12-4

3、数组接收参数

请求的参数名称要和数组的名称相同

<form action="/hello3" method="post"><input type="checkbox" name="hobby" value="足球">足球<br/><input type="checkbox" name="hobby" value="篮球">篮球<br/><input type="checkbox" name="hobby" value="排球">排球<br/><input type="submit" placeholder="提交">
</form>
@RequestMapping(value = "/hello3")
public String test1(String[] hobby,Model model) {System.out.println(hobby.length);model.addAttribute("msg", hobby.length);return "hello";
}

4、集合接收参数

实体类:

@Data
public class UserList {List<User> userList;
}

控制层的方法:

@RequestMapping(value = "/hello4")
public String test1(UserList userList, Model model) {System.out.println(userList);model.addAttribute("msg", userList);return "hello";
}

请求地址为:http://localhost:8080/hello4?userList[0].name=张三&userList[0].age=22

错误解决办法:

1.在本地tomcat的解压目录 conf中的server.xml 的服务器配置:加上特殊符号的识别

URIEncoding=“utf-8”
relaxedPathChars="|{}[],%"
relaxedQueryChars="|{}[],%"

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" URIEncoding="utf-8" relaxedPathChars="|{}[],%"relaxedQueryChars="|{}[],%"/>

2.注意:tomcat版本太高,这种传参方式:那么直接400 (当前高版本数据格式不识别)

5、路径携带参数

@PathVariable将{id}路径匹配到值赋给id参数
路径名和参数名相同则@PathVariable(“id”)可简写为 @PathVariable

@RequestMapping(value = "/hello5/{name}/{age}")
public String test1(@PathVariable("name") String name, @PathVariable int age, Model model) {model.addAttribute("msg", name+"  "+age);return "hello";
}

请求路径为:http://localhost:8080/hello5/张三/22

6、中文乱码解决

首先,页面中字符集统一

JSP : <%@page  pageEncoding="utf-8" %>
HTML : <meta charset="UTF-8">

其次,tomcat中字符集设置,对get请求中,中文参数乱码有效

Tomcat配置:URIEncoding=utf-8示例:
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />

最后,设置此filter,对post请求中,中文参数乱码有效

<!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); -->
<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>

如果还有问题,就使用下列自定义过滤器:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;/**
* 解决get和post请求 全部乱码的过滤器
*/
public class GenericEncodingFilter implements Filter {@Override
public void destroy() {}@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//处理response的字符编码HttpServletResponse myResponse=(HttpServletResponse) response;myResponse.setContentType("text/html;charset=UTF-8");// 转型为与协议相关对象HttpServletRequest httpServletRequest = (HttpServletRequest) request;// 对request包装增强HttpServletRequest myrequest = new MyRequest(httpServletRequest);chain.doFilter(myrequest, response);
}@Override
public void init(FilterConfig filterConfig) throws ServletException {}}//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {private HttpServletRequest request;
//是否编码的标记
private boolean hasEncode;
//定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
public MyRequest(HttpServletRequest request) {super(request);// super必须写this.request = request;
}// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {// 先获得请求方式String method = request.getMethod();if (method.equalsIgnoreCase("post")) {// post请求try {// 处理post乱码request.setCharacterEncoding("utf-8");return request.getParameterMap();} catch (UnsupportedEncodingException e) {e.printStackTrace();}} else if (method.equalsIgnoreCase("get")) {// get请求Map<String, String[]> parameterMap = request.getParameterMap();if (!hasEncode) { // 确保get手动编码逻辑只运行一次for (String parameterName : parameterMap.keySet()) {String[] values = parameterMap.get(parameterName);if (values != null) {for (int i = 0; i < values.length; i++) {try {// 处理get乱码values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}}}}hasEncode = true;}return parameterMap;}return super.getParameterMap();
}//取一个值
@Override
public String getParameter(String name) {Map<String, String[]> parameterMap = getParameterMap();String[] values = parameterMap.get(name);if (values == null) {return null;}return values[0]; // 取回参数的第一个值
}//取所有值
@Override
public String[] getParameterValues(String name) {Map<String, String[]> parameterMap = getParameterMap();String[] values = parameterMap.get(name);return values;
}
}

然后再xml中配置这个自定义过滤器:

<filter>
<filter-name>encoding</filter-name>
<filter-class>com.mxd.filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

四、跳转

1、转发

@RequestMapping("/forw")
class ForwardController{@RequestMapping("/test1")public String testForward(){System.out.println("test forward1");// 转发跳转 /views/users.jsp// return "views/users";//和下一行等价return "forward:/views/users.jsp";}@RequestMapping("/test2")public String testForward2(){System.out.println("test forward2");//转发到  /forw/test1//return "forward:test1";//相对路径(转发到本类中的test1)//转发到  /forw/test1return "forward:/forw/test1"; //绝对路径}
}

2、重定向

@RequestMapping("/redir")
class RedirectController{@RequestMapping("/test1")public String testRedirect1(){System.out.println("test redirect1");//重定向到 /redir/test1//return "redirect:test1"; //相对路径(转发到本类中的test1)return "redirect:/redir/test1";//绝对路径}@RequestMapping("/test2")public String testRedirect2(){System.out.println("test redirect2");//重定向到 /views/users.jspreturn "redirect:/view/user.jsp";}
}

3、跳转细节

  • 在增删改之后,为了防止请求重复提交,重定向
  • 在查询之后,可以做转发

五、传值


C得到数据后,跳转到V,并向V传递数据。进而V中可以渲染数据,让用户看到含有数据的页面

转发跳转:Request作用域

重定向跳转:Session作用域

1、 Request和Session

//形参中 即可获得 request 和 session对象
@RequestMapping("/test1")
public String testData(HttpSession session,HttpServletRequest req,Integer id){session.setAttribute("user",new User());req.setAttribute("age", 18);req.setAttribute("users",Arrays.asList(new User(),new User()));//return "test2";return "forward:/WEB-INF/test2.jsp";
}

2、 JSP中取值

建议:重点复习 EL JSTL

//jsp中用EL表达式 取值即可
${sessionScope.user.name} <br/>
${sessionScope.user.birth} <br>
${requestScope.age}

3、 Model

//model中的数据,会在V渲染之前,将数据复制一份给request
@RequestMapping("/test")
public String testData(Model model){model.addAttribute("name", "张三");return "index";
}//jsp中用EL表达式 取值即可
${requestScope.name}

4、 ModelAndView

//modelandview 可以集中管理 跳转和数据
@RequestMapping("/test")
public ModelAndView testData(){//返回值类型为ModelAndView//新建ModelAndView对象ModelAndView mv = new ModelAndView();// 设置视图名,还可以设置如何跳转(转发还是重定向)mv.setViewName("forward:/index.jsp");// 增加数据mv.addObject("age",18);return mv;
}//jsp中用EL表达式 取值即可
${requestScope.age}

5、ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}

6、 @SessionAttributes

  • @SessionAttributes({“gender”,“name”}) :model中的 name和gender 会存入session中
  • SessionStatus 移除session
@Controller
@SessionAttributes({"gender","name"}) // model中的 name和gender 会存入session中
public class UserController {@RequestMapping("/hello")public String hello(Model m){m.addAttribute("gender",true); // 会存入sessionmv.addObject("name","zhj"); // 会存入sessionreturn "index";}@RequestMapping("/hello2")public String hello(SessionStatus status){// 移除通过SessionAttributes存入的sessionstatus.setComplete();return "index";}
}

7、对比

Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;

ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;

ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

六、静态资源


1、 静态资源问题

静态资源:html,js文件,css文件,图片文件

静态文件没有url-pattern,所以默认是访问不到的,之所以可以访问,是因为,tomcat中有一个全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是 “/”,是全局默认的Servlet. 所以每个项目中不能匹配的静态资源的请求,有这个Servlet来处理即可。

但,在SpringMVC中DispatcherServlet也采用了 “/” 作为url-pattern, 则项目中不会再使用全局的Serlvet,则静态资源不能完成访问。

2、 解决方案1

DispathcerServlet采用其他的url-pattern

此时,所有访问handler的路径都要以 action结尾!!

<servlet><servlet-name>mvc9</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>mvc9</servlet-name><url-pattern>*.action</url-pattern>
</servlet-mapping>

3、 解决方案2

DispathcerServlet的url-pattern依然采用 “/”,但追加配置

<!-- 额外的增加一个handler,且其requestMapping:  "/**" 可以匹配所有请求,但是优先级最低所以如果其他所有的handler都匹配不上,请求会转向 "/**" ,恰好,这个handler就是处理静态资源的处理方式:将请求转会到tomcat中名为default的Servlet-->
<mvc:default-servlet-handler/>

4、 解决方案3

  • mapping是访问路径,location是静态资源存放的路径
  • 将/html/** 中 /**匹配到的内容,拼接到 /hhh/后
    http://…/html/a.html 访问 /hhh/a.html
<mvc:resources mapping="/html/**" location="/hhh/"/><!--配置资源映射地址-->
<mvc:resources mapping="/bootstrap/**" location="/WEB-INF/static/bootstrap/"/>
<!--<mvc:resources mapping="/js/**" location="/WEB-INF/static/js/"/>
<mvc:resources mapping="/css/**" location="/WEB-INF/static/css/"/>
<mvc:resources mapping="/images/**" location="/WEB-INF/static/images/"/>-->

七、JSON数据的处理

1、导入依赖

<!-- Jackson springMVC默认的Json解析器就是 Jackson,所以只需要导入jackson的jar,即可使用。-->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version>
</dependency>

2、@ResponseBody

@Controller
public class JsonController{    @RequestMapping("/test1")@ResponseBody //将handler的返回值,转换成json(jackson),并将json响应给客户端。public User hello1(){System.out.println("hello world");User user = new User();return user;}// @ResponseBody还可以用在handler的返回值上@RequestMapping("/test2")public @ResponseBody List<User> hello2(){System.out.println("hello world");List<User> users = Arrays.asList(new User(),new User());return users;}// 如果返回值已经是字符串,则不需要转json,直接将字符串响应给客户端
@RequestMapping(value="/test3",produces = "text/html;charset=utf-8") //produces 防止中文乱码@ResponseBody public String hello2(){System.out.println("hello world");return "你好";}
}

3、@RestController

Controller类上加了@RestController注解,等价于在类中的每个方法上都加了@ResponseBody

@Controller
@RestController
public class JsonController{@RequestMapping("/test1")public User hello1(){System.out.println("hello world");User user = new User();return user;}//@ResponseBody还可以用在handler的返回值上@RequestMapping("/test2")public List<User> hello2(){System.out.println("hello world");List<User> users = Arrays.asList(new User(),new User());return users;}
}

4、@RequestBody

@RequestBody**, 接收Json参数

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birth;
}

Controller控制层的方法

@RequestMapping("/json")
//@RequestBody将请求体中的json数据转换为java对象
public String test1(@RequestBody User user, Model model){System.out.println(user);model.addAttribute("msg",user );return "test1";
}

5、测试

5.1 ajax发送json数据

第一种:

var xhr = new XMLHttpRequest();
xhr.open("post","${pageContext.request.contextPath}/json?"+new Date().getTime());
xhr.setRequestHeader("content-type","application/json");//设置请求头
xhr.send('{"name":"张三","age":"22","birth":"2021-12-16"}');//传递json串

第二种:

var user = {name:"张三",age:22,birth:"2021-12-16"};
$.ajax({url:'${pageContext.request.contextPath}/json2/test4',type:'post',contentType:"application/json",//声明请求参数类型为 jsondata:JSON.stringify(user),// 转换js对象成jsonsuccess:function(ret){console.log(ret);}
});

5.2 postman发送json数据

{"name":"张三","age":22,"birth":"2222-02-02"
}

6、Jackson常用注解

6.1 日期格式化

①可以使用spring自带的注解@DateTimeFormat(pattern=“yyyy-MM-dd HH:mm:ss”),但是传入的参数必须是"2021-08-02 22:05:55",否则会抛出异常

②Jackson当中带的注解@JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//必须发送json数据才能接收private Date birth;}

6.2 属性名修改

@JsonProperty(“new_name”)

public class User{@JsonProperty("new_id") //不再使用原属性名,而是 "new_id"private Integer id;private String name;....get/set
}
输出的json:{“new_id”:xx,"name":"xx"}

6.3 属性忽略

@JsonIgnore

public class User{private Integer id;@JsonIgnore // 生成json时,忽略此属性private String name;....get/set
}
输出json时: {"id":xx}

6.4 null和empty属性排除

Jackson 默认会输出null值的属性,如果不需要,可以排除。

@JsonInclude(JsonInclude.Include.NON_NULL) //null值 属性不输出
@JsonInclude(value= JsonInclude.Include.NON_EMPTY) // empty属性不输出( 空串,长度为0的集合,null值)

public class User{private Integer id;@JsonInclude(JsonInclude.Include.NON_NULL) // 若"name==null" 忽略此属性private String name;@JsonInclude(value= JsonInclude.Include.NON_EMPTY)  // 若hobby长度为0或==null 忽略此属性private List<String> hobby;....get/set
}
如果name=null,且 hobby长度为0,则输出json时:{"id":xx}

6.5 自定义序列化

@JsonSerialize(using = MySerializer.class) // 使用MySerializer输出某属性

public class User {private Integer id;private String name;@JsonSerialize(using = MySerializer.class)private Double salary = 10000.126;//在输出此属性时,使用MySerializer输出....get/set
}
则输出json时:{"id":xx,"name":"xxx","salary":10000.13}
public class MySerializer extends JsonSerializer<Double> {// value即 Double salary的值@Override public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {// 将Double salary的值 四舍五入String number = BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_UP).toString();// 输出 四舍五入后的值gen.writeNumber(number);}
}

7、 FastJson

7.1 导入依赖

<!-- FastJson -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version>
</dependency>

7.2 安装FastJson

<mvc:annotation-driven><!-- 安装FastJson,转换器 --><mvc:message-converters><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><!-- 声明转换类型:json --><property name="supportedMediaTypes"><list><value>application/json</value></list></property></bean></mvc:message-converters>
</mvc:annotation-driven>

7.3 使用

@ResponseBody @RequestBody @RestController 使用方法不变

7.4 常用注解

  • 日期格式化:@JSONField(format=“yyyy/MM/dd”)
  • 属性名修改:@JSONField(name=“birth”)
  • 忽略属性:@JSONField(serialize = false)
  • 包含null值:@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) 默认会忽略所有null值,有此注解会输出null
    • @JSONField(serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty) null的String输出为""
  • 自定义序列化:@JSONField(serializeUsing = MySerializer2.class)
public class User implements Serializable{@JSONField(serialize = false)private Integer id;@JSONField(name="NAME",serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty)private String name;@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) private String city;@JSONField(format="yyyy/MM/dd")private Date birth;@JSONField(serializeUsing = MySerializer2.class)private Double salary;...
}
public class MySerializer2 implements ObjectSerializer {@Overridepublic void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,int features) throws IOException {Double value = (Double) object; // salary属性值String text = value + "元";// 在salary后拼接 “元”serializer.write(text); // 输出拼接后的内容}
}
new User(1,null,null,new Date(),100.5);
// 如上对象,转换json:
{NAME:"",city:null,"birth":"2020/12/12","salary":"100.5元"}

7.5 fastjson和Jackson的区别

  • Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。
  • FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。
  • FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
  • Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson社区相对比较活跃,更新速度也比较快, 从Github中的统计来看,Jackson是最流行的json解析器之一,Spring MVC的默认json解析器便是Jackson。

八、异常解析器


1、 现有方案,分散处理

Controller中的每个Handler自己处理异常

此种处理方案,异常处理逻辑,分散在各个handler中,不利于集中管理

public String xxx(){try{...}catch(Exception1 e){e.printStackTrace();return "redirect:/xx/error1";}catch(Exception2 e){e.printStackTrace();return "redirect:/xx/error2";}
}

2、 异常解析器,统一处理

Controller中的每个Handler不再自己处理异常,而是直接throws所有异常。

定义一个“异常解析器” 集中捕获处理 所有异常

此种方案,在集中管理异常方面,更有优势!

public class MyExResolver implements HandlerExceptionResolver{/*** 异常解析器:主体逻辑* 执行时刻:当handler中抛出异常时,会执行:捕获异常,并可以跳到错误页面*/@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {ex.printStackTrace();//打印异常栈//创建一个ModelAndViewModelAndView mv = new ModelAndView();//识别异常if (ex instanceof Exception1) {mv.setViewName("redirect:/xxx/error1");}else if(ex instanceof Exception2){mv.setViewName("redirect:/xxx/error2");}else{mv.setViewName("redirect:/xxx/error");}return mv;}
}
<!-- 声明异常解析器 -->
<bean class="com.baizhi.exception.resolver.MyExResolver"></bean>

九、拦截器

1、 作用

作用:抽取handler中的冗余功能

2、 定义拦截器

执行顺序: preHandle–postHandle–afterCompletion

public class MyInter1 implements HandlerInterceptor{//主要逻辑:在handler之前执行:抽取handler中的冗余代码@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {System.out.println("pre~~~");/*response.sendRedirect("/springMVC_day2/index.jsp");//响应return false;//中断请求*/return true;//放行,后续的拦截器或handler就会执行}//在handler之后执行:进一步的响应定制@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("post~~");}//在页面渲染完毕之后,执行:资源回收@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {System.out.println("after~~");}
}

3、 配置拦截路径

<mvc:interceptors><mvc:interceptor><mvc:mapping path="/inter/test1"/><mvc:mapping path="/inter/test2"/><mvc:mapping path="/inter/test*"/> <!-- test开头 --><mvc:mapping path="/inter/**"/> <!-- /** 任意多级任意路径 --><mvc:exclude-mapping path="/inter/a/**"/>   <!--不拦截此路径--><bean class="com.mxd.interceptor.MyInter1"></bean>   <!--拦截器类--></mvc:interceptor>
</mvc:interceptors>

十、上传

1、SpringMVC的上传

1.1 导入依赖

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version><exclusions><exclusion><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId></exclusion></exclusions>
</dependency>

1.2 页面表单代码

<%--表单上面必须指定一个属性:enctype="multipart/form-data"必须有file类型的输入框:<input type="file">
--%>
<form action="/upload/img" method="post" enctype="multipart/form-data">上传图片:<input type="file" name="filename"><br/><input type="submit" value="上传">
</form>

1.3 在springmvc.xml中配置上传解析器

<!-- 上传解析器 id必须是:“multipartResolver”-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 最大可上传的文件大小(10485760等于10M)  单位:byte字节  超出后会抛出MaxUploadSizeExceededException异常,可以异常解析器捕获 --><property name="maxUploadSize" value="10485760"></property>
</bean>

1.4 Handler

@RequestMapping("/upload/img")
public String uploadImg(@RequestParam("filename") MultipartFile multipartFile, HttpSession session) throws IOException {//必须有这个SpringMVC提供的类(本质就是流对象):MultipartFile//1.获取文件名String filename = multipartFile.getOriginalFilename();System.out.println(filename);//2.下一次上传图片时,图片内容换了,为了防止覆盖情况,定制唯一的UUID命名String unique = UUID.randomUUID().toString();System.out.println(unique);//获得文件后缀String extension = FilenameUtils.getExtension(filename);//abc.txt   txt    //将生成的UUID和文件后缀拼接起来(全局唯一的文件名)String uniqueFileName = unique+"."+extension;System.out.println(uniqueFileName);//3.获取文件的类型String type = multipartFile.getContentType();System.out.println("type:"+type);//4.上传完成:需要将图片存入本地磁盘,放在当前web工程下的/upload_file目录下//在webapp目录下创建一个目录"upload_file",且此目录初始不要为空,否则编译时被忽略//如果不是在创建maven工程时同时创建的web工程,获得的目录是在项目的out目录中找String realPath = session.getServletContext().getRealPath("upload_file");System.out.println("realPath:"+realPath);//5.将上传的文件,存入磁盘路径中multipartFile.transferTo(new File(realPath+"\\"+uniqueFileName));return "upload_ok";}

2、七牛云上传

2.1 导入依赖

<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>[7.7.0, 7.7.99]</version>
</dependency>

这里的version指定了一个版本范围,每次更新pom.xml的时候会尝试去下载7.7.x版本中的最新版本,你可以手动指定一个固定的版本。上面的jar包如果不管用可以直接导入以下四个依赖

<dependencies><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.2</version><scope>compile</scope></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version><scope>compile</scope></dependency><dependency><groupId>com.qiniu</groupId><artifactId>happy-dns-java</artifactId><version>0.1.6</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>

2.2 页面表单代码

<form action="/qny/img" method="post" enctype="multipart/form-data">七牛云-上传图片:<input type="file" name="filename"><br/><input type="submit" value="上传">
</form>

2.3 编写工具类

public class UploadUtils {//通过七牛云 ----上传图片的外链 ,返回值Stringpublic static String upload(MultipartFile multipartFile){//参数为上传的流对象//构造一个带指定 Region 对象的配置类//配置区域(我是华南,参数就为华南)Configuration cfg = new Configuration(Region.huanan());//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传(点击个人中心→密钥管理)String accessKey = "-AminpvyFoa2rGjt3JgPivj6DI53n6cG1aFAdlHP";String secretKey = "DRyd_wN8O0ywa4f1OdXiH8OACTskA_kdfIm4CSRi";String bucket = "javaee-upload-test-01";//七牛云空间的名称//默认不指定key的情况下,以文件内容的hash值作为文件名String key = null;//底下两行代码暂时不用/*byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes);*///身份认证Auth auth = Auth.create(accessKey, secretKey);//生成upToken字符串,代表某个人的七牛云信息(内部利用哈希对信息进行了加密)String upToken = auth.uploadToken(bucket);try {//Response response = uploadManager.put(byteInputStream,key,upToken,null, null);//参数:(1)这里使用自己的流对象(2)key:默认为null(3)upToken字符串Response response = null;try {response = uploadManager.put(multipartFile.getInputStream(),key,upToken,null, null);} catch (IOException e) {e.printStackTrace();}//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);//putRet中包含身份认证的信息System.out.println(putRet.key);System.out.println(putRet.hash);//返回的是七牛云的图片外链,可以进行查看return "http://r5a60jn00.hn-bkt.clouddn.com/"+putRet.hash;} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}return null;}
}

2.4 Handler

@Controller
public class QNYController {@RequestMapping("/qny/img")public String uploadFile(@RequestParam("filename") MultipartFile multipartFile, Model model){//调用工具类String upload = UploadUtils.upload(multipartFile);System.out.println(upload);model.addAttribute("imgUrl", upload);return "upload_ok";}
}

十一、下载

1、 超链

<a href="/download?name=abc.jpg">点击下载</a>

2、 Handler

@Controller
public class DownloadController {@RequestMapping("/download")public void downloadFile(String name, HttpSession session, HttpServletResponse response) throws IOException {System.out.println("name:"+name);//获得要下载文件的绝对路径String path = session.getServletContext().getRealPath("/upload_file");System.out.println(path);//文件的完整路径String real_path = path+"\\"+name;//设置响应头  告知浏览器,要以附件的形式保存内容   filename=浏览器显示的下载文件名response.setHeader("content-disposition","attachment;filename="+name);//读取目标文件,写出给客户端IOUtils.copy(new FileInputStream(real_path), response.getOutputStream());//上一步,已经是响应了,所以此handler直接是void}
}

十二、验证码

1、导入依赖

<!-- Kaptcha -->
<dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version><exclusions><exclusion><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId></exclusion></exclusions>
</dependency>

2、在web.xml中声明验证码组件

 <!--验证码的配置-->
<servlet><servlet-name>cap</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class><init-param><param-name>kaptcha.border</param-name><param-value>no</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.length</param-name><param-value>5</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.string</param-name><param-value>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</param-value></init-param><init-param><param-name>kaptcha.background.clear.to</param-name><param-value>211,229,237</param-value></init-param><init-param><!-- session.setAttribute("captcha","验证码") 存储在HttpSession名字 captcha--><param-name>kaptcha.session.key</param-name><param-value>captcha</param-value></init-param>
</servlet>
<servlet-mapping><servlet-name>cap</servlet-name><url-pattern>/captcha</url-pattern>
</servlet-mapping>

3、html页面

<img id="cap" src="/captcha" style="width: 85px">
<script>$(function (){$("#cap").click(function (){//注:this和$ (this)是两个不同的对象:this作为DOM对象只能使用javascript方法,//而$ (this)则只能使用jquery方法//第一种刷新验证码的方式//this.src="/captcha?time="+new Date().getTime();//第二种刷新验证码的方式var path =$(this).attr("src")+"?"+new Date().getTime();$(this).attr("src",path);})})
</script>

十三、REST

1、 开发风格

是一种开发风格,遵从此风格开发软件,符合REST风格,则RESTFUL。

两个核心要求:

  • 每个资源都有唯一的标识(URL)
  • 不同的行为,使用对应的http-method
访问标识 资源
http://localhost:8989/xxx/users 所有用户
http://localhost:8989/xxx/users/1 用户1
http://localhost:8989/xxx/users/1/orders 用户1的所有订单
请求方式 标识 意图
GET http://localhost:8989/xxx/users 查询所有用户
POST http://localhost:8989/xxx/users 在所有用户中增加一个
PUT http://localhost:8989/xxx/users 在所有用户中修改一个
DELETE http://localhost:8989/xxx/users/1 删除用户1
GET http://localhost:8989/xxx/users/1 查询用户1
GET http://localhost:8989/xxx/users/1/orders 查询用户1的所有订单
POST http://localhost:8989/xxx/users/1/orders 在用户1的所有订单中增加一个

注:一般是get查询,post添加,delete删除,put修改

2、 优点

  • **输出json:

3、 使用

3.1 定义Rest风格的 Controller

@RequestMapping(value="/users",method = RequestMethod.GET)

等价

@GetMapping("/users")

@RestController
public class RestController {@GetMapping("/users")public List<User> queryAllUsers(){System.out.println("get");List<User> users = ....return users;}@PostMapping("/users")public String addUser(@RequestBody User user){System.out.println("Post user :"+user);return "{status:1}";}@PutMapping("/users")public String updateUser(@RequestBody User user){System.out.println("Put user" user:"+user);return "{status:1}";}@GetMapping("/users/{id}")public String queryOneUser(@PathVariable Integer id){//@PathVariable 接收路径中的值System.out.println("Get user id:"+id);return "{status:1}";}@DeleteMapping("/users/{id}")public String deleteOneUser(@PathVariable Integer id){//@PathVariable 接收路径中的值System.out.println("delete user id:"+id);return "{status:1}";}
}

3.2 Ajax请求

<script>    function putUser(){ // 发送更新请求 (增加请求发送方式也是如此)var xhr = new XMLHttpRequest();//定义 put,delete,get,post方式 即可,不用定义_methodxhr.open("put","${pageContext.request.contextPath}/rest04/users");// 设置请求头xhr.setRequestHeader("content-type","application/json");// 设置请求参数var user = {id:1,NAME:"shine",city:"bj","birth":"2020/12/12","salary":100.5};xhr.send(JSON.stringify(user));xhr.onreadystatechange=function(){if(xhr.readyState==4 && xhr.status==200){var ret = xhr.responseText;// 解析json,并输出console.log(JSON.parse(ret));}}/*$.ajax({url:'${pageContext.request.contextPath}/rest04/users',type:'put',contentType:"application/json",//声明请求参数类型为 jsondata:JSON.stringify(user),// 转换js对象成jsonsuccess:function(ret){console.log(JSON.parse(ret));}});*/}function delUser(){  // 发送删除请求var xhr = new XMLHttpRequest();//定义 put,delete,get,post方式 即可,不用定义_methodxhr.open("delete","${pageContext.request.contextPath}/rest04/users/1");xhr.send();xhr.onreadystatechange=function(){if(xhr.readyState==4 && xhr.status==200){var ret = xhr.responseText;console.log(JSON.parse(ret));}}}
</script>

十四、跨域请求

1、 域

域:协议+IP+端口

  • http://localhost:8989
  • http://localhost:8080
  • http://www.baidu.com:80

2、 Ajax跨域问题

  • Ajax发送请求时,不允许跨域,以防用户信息泄露。
  • 当Ajax跨域请求时,响应会被浏览器拦截(同源策略),并报错。即浏览器默认不允许ajax跨域得到响应内容。
  • 互相信任的域之间如果需要ajax访问,(比如前后端分离项目中,前端项目和后端项目之间),则需要额外的设置才可正常请求。

3、 解决方案

  • 允许其他域访问
  • 在被访问方的Controller类上,添加注解
@CrossOrigin("http://localhost:8080") //允许此域发请求访问
public class SysUserController {....
}
  • 携带对方cookie,使得session可用
  • 在访问方,ajax中添加属性:withCredentials: true
$.ajax({type: "POST",url: "http://localhost:8989/web/sys/login",...,xhrFields: {// 跨域携带cookiewithCredentials: true}
});
或
var xhr = new XMLHttpRequest();
// 跨域携带cookie
xhr.withCredentials=true;

十五、SpringMVC的执行流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXUtXLmb-1641542709370)(Pictures/springMVC执行流程.jpg)]

十六、SSM整合(Spring+Spring MVC+Mybatis)

1、 整合思路

此时项目中有两个工厂

  • DispatcherServlet 启动的springMVC工厂==负责生产C及springMVC自己的系统组件
  • ContextLoaderListener 启动的spring工厂==负责生产其他所有组件
  • springMVC的工厂会被设置为spring工厂的子工厂,可以随意获取spring工厂中的组件
  • 整合过程,就是累加:代码+依赖+配置。然后将service注入给controller即可

2、整合技巧

两个工厂不能有彼此侵入,即,生产的组件不能有重合。

<!-- 告知SpringMVC  哪些包中 存在 被注解的类use-default-filters=true 凡是被 @Controller @Service  @Repository注解的类,都会被扫描use-default-filters=false 默认不扫描包内的任何类, 只扫描include-filter中指定的类只扫描被@Controller注解的类
-->
<context:component-scan base-package="com.zhj" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 告知Spring唯独不扫描@Controller注解的类 -->
<context:component-scan base-package="com.zhj" use-default-filters="true"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

3、整合的步骤:

3.1 添加依赖

<!--依赖:junit,mybatis,mysql驱动,连接池,mybatis-spring,spring-jdbc,spring-webmvc-->
<!--lombok,jackson-databind(处理json数据)等等-->

3.2 整合Spring和Mybatis

Spring的核心配置文件:spring-context.xml

<!-- 告知spring,哪些包中 有被注解的类、方法、属性 -->
<!-- <context:component-scan base-package="com.qf.a,com.xx.b"></context:component-scan> -->
<context:component-scan base-package="com.mxd"></context:component-scan><!--1、 加载properties文件中数据库参数信息2、创建数据源对象(有好几种:①spring-jdbc中的数据源 ②mybatis中的数据源 ③druid中的数据源)3、创建SqlSessionFactory对象 SqlSessionFactoryBean对象4、配置mapper的扫描器对象--><!--1.加载properties文件中数据库参数信息(输入<property...就会有提示了)-->
<context:property-placeholder location="classpath:jdbc.properties"/><!--2.创建数据源对象(有好几种)-->
<bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}" />
</bean><!--3.创建SqlSessionFactory对象 SqlSessionFactoryBean对象-->
<bean id="sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean"><!--        配置注入的数据源--><property name="dataSource" ref="dataSource" /><!--        配置mybatis映射文件的路径,如果用注解了这个就要注释--><property name="mapperLocations" value="classpath:com/mxd/mapper/*Mapper.xml" /><!--        配置实体的别名包扫描--><property name="typeAliasesPackage" value="com.mxd.pojo" /><!--提供分页插件,如果配置了这个插件,就必须要进行分页查询,不然会抛异常--><!--<property name="plugins"><array><bean class="com.github.pagehelper.PageInterceptor"></bean></array></property>-->
</bean><!--4.spring与mybatis整合:配置mapper的扫描器对象      管理DAO实现类的创建,并创建DAO对象,存入工厂管理com.mxd.mapper/dao实现对象在工厂中的id是:“首字母小写的-接口的类名”mybatis提供的这个和spring整合的依赖中MapperScannerConfigurer,Mapper的配置扫描器必须配置这个类他的id必须mapperScannerConfigurer,否则报错-->
<bean id="mapperScannerConfigurer"class="org.mybatis.spring.mapper.MapperScannerConfigurer" ><!--        必须配置扫描器数据源对象--><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /><!--        配置接口扫描器扫描的默认包路径,然后交给spring  --><property name="basePackage" value="com.mxd.mapper"/>
</bean>

3.3 SpringMVC的xml配置

<!--1.自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.mxd.controller"/>
<!--2.让Spring MVC不处理静态资源(.css  .js等等) -->
<mvc:default-servlet-handler /><!--3.注册mvc注解驱动在spring中一般采用@RequestMapping注解来完成映射关系要想使@RequestMapping注解生效,必须向上下文中注册DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例。这两个实例分别在类级别和方法级别处理。而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven /><!--4.视图解析器 -->
<bean id="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--前缀  注意后面的斜杠必须加,不然会找不到--><property name="prefix" value="/WEB-INF/jsp/"/><!--后缀--><property name="suffix" value=".jsp"/>
</bean><!--...拦截器,上传解析器等等--><!--导入spring和mybatis整合的xml文件-->
<import resource="spring-context.xml"/>

只需要导入其他的xml配置就整合完成

3.4 web.xml配置

注:web.xml中的配置,可以查看网上的web.xml配置的详解

<!--制定spring的配置文件-->
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value>
</context-param><!--过滤器-->
<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>
</filter>
<filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping><!--监听器-->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value></param-value></init-param><load-on-startup>1</load-on-startup>
</servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

SpringMVC和SSM整合步骤(最详细)相关推荐

  1. SSM整合,非常详细的SSM整合

    对于ssm框架网上有很多,这里只是自己为大家提供的一个ssm整合框架参考分享,这个前提是基于maven的管理工具写的, 如果觉得写得不好,博主这边已经把代码上传了: 不妨可以参考代码再理解学习:htt ...

  2. 整理动力节点王鹤老师ssm整合步骤

    1.SSM整合开发步骤 总体来说就是 SPringMVC接收用户请求-----Spring中的Service对象-----Mybatis处理数据 ssm整合也叫做ssi,整合中有容器 1.第一容器Sp ...

  3. SpringMVC以及SSM整合

    本人才疏学浅,如有错误欢迎批评!转载请注明出处:https://www.cnblogs.com/lee-yangyaozi/p/11226145.html SpringMVC概述 Spring Web ...

  4. 框架-springmvc(ssm整合)

    第一天 课程安排: 1.什么是springMVC? 2.springMVC框架原理前端控制器.处理器映射器.处理器适配器.视图解析器. 3.springMVC入门程序目的:对前端控制器.处理器映射器. ...

  5. 【SSM整合】SSM整合学习-2022详细学习笔记

    SSM整合 这是我学习尚硅谷2022版ssm框架做的笔记 欢迎访问我的个人博客 相关文章

  6. 三大框架整合步骤(详细)

    以是从struts2-------->>>hibernate--------------->>>>spring的整合过程. 环境:tomcat7+MyEcli ...

  7. Spring+SpringMVC+Mybatis SSM框架详解

    一.JDBC编程 1.JDBC 简介 JDBC其实就是 Java 官方提供的一套规范(接口),用于帮助开发人员快速实现不同关系型数据库的连接. 程序运行的时候,数据都是在内存中的.当程序终止的时候,通 ...

  8. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)

    SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一) 1. 前言 最近在写毕设过程中,重新梳理了一遍SSM框架,特此记录一下. 附上源码:https://gitee ...

  9. 超级详细!!!Spring、SpringMVC、Mybatis知识点完整版更新!IOD、DI依赖注入、Mybatis配置、SQL、MVC拦截器、Web开发、SSM整合案例。

    Spring Spring框架知识点完整版 上篇,SSM三部曲之一 知识点涵盖:Spring简介IOC控制反转DI依赖注入LombokSPEL配置文件低频知识点注解开发Spring常用注解 链接:ht ...

最新文章

  1. vue中一个组件导入另一个组件
  2. suse 新增用户oracle,在SUSE Linux中让其他用户能运行Oracle命令
  3. react入门--------安装react
  4. SFTP多用户权限 linux环境 一站式解决方案
  5. Oracle11gR2下搭建DataGuard主备同步详解
  6. tomcat报错“The specified JRE installation does not exist”
  7. oracle 中表变量的用法,oracle 表类型变量的使用
  8. sql表格模型获取记录内容_SQL Server和BI –如何使用Reporting Services 2016记录表格模型
  9. pselect 和 select
  10. java 错误日期转正确日期_java – jdk8日期转换中的错误?
  11. failed creating java jvm.dll
  12. 网络和http协议理论
  13. 将两个ISO文件挂载至同一个虚拟光驱
  14. 如何将判决书上的文字提取出来
  15. 计算机低级格式化,低级格式化,教您硬盘怎么低级格式化
  16. 教授专栏25 | 李家涛:从中国元素到全球管理理论—中国管理研究三十年[Part Ⅰ]...
  17. 研发的首要目的是什么——一个容易被忽略的问题
  18. 最新数据挖掘赛事方案梳理!
  19. VR数字沙盘高度还原未来房屋实
  20. 2021年起重机司机(限桥式起重机)报名考试及起重机司机(限桥式起重机)模拟试题

热门文章

  1. FckEditor中文配置手册详细说明
  2. 监控概述 、 Zabbix基础 、 Zabbix监控服案例
  3. asp.net酒店餐饮管理系统
  4. 计算机组成原理( 程序员必学简化版 )
  5. QT串口动态实时显示大量数据波形曲线(一)========“串口设置与ui界面添加(灯与按钮)”
  6. 2022 音视频技术风向标
  7. MySQL索引的前世今生
  8. C语言课设电子英汉词典系统(大作业)
  9. 大航海时代2皮耶德攻略(SFC日版)
  10. 留学生快速斩获IT名企实习offer的5大攻略