0
点赞
收藏
分享

微信扫一扫

SSM框架之SpringMVC学习笔记1

哈哈我是你爹呀 2022-01-20 阅读 45

SpringMVC初步学习


MVC


  • 模型(Model(Dao,Service)),视图(View(Jsp)),控制器(Controller(Servlet))
  • 是一种软件设计规范
  • 将业务逻辑,数据,显示分离的方法来组织代码
  • 不是设计模式,而是架构模式
  • 是基于 Java 实现 MVC 的轻量级 Web 框架

导入依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.14</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
    <scope>compile</scope>
</dependency>

一个简单的 SpringMVC 程序


  • 接口方法实现
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>
//导入Controller接口
public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //ModelAndView模型和视图
        ModelAndView mv=new ModelAndView();
        //封装对象,放在ModelAndView中
        mv.addObject("msg","HelloSpringMVC");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello");
        return mv;
    }
}
<?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给他的ModelAndView-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--后缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--前缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <bean id="/hello" class="com.yqly.controller.HelloController"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--注册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>
        <!--启动级别1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--/匹配所有请求:(不包括.jsp页面)-->
    <!--/*匹配所有请求:(包括.jsp页面,会出现不限嵌套的情况)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

有可能出现的问题,Tomcat 项目中没有自动创建 lib 目录

  • 打开项目管理

在这里插入图片描述

  • 创建 lib 目录

在这里插入图片描述

  • 将依赖全部导入该目录

在这里插入图片描述

  • 重启项目

SpringMVC 执行原理


在这里插入图片描述

  1. 用户发出请求

  2. DispatcherServlet 表示前端控制器,是整个 SpringMVC 的控制中心,DispatcherServlet 接收请求并拦截请求

    假设请求的 url 为:http://localhost:8080/SpringMVC/hello

    http://localhost:8080 为服务器域名

    SpringMVC 为部署哎服务器上的 web 站点

    hello 表示控制器

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  1. HandlerMapping 为处理器映射,由 DispatcherServlet 自行调用

    作用:根据 url 查找控制器

  2. HandlerExecution 表示具体的 Handler,将解析后的信息传递给 DispatcherServlet

<bean id="/hello" class="com.yqly.controller.HelloController"/>
  1. HandlerAdapter 表示处理器适配器,其按照特定的规则去执行 Handler
  2. Handler 让具体的 Controller 执行
  3. Controller 将具体的执行信息返回给 HandlerAdpater,如 ModelAndView
  4. HandlerAdapter 将视图逻辑名或模型传递给 DispatcherServlet
  5. DispacherServlet 调用视图解析器(ViewResolver)来解析 HandlerAdapter 传递的逻辑视图名
    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>
  1. 视图解析器将解析的逻辑视图名传给 DispatcherServlet
  2. DispatcherServlet 根据视图解析器解析的视图结果,调用具体视图
  3. 最终将视图呈现给用户

以上十二步可以大概分为三个部分

1~4:适配请求,获得请求的目的

5~8:完成请求,返回结果

9~12:将结果以视图形式展示

注解开发 SpringMVC


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--注册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>
        <!--启动级别1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--/匹配所有请求:(不包括.jsp页面)-->
    <!--/*匹配所有请求:(包括.jsp页面,会出现不限嵌套的情况)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
<?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.yqly.controller"/>
    <!--让SpringMVC不处理静态资源(.css,.js,.html,mp3...)-->
    <mvc:default-servlet-handler/>
    <!--自动完成DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个实例的注入-->
    <mvc:annotation-driven/>
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>
  • @Controller

    代表这个类会被 Spring 接管

    被注解的类中的所有方法,如果返回值为 String,并且有具体页面可以跳转,那么就会被视图解析器解析

  • @RequestMapping

    可以加在类上(表示该类下的所有响应请求的方法都要以该路径为父路径),也可以加在方法上(表示直接路径)

    如果同时注解了类和方法,需要先指定类路径,再指定方法路径

@Controller       
public class HelloController{
    //真是访问地址的选择器名
    @RequestMapping("/test")
    public String Hello(Model model){
        //向模型中添加属性msg与值,可以在jsp页面中取出并渲染
        model.addAttribute("msg","大雾四起");
        return "test";
    }
}

RestFul 风格


  • 是一种资源定位及资源操作的风格

  • 不是标准也不是协议

  • 基于该风格设计的软件可以更加简洁,更有层次,更易于实现缓存等机制

  • 使用不同的方法对资源进行操作

    (POST,DELETE,PUT,GET)分别对应(添加,删除,修改,查询)

传统方法操作资源

  • 通过不同的参数来实现不同的效果,方法单一,POST 和 GET
http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

使用 RestFul 操作资源

  • 可以通过不同的请求方式来实现不同的效果(如:请求地址一样,功能不同)
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
@Controller
public class RestFulController {
    @RequestMapping("/add/{a}/{b}")
    public String test(Model model, @PathVariable int a, @PathVariable int b){
        int sum=a+b;
        model.addAttribute("msg",sum);
        return "test";
    }
}
  • 可以通过 @PathVariable 注解,让方法参数的值对应绑定到一个 URL 模板变量上
  • 可以通过在 @RequestMapping 中加 method 来设置请求方式,也可以通过 @RequestMapping 注解的变体(@GetMapping 等)来设置请求方式

转发与重定向


没有视图解析器

转发的方式

  • 返回路径必须为全路径
@Controller
public class HelloController {
    @RequestMapping("/add/c1")
    public String test(){
        return "/test.jsp";
    }
}
@Controller
public class HelloController {
    @RequestMapping("/add/c1")
    public String test(Model model){
        return "forword:/test.jsp";
    }
}

重定向的方式

@Controller
public class HelloController {
    @RequestMapping("/add/c1")
    public String test(Model model){
        return "redirect:/test.jsp";
    }
}

有视图解析器

转发的方式

  • 默认为转发
@Controller
public class HelloController {
    @RequestMapping("/add/c1")
    public String test(Model model){
        return "test";
    }
}

重定向的方式

  • 与没有视图解析器时一样
@Controller
public class HelloController {
    @RequestMapping("/add/c1")
    public String test(Model model){
        return "redirect:/test.jsp";
    }
}

数据接收和传递


数据接收

  • 从前端获取数据

提交的数据为单个或多个参数

参数名与提交时的数据名一致

提交数据

http://localhost:8080/c1?name=小王

处理方法

@Controller
public class HelloController {
    @RequestMapping("/c1")
    public String test(String name){
        return "test";
    }
}

参数名与提交时的数据名不一致

提交数据

http://localhost:8080/c1?username=小王

处理方法

@Controller
public class HelloController {
    @RequestMapping("/c1")
    public String test(@RequestParam("username") String name){
        return "test";
    }
}

提交的数据为对象

  • 接收前端传递的数据,与对象中的属性名一一匹配,如果一致则填入数据,否则为空

提交数据

http://localhost:8080/user/c2?id=1&name=wxh&age=17

处理方法

@RequestMapping("/c2")
public String test2(User user){
    System.out.println(user);
    return "test";
}

在这里插入图片描述

数据传递

  • 将数据传到前端

  • ModelAndView

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

  • ModelMap

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

  • Model

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

乱码问题


  • 从前端接收到的中文会变成乱码

方法一:加过滤器

编写过滤器

public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

注册

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>com.yqly.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

方法二:配置SpringMVC的乱码过滤

  • 在 web.xml 中配置
<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>

JSON


  • JSON(JavaScript Object Notation),JS 对象标记
  • 是一种轻量级的数据交换格式,使用广泛
  • 采用完全独立于编程语言的文本格式来存储和表示数据
  • 要求和语法格式
    • 对象表示为键值对,数据由逗号隔开
      • { " 键 " : " 值 " , " 键 " : " 值 " … }
    • 花括号保存对象
    • 方括号保存数组

JSON 和 JavaScript 对象互转

  • JSON 字符串转 JavaScript 对象
var obj=JSON.parse('{"a":"hello","b","world"}');
//结果为:{a:'hello',b:'world'}
  • JavaScript 对象转 JSON 字符串
var json=JSON.stringify({a:'hello',b:'world'});
//结果为:'{"a":"hello","b","world"}'
<script>
    let user={
        id:1,
        name:"小王",
        age:17
    };
    let json=JSON.stringify(user);
    console.log(json);
    let parse = JSON.parse(json);
    console.log(parse);
</script>

Controller 返回 JSON 数据

Jackson

  • 前提:导入相关包
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
    <scope>compile</scope>
</dependency>
  • 将对象转换为字符串返回到前端

    @ResponseBody

    代表该方法不会走视图解析器(即不会被拼接),而是直接返回该字符串

    @RestController

    代表该类下的所有方法都不会走视图解析器,不能与 @ResponseBody 同时使用

@Controller
public class UserController {
    @RequestMapping("/j1")
    @ResponseBody
    public String test() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        User user = new User(1,"小钱",22);
        String s = mapper.writeValueAsString(user);
        return s;
    }
}
关于输出 JSON 中的乱码问题
方法一:直接在 @RequestMapping 中设置 produces 的值为 application/json;charset=utf-8
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
方法二:在 springmvc 的配置文件中通过配置来解决乱码问题
<mvc:annotation-driven>
    <mvc:message-converters>
        <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>

Fastjson

  • 前提:导入相关包
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.79</version>
    <scope>compile</scope>
</dependency>
  • Fastjson 主要的类

    JSONObject 代表 json 对象

    JSONArray 代表 json 对象数组

    JSON 代表 JSONObject 和 JSONArray 的转化

@RequestMapping("/j2")
public String test2() throws JsonProcessingException {
    ArrayList<User> userArrayList = new ArrayList<>();
    User user1 = new User(1, "小钱", 11);
    User user2 = new User(2, "小我", 1);
    User user3 = new User(3, "小熊", 41);
    User user4 = new User(4, "小在", 18);
    userArrayList.add(user1);
    userArrayList.add(user2);
    userArrayList.add(user3);
    userArrayList.add(user4);
    return JSON.toJSONString(userArrayList);
}
举报

相关推荐

0 条评论