1、MVC常用

web.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <!--1.注册DispatcherServlet-->
  7. <servlet>
  8. <servlet-name>springmvc</servlet-name>
  9. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  10. <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
  11. <init-param>
  12. <param-name>contextConfigLocation</param-name>
  13. <param-value>classpath:springmvc-servlet.xml</param-value>
  14. </init-param>
  15. <!--启动级别-1-->
  16. <load-on-startup>1</load-on-startup>
  17. </servlet>
  18. <!--/ 匹配所有的请求;(不包括.jsp)-->
  19. <!--/* 匹配所有的请求;(包括.jsp)-->
  20. <servlet-mapping>
  21. <servlet-name>springmvc</servlet-name>
  22. <url-pattern>/</url-pattern>
  23. </servlet-mapping>
  24. <filter>
  25. <filter-name>encoding</filter-name>
  26. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  27. <init-param>
  28. <param-name>encoding</param-name>
  29. <param-value>utf-8</param-value>
  30. </init-param>
  31. </filter>
  32. <!--解决乱码-->
  33. <filter-mapping>
  34. <filter-name>encoding</filter-name>
  35. <url-pattern>/*</url-pattern>
  36. </filter-mapping>
  37. </web-app>

/ 和 / 的区别:< url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对我们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。< url-pattern > / </ url-pattern > 会匹配 *.jsp,会出现返回 jsp视图时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错

springmvc-servlet.xml:

在resources中配置,SpringMVC的核心配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mv="http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. https://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/mvc
  11. https://www.springframework.org/schema/mvc/spring-mvc.xsd">
  12. <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
  13. <context:component-scan base-package="com.qing.controller"/>
  14. <!-- 让Spring MVC不处理静态资源 .css .js .html等-->
  15. <mvc:default-servlet-handler/>
  16. <!-- 视图解析器 -->
  17. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  18. id="internalResourceViewResolver">
  19. <!-- 前缀 -->
  20. <property name="prefix" value="/WEB-INF/jsp/"/>
  21. <!-- 后缀 -->
  22. <property name="suffix" value=".jsp"/>
  23. </bean>
  24. <!--Json乱码问题-->
  25. <mvc:annotation-driven>
  26. <mvc:message-converters register-defaults="true">
  27. <bean class="org.springframework.http.converter.StringHttpMessageConverter">
  28. <constructor-arg value="UTF-8"/>
  29. </bean>
  30. <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  31. <property name="objectMapper">
  32. <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
  33. <property name="failOnEmptyBeans" value="false"/>
  34. </bean>
  35. </property>
  36. </bean>
  37. </mvc:message-converters>
  38. </mvc:annotation-driven>
  39. <!-- 拦截器配置-->
  40. <mv:interceptors>
  41. <mvc:interceptor>
  42. <mvc:mapping path="/**"/>
  43. <bean class="com.qing.interceptor.MtInterceptor"/>
  44. </mvc:interceptor>
  45. </mv:interceptors>
  46. </beans>

第23行的路径一定要对应WEB-INF下的jsp

常用的jar包

  1. <dependency>
  2. <groupId>junit</groupId>
  3. <artifactId>junit</artifactId>
  4. <version>4.12</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>javax.servlet</groupId>
  8. <artifactId>servlet-api</artifactId>
  9. <version>2.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>javax.servlet.jsp</groupId>
  13. <artifactId>jsp-api</artifactId>
  14. <version>2.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>jstl</groupId>
  18. <artifactId>jstl</artifactId>
  19. <version>1.2</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework</groupId>
  23. <artifactId>spring-webmvc</artifactId>
  24. <version>5.3.6</version>
  25. </dependency>

2、回顾servlet

1.1 创建web项目

1.2 导包

  1. <dependency>
  2. <groupId>javax.servlet</groupId>
  3. <artifactId>servlet-api</artifactId>
  4. <version>2.5</version>
  5. <scope>provided</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>javax.servlet.jsp</groupId>
  9. <artifactId>jsp-api</artifactId>
  10. <version>2.0</version>
  11. <scope>provided</scope>
  12. </dependency>

1.3 配置servlet

  1. public class HelloServlet extends HttpServlet {
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. //1 获取前端参数
  5. String method=req.getParameter("method");
  6. if(method.equals("add")){
  7. req.getSession().setAttribute("msg","执行了add方法");
  8. }
  9. if (method.equals("delete")){
  10. req.getSession().setAttribute("msg","执行了delete方法");
  11. }
  12. //2 调用业务层
  13. //3 视图转发或重定向
  14. req.getRequestDispatcher("/jsp/test.jsp").forward(req,resp);
  15. }
  16. @Override
  17. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  18. doGet(req, resp);
  19. }
  20. }

1.4 配置web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <servlet>
  7. <servlet-name>hello</servlet-name>
  8. <servlet-class>com.qing.servlet.HelloServlet</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>hello</servlet-name>
  12. <url-pattern>/hello</url-pattern>
  13. </servlet-mapping>
  14. <welcome-file-list>
  15. <welcome-file>form.jsp</welcome-file>
  16. </welcome-file-list>
  17. </web-app>

3、第一个SpringMVC程序

  • 创建项目,添加web框架支持

  • 编写web.xml配置文件

  • 编写springmvc-servlet.xml配置文件 ```xml <?xml version=”1.0” encoding=”UTF-8”?>

  1. <!--Handler-->
  2. <bean id="/hello" class="com.qing.controller.HelloController"/>

  1. -
  2. 编写一个hello.jsp页面
  3. -
  4. 编写HelloController控制
  5. ```java
  6. import org.springframework.web.servlet.ModelAndView;
  7. import org.springframework.web.servlet.mvc.Controller;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. //注意:这里我们先导入Controller接口
  11. public class HelloController implements Controller {
  12. public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
  13. //ModelAndView 模型和视图
  14. ModelAndView mv = new ModelAndView();
  15. //业务代码
  16. String result = "HelloSpringMVC";
  17. //封装对象,放在ModelAndView中 ,Model
  18. mv.addObject("msg", result);
  19. //封装要跳转的视图,放在ModelAndView中
  20. mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
  21. return mv;
  22. }
  23. }


出现问题:
如果出现了404页面错误,在代码逻辑没有出错的情况下,检查Artifacts下有没有lib依赖,若没有,则需添加

4、使用注解开发

  • 创建项目,添加web框架支持

  • 编写web.xml配置文件

  • 编写springmvc-servlet.xml配置文件 ```xml <?xml version=”1.0” encoding=”UTF-8”?>

  1. <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
  2. <context:component-scan base-package="com.qing.controller"/>
  3. <!-- 让Spring MVC不处理静态资源 .css .js .html等-->
  4. <mvc:default-servlet-handler />
  5. <!--
  6. 支持mvc注解驱动
  7. 在spring中一般采用@RequestMapping注解来完成映射关系
  8. 要想使@RequestMapping注解生效
  9. 必须向上下文中注册DefaultAnnotationHandlerMapping
  10. 和一个AnnotationMethodHandlerAdapter实例
  11. 这两个实例分别在类级别和方法级别处理。
  12. 而annotation-driven配置帮助我们自动完成上述两个实例的注入。
  13. -->
  14. <mvc:annotation-driven />
  15. <!-- 视图解析器 -->
  16. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
  17. id="internalResourceViewResolver">
  18. <!-- 前缀 -->
  19. <property name="prefix" value="/WEB-INF/jsp/" />
  20. <!-- 后缀 -->
  21. <property name="suffix" value=".jsp" />
  22. </bean>

  1. -
  2. 编写一个hello.jsp页面
  3. -
  4. 编写HelloController控制
  5. ```java
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.ui.Model;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. //在类上添加@controller注解后,这个类才会被视图解析器解析
  10. @Controller
  11. public class HelloController {
  12. @RequestMapping("/hello") //网页请求http://localhost:8080/SpringMVC_03_annotation_war_exploded/hello时
  13. public String hello(Model model){
  14. //封装数据
  15. model.addAttribute("msg","Hello,SpringMVC!");
  16. return "hello"; //会被视图解析器处理 经过封装后显示对应的/WEB-INF/jsp/hello.jsp页面
  17. }
  18. }

5、RestFul风格

  1. import org.springframework.stereotype.Controller;
  2. import org.springframework.ui.Model;
  3. import org.springframework.web.bind.annotation.*;
  4. @Controller
  5. public class RestFulController {
  6. //原来的路径请求为:http://localhost:8080/SpringMVC_03/add?a=1&b=2
  7. //使用restful风格的路径请求为:http://localhost:8080/SpringMVC_03/add/1/2 (常用)
  8. //可以自定义请求方式 get、post等
  9. // @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
  10. @RequestMapping("/add/{a}/{b}")
  11. // @GetMapping("/add/{a}/{b}")
  12. // @PostMapping("/add/{a}/{b}")
  13. public String add(@PathVariable int a, @PathVariable int b, Model model) {
  14. //@PathVariable 代表参数为路径参数
  15. int res = a + b;
  16. model.addAttribute("msg", "结果为" + res);
  17. return "add";
  18. }
  19. }

RestFul风格使用安全,他人分辨不出参数的意义;而使用原始传参,add?a=1&b=2就可以清楚的分辨

6、重定向与转发

区别:

转发是服务器行为,只需一次跳转,用户看不到url地址上的变化重定向是游览器端的行为,需要进行二次跳转,用户能看到url地址上的变化
转发的速度比重定向的速度相对要高,因为转发只需要做一次请求,而重定向需要做二次请求。
转发能够获取request作用域中的数据,他只发出了一次请求,而重定向无法获取request中的数据 ,因为他发出了二次请求,每一次请求对应着一次新的request
转发只能访问当前服务器中的数据,而重定向可以访问任意服务器中的数据
转发不能解决数据的重复提交问题(就是能按F5进行刷新操作),而重定向能解决数据的重复提交。

语句:

  • 原生转发:request.getRequestDispatcher(“路径”).forward(request, response);
  • 原生重定向:response.sendRedirect(“路径”);
  • SpringMvc转发:forward:/路径
  • SpringMvc重定向:redirect:/路径

测试:

  1. @Controller
  2. public class ViewModel {
  3. @RequestMapping("/v")
  4. public String view1(Model model){
  5. model.addAttribute("msg", "ViewModel");
  6. // return "forward:/index.jsp"; //转发
  7. return "redirect:/toIndex"; //重定向 走对应的toIndex请求,再从toIndex请求中二次跳转到index.jsp页面
  8. }
  9. @RequestMapping("/toIndex")
  10. public String view2(Model model){
  11. model.addAttribute("msg", "ViewModel");
  12. return "index"; //二次跳转至index.jsp页面
  13. }
  14. }

7、前端接收数据以及回显

  1. @Controller
  2. @RequestMapping("/user")
  3. public class UserController {
  4. //http://localhost:8080/SpringMVC_03/user/u1?&username=qing
  5. @RequestMapping("u1")
  6. public String test1(@RequestParam("username") String name, Model model) {
  7. //@RequestParam代表了前端传参的参数名,固定的
  8. //接收前端参数
  9. System.out.println("前端参数为:" + name);
  10. //将结果返回前端
  11. model.addAttribute("msg",name);
  12. //视图跳转
  13. return "hello";
  14. }
  15. //前端接收的是一个对象时:id name age
  16. //http://localhost:8080/SpringMVC_03/user/u2?id=1&name=qing&age=18
  17. @RequestMapping("u2")
  18. public String test2(User user,Model model){
  19. System.out.println(user.toString());
  20. model.addAttribute("msg",user);
  21. return "hello";
  22. }
  23. }

8、解决乱码

方法一:自定义过滤器

编写EncodingFilter类:

  1. import javax.servlet.*;
  2. import java.io.IOException;
  3. public class EncodingFilter implements Filter {
  4. @Override
  5. public void init(FilterConfig filterConfig) throws ServletException {
  6. }
  7. @Override
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  9. request.setCharacterEncoding("utf-8");
  10. response.setCharacterEncoding("utf-8");
  11. chain.doFilter(request,response);
  12. }
  13. @Override
  14. public void destroy() {
  15. }
  16. }

配置web.xml:

  1. <filter>
  2. <filter-name>encoding</filter-name>
  3. <filter-class>com.qing.filter.EncodingFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>encoding</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

**注:这里第8行必须使用 / 才能使过滤器生效,过滤到所有的jsp页面

方式二:spring自带过滤器(建议使用)

配置web.xml:

  1. <filter>
  2. <filter-name>encoding</filter-name>
  3. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  4. <init-param>
  5. <param-name>encoding</param-name>
  6. <param-value>utf-8</param-value>
  7. </init-param>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>encoding</filter-name>
  11. <url-pattern>/*</url-pattern>
  12. </filter-mapping>

方式三:万能的过滤器(大佬编写)

自定义类:

  1. /**
  2. * 解决get和post请求 全部乱码的过滤器
  3. */
  4. public class GenericEncodingFilter implements Filter {
  5. @Override
  6. public void destroy() {
  7. }
  8. @Override
  9. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  10. //处理response的字符编码
  11. HttpServletResponse myResponse=(HttpServletResponse) response;
  12. myResponse.setContentType("text/html;charset=UTF-8");
  13. // 转型为与协议相关对象
  14. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  15. // 对request包装增强
  16. HttpServletRequest myrequest = new MyRequest(httpServletRequest);
  17. chain.doFilter(myrequest, response);
  18. }
  19. @Override
  20. public void init(FilterConfig filterConfig) throws ServletException {
  21. }
  22. }
  23. //自定义request对象,HttpServletRequest的包装类
  24. class MyRequest extends HttpServletRequestWrapper {
  25. private HttpServletRequest request;
  26. //是否编码的标记
  27. private boolean hasEncode;
  28. //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
  29. public MyRequest(HttpServletRequest request) {
  30. super(request);// super必须写
  31. this.request = request;
  32. }
  33. // 对需要增强方法 进行覆盖
  34. @Override
  35. public Map getParameterMap() {
  36. // 先获得请求方式
  37. String method = request.getMethod();
  38. if (method.equalsIgnoreCase("post")) {
  39. // post请求
  40. try {
  41. // 处理post乱码
  42. request.setCharacterEncoding("utf-8");
  43. return request.getParameterMap();
  44. } catch (UnsupportedEncodingException e) {
  45. e.printStackTrace();
  46. }
  47. } else if (method.equalsIgnoreCase("get")) {
  48. // get请求
  49. Map<String, String[]> parameterMap = request.getParameterMap();
  50. if (!hasEncode) { // 确保get手动编码逻辑只运行一次
  51. for (String parameterName : parameterMap.keySet()) {
  52. String[] values = parameterMap.get(parameterName);
  53. if (values != null) {
  54. for (int i = 0; i < values.length; i++) {
  55. try {
  56. // 处理get乱码
  57. values[i] = new String(values[i]
  58. .getBytes("ISO-8859-1"), "utf-8");
  59. } catch (UnsupportedEncodingException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }
  64. }
  65. hasEncode = true;
  66. }
  67. return parameterMap;
  68. }
  69. return super.getParameterMap();
  70. }
  71. //取一个值
  72. @Override
  73. public String getParameter(String name) {
  74. Map<String, String[]> parameterMap = getParameterMap();
  75. String[] values = parameterMap.get(name);
  76. if (values == null) {
  77. return null;
  78. }
  79. return values[0]; // 取回参数的第一个值
  80. }
  81. //取所有值
  82. @Override
  83. public String[] getParameterValues(String name) {
  84. Map<String, String[]> parameterMap = getParameterMap();
  85. String[] values = parameterMap.get(name);
  86. return values;
  87. }
  88. }

配置web.xml:

  1. <filter>
  2. <filter-name>encoding</filter-name>
  3. <filter-class>com.qing.filter.GenericEncodingFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>encoding</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

9、Jackson(推荐)

导包:

  1. <dependency>
  2. <groupId>com.fasterxml.jackson.core</groupId>
  3. <artifactId>jackson-databind</artifactId>
  4. <version>2.12.3</version>
  5. </dependency>

9.1 格式转换

  1. <script type="text/javascript">
  2. //编写一个JavaScript对象
  3. var user={
  4. name:"卿帆",
  5. age:20,
  6. sex:"男"
  7. }
  8. //控制台输出
  9. console.log(user);
  10. //将js对象、数组转换为字符串
  11. var obj=JSON.stringify(user);
  12. console.log(obj);
  13. //将字符串转换为json对象
  14. var json=JSON.parse(obj);
  15. console.log(json)
  16. </script>

9.2 后端传送数据给前端

测试单个对象:

  1. // @RestController
  2. @Controller
  3. public class UserController {
  4. @RequestMapping("/j1")
  5. @ResponseBody //添加此注解后不会走视图解析器,直接返回一个字符串 配合@controller使用;也可以使用@RestController直接返回字符串
  6. public String json1() throws JsonProcessingException {
  7. ObjectMapper mapper=new ObjectMapper();
  8. User user=new User("qingfan",20,"男");
  9. String string = mapper.writeValueAsString(user); //生成json字符串
  10. return string;
  11. }
  12. }

测试集合:

  1. @RequestMapping("/j2")
  2. @ResponseBody //添加此注解后不会走视图解析器,直接返回一个字符串
  3. public String json2() throws JsonProcessingException {
  4. ObjectMapper mapper = new ObjectMapper();
  5. User user1 = new User("卿", 20, "男");
  6. User user2 = new User("陈", 20, "女");
  7. User user3 = new User("帆", 20, "男");
  8. User user4 = new User("莹", 20, "女");
  9. List<User> users = new ArrayList<>();
  10. users.add(user1);
  11. users.add(user2);
  12. users.add(user3);
  13. users.add(user4);
  14. String string = mapper.writeValueAsString(users); //生成json字符串
  15. return string;
  16. }

测试时间:

  1. @RequestMapping("/j3")
  2. @ResponseBody //添加此注解后不会走视图解析器,直接返回一个字符串
  3. public String json3() throws JsonProcessingException {
  4. ObjectMapper mapper = new ObjectMapper();
  5. /*
  6. //默认使用时间戳
  7. //自定义时间格式
  8. SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  9. Date data = new Date();
  10. String string = mapper.writeValueAsString(sf.format(date););
  11. return string;
  12. */
  13. //不使用时间戳的方式格式化时间
  14. mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  15. //自定义时间格式
  16. SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  17. mapper.setDateFormat(sf);
  18. Date data = new Date();
  19. String string = mapper.writeValueAsString(data);
  20. return string;
  21. }

9.3 前端出现乱码

解决方式一:

  1. @RequestMapping("/j1")更改为:
  2. @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")

方式二:在spring配置文件中配置

  1. <!--Json乱码问题-->
  2. <mvc:annotation-driven>
  3. <mvc:message-converters register-defaults="true">
  4. <bean class="org.springframework.http.converter.StringHttpMessageConverter">
  5. <constructor-arg value="UTF-8"/>
  6. </bean>
  7. <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  8. <property name="objectMapper">
  9. <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
  10. <property name="failOnEmptyBeans" value="false"/>
  11. </bean>
  12. </property>
  13. </bean>
  14. </mvc:message-converters>
  15. </mvc:annotation-driven>

9.4 抽象JsonUtils工具类

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import com.fasterxml.jackson.databind.SerializationFeature;
  4. import java.text.SimpleDateFormat;
  5. public class JsonUtils {
  6. public static String getJson(Object object) {
  7. return getJson(object, "yyyy-MM-dd HH:mm:ss");
  8. }
  9. public static String getJson(Object object, String dateFormat) {
  10. ObjectMapper mapper = new ObjectMapper();
  11. //不使用时间戳的方式格式化时间
  12. mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  13. //自定义时间格式
  14. SimpleDateFormat sf = new SimpleDateFormat(dateFormat);
  15. mapper.setDateFormat(sf);
  16. try {
  17. return mapper.writeValueAsString(object);
  18. } catch (JsonProcessingException e) {
  19. e.printStackTrace();
  20. }
  21. return null;
  22. }
  23. }

10、Fastjson

导包:

  1. <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>fastjson</artifactId>
  5. <version>1.2.76</version>
  6. </dependency>

测试:

  1. @RequestMapping("/j3")
  2. @ResponseBody
  3. public String json3() {
  4. User user1 = new User("卿", 20, "男");
  5. User user2 = new User("陈", 20, "女");
  6. User user3 = new User("帆", 20, "男");
  7. User user4 = new User("莹宝", 20, "女");
  8. List<User> users = new ArrayList<>();
  9. users.add(user1);
  10. users.add(user2);
  11. users.add(user3);
  12. users.add(user4);
  13. return JSON.toJSONString(users);
  14. }

11、拦截器

自定义拦截器类:

  1. import javax.servlet.http.HttpServletRequest;
  2. import javax.servlet.http.HttpServletResponse;
  3. public class MtInterceptor implements HandlerInterceptor {
  4. @Override
  5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  6. HttpSession session = request.getSession();
  7. //判断登录情况
  8. if(request.getRequestURI().contains("login")){
  9. return true;
  10. }
  11. if(session.getAttribute("userLoginInfo")!=null){
  12. return true;
  13. }
  14. //没有登录时 跳转到登录页面
  15. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
  16. return false;
  17. }
  18. //下面2个方法可以省略
  19. @Override
  20. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  21. System.out.println("=======处理后=======");
  22. }
  23. @Override
  24. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  25. System.out.println("=======清理=======");
  26. }
  27. }

配置Spring配置文件

  1. <!-- 拦截器配置-->
  2. <mv:interceptors>
  3. <mvc:interceptor>
  4. <!-- /** 是拦截根目录下的所有请求-->
  5. <mvc:mapping path="/**"/>
  6. <bean class="com.qing.interceptor.MtInterceptor"/>
  7. </mvc:interceptor>
  8. </mv:interceptors>

12、文件上传和下载

12.1 上传

导包:

  1. <!--文件上传需要导入的jar包-->
  2. <dependency>
  3. <groupId>commons-fileupload</groupId>
  4. <artifactId>commons-fileupload</artifactId>
  5. <version>1.4</version>
  6. </dependency>
  7. <!--servlet必须使用高版本的javax.servlet-api-->
  8. <dependency>
  9. <groupId>javax.servlet</groupId>
  10. <artifactId>javax.servlet-api</artifactId>
  11. <version>4.0.1</version>
  12. </dependency>
  13. </dependencies>

编写Spring配置文件:

  1. <!--文件上传配置-->
  2. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  3. <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
  4. <property name="defaultEncoding" value="utf-8"/>
  5. <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
  6. <property name="maxUploadSize" value="10485760"/>
  7. <property name="maxInMemorySize" value="40960"/>
  8. </bean>

编写FileController:

  1. @RestController
  2. public class FileController {
  3. //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
  4. //批量上传CommonsMultipartFile则为数组即可
  5. @RequestMapping("/upload")
  6. public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
  7. //获取文件名 : file.getOriginalFilename();
  8. String uploadFileName = file.getOriginalFilename();
  9. //如果文件名为空,直接回到首页!
  10. if ("".equals(uploadFileName)) {
  11. return "redirect:/index.jsp";
  12. }
  13. System.out.println("上传文件名 : " + uploadFileName);
  14. //上传路径保存设置
  15. String path = request.getServletContext().getRealPath("/upload");
  16. //如果路径不存在,创建一个
  17. File realPath = new File(path);
  18. if (!realPath.exists()) {
  19. realPath.mkdir();
  20. }
  21. System.out.println("上传文件保存地址:" + realPath);
  22. InputStream is = file.getInputStream(); //文件输入流
  23. OutputStream os = new FileOutputStream(new File(realPath, uploadFileName)); //文件输出流
  24. //读取写出
  25. int len = 0;
  26. byte[] buffer = new byte[1024];
  27. while ((len = is.read(buffer)) != -1) {
  28. os.write(buffer, 0, len);
  29. os.flush();
  30. }
  31. os.close();
  32. is.close();
  33. return "redirect:/index.jsp";
  34. }
  35. /*
  36. * 方式二 采用file.Transto 来保存上传的文件
  37. */
  38. @RequestMapping("/upload2")
  39. public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
  40. //上传路径保存设置
  41. String path = request.getServletContext().getRealPath("/upload");
  42. File realPath = new File(path);
  43. if (!realPath.exists()){
  44. realPath.mkdir();
  45. }
  46. //上传文件地址
  47. System.out.println("上传文件保存地址:"+realPath);
  48. //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
  49. file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
  50. return "redirect:/index.jsp";
  51. }
  52. }

12.2 下载

  1. @RequestMapping("/download")
  2. @ResponseBody
  3. public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
  4. System.out.println("downloads():");
  5. //要下载的图片地址
  6. String path = request.getServletContext().getRealPath("/upload");
  7. String fileName = "1.jpg";
  8. //1、设置response 响应头
  9. response.reset(); //设置页面不缓存,清空buffer
  10. response.setCharacterEncoding("UTF-8"); //字符编码
  11. response.setContentType("multipart/form-data"); //二进制传输数据
  12. //设置响应头
  13. response.setHeader("Content-Disposition",
  14. "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
  15. File file = new File(path,fileName);
  16. //2、 读取文件--输入流
  17. InputStream input=new FileInputStream(file);
  18. //3、 写出文件--输出流
  19. OutputStream out = response.getOutputStream();
  20. byte[] buff =new byte[1024];
  21. int index=0;
  22. //4、执行 写出操作
  23. while((index= input.read(buff))!= -1){
  24. out.write(buff, 0, index);
  25. out.flush();
  26. }
  27. out.close();
  28. input.close();
  29. return "ok";
  30. }

13、SpringMvc扩展(面试)

13.1 MVC工作流程

流程详解:

  • 用户发送出请求到前端控制器DispatcherServlet。
  • DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
  • HandlerMapping找到具体的Handler(可查找xml配置或注解配置),生成处理器对象的执行链(如果有),再一起返回给DispatcherServlet。
  • DispatcherServlet调用HandlerAdapter(处理器适配器)。
  • HandlerAdapter经过适配调用具体的处理器(controller)。
  • Controller执行完成返回ModelAndView对象。
  • HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
  • DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
  • ViewReslover解析后返回具体View(视图)。
  • DispatcherServlet根据View进行渲染视图(即将数据填充至视图中)。
  • DispatcherServlet响应用户。

设计组件分析:

1、前端控制器DispatcherServlet(不需要程序员开发),由框架提供,在web.xml中配置。
作用:接收请求,响应结果,相当于转发器,中央处理器。

2、处理器映射器HandlerMapping(不需要程序员开发),由框架提供。
作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。

3、处理器适配器HandlerAdapter(不需要程序员开发),由框架提供。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Controller。

4、控制器Controller(需要工程师开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。
作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。

5、视图解析器ViewResolver(不需要程序员开发),由框架提供
作用:进行视图解析,把逻辑视图名解析成真正的物理视图。
SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、pdfView等。

6、视图View(需要工程师开发)
作用:把数据展现给用户的页面
View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等)

13.2 MVC九大组件

  • HandlerMapping
    处理器映射器,对应的初始化方法是initHandlerMappings(context),这就是根据用户请求的资源uri来查找Handler的。在SpringMVC中会有很多请求,每个请求都需要一个Handler处理,HandlerMapping就解决具体接收到一个请求之后使用哪个Handler进行处理
  • HandlerAdapter
    对应的初始化方法是initHandlerAdapters(context),从名字上看,它就是一个适配器。因为SpringMVC中的Handler可以是任意的形式,只要能处理请求就ok,但是Servlet需要的处理方法的结构却是固定的,都是以request和response为参数的方法。HandlerAdapter解决如何让固定的Servlet处理方法调用灵活的Handler来进行处理
    小结:Handler是用来干活的工具;HandlerMapping用于根据需要干的活找到相应的工具;HandlerAdapter是使用工具干活的人。
  • HandlerExceptionResolver:根据异常设置ModelAndView,之后再交给render方法进行渲染
  • ViewResolver:找到渲染所用的模板和所用的技术(也就是视图的类型)进行渲染
  • RequestToViewNameTranslator:从request中获取ViewName
  • LocaleResolver:解决语言国际化,从request解析出Locale
  • ThemeResolver:⽤来解析主题
  • MultipartResolver:⽤于上传请求
  • FlashMapManager:⽤于重定向时的参数传递

13.3 MVC控制器是不是单例模式

  • 控制器是单例模式
  • MVC如何保证线程安全:

    • 不要在controller中定义成员变量,最好将控制器设计成无状态模式
    • 万一必须要定义一个非静态成员变量时候,则通过注解@Scope(“prototype”),将其设置为多例
    • 在Controller中调用成员变量Service也不会造成线程安全问题:因为只是调用Service里的方法,方法都是线程安全的,多线程调用一个实例的方法,会在内存中复制变量,所以只要不在Constroller里修改Service这个实例就没问题