【SpringMVC】学习笔记(全)

学习笔记,如有错误,请留言指正

SpringMVC

SSM: SpringMVC + Spring + MyBatis

MVC 三层架构

springMVC的工作流程(重点)

1. 回顾MVC

  • Model : 模型(dao,service…)

  • View : 视图(html, jsp…)

  • Controller : 控制层(servlet…)

MVC是一种软件设计规范,是将业务逻辑、数据、显示分离的方法来组织代码,降低了视图与业务逻辑间的双向耦合;

项目中的Entity、VO、DTO

1、entity 里的每一个字段,与数据库相对应,

2、vo 里的每一个字段,是和你前台 html 页面相对应,

3、dto 这是用来转换从 entity 到 vo,或者从 vo 到 entity 的中间的东西 。(DTO中拥有的字段应该是entity中或者是vo中的一个子集)

2. 回顾servlet

新建项目

  • 导包:
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.8</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
  • helloServlet

    • servlet需要继承HttpServlet包
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1. 获取前端请求
            String method = req.getParameter("method");
            if (method.equals("add")){
                HttpSession session = req.getSession();
                session.setAttribute("msg","执行了add方法");
    
            }else if(method.equals("delete")){
                req.getSession().setAttribute("msg","执行了delete方法!");
            }
            //2. 调用业务层
    
            //3. 返回数据或转发/重定向
            req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • web.xml

    • servlet需要在web.xml中配置
    <?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">
    
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.nych.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/helloTest</url-pattern>
        </servlet-mapping>
    
        
            <!--  超时时间 分钟 -->
    <!--    <session-config>-->
    <!--        <session-timeout>15</session-timeout>-->
    <!--    </session-config>-->
    
    
            <!--  首面  -->
    <!--    <welcome-file-list>-->
    <!--        <welcome-file></welcome-file>-->
    <!--    </welcome-file-list>-->
    
    </web-app>
    
  • 请求页面

    • index.jsp
    <%--
      Created by IntelliJ IDEA.
      User: nych
      Date: 2021/8/12
      Time: 11:21
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
        <form action="helloTest" method="post">
          <input type="hidden" name="method" value="add">
          <input type="submit">
        </form>
      </body>
    </html>
    

3. SpringMVC

  • 特点
    • 轻量级,简单易学
    • 高效,基于请求响应的MVC框架
    • 与Spring兼容性好,无缝结合
    • 约定大于配置
    • 功能强大
    • 使用的人多

Spring的web框架围绕着DispatcherServlet设计,DispatcherServlet的作用是将请求分发到不同的处理器。

3.1 springMVC初体验:

  • web.xml

    <?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; 这是springMVC的核心配置,请求分发器/前端控制器  -->
        <servlet>
            <servlet-name>springMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--  DispatcherServlet需要绑定spring的配置文件  -->
            <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>
    
  • 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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--  处理器/映射器  -->
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        <!--  处理器适配器  -->
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
        <!--  视图解析器  -->
        <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 前缀 访问路径 -->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!-- 后缀 -->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <bean id="/h1" class="com.nych.controller.HelloController"/>
    
    </beans>
    
  • 对应的jsp文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WDE4Ekqi-1629163721568)(SpringMVC.assets/1628844236606.png)]

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>HelloSpringMVC</title>
    </head>
    <body>
        <h1>${msg}</h1>
    </body>
    </html>
    
  • controller

    public class HelloController implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            
            ModelAndView mv = new ModelAndView();
            //业务代码
            String result = "Hello SpringMVC";
            mv.addObject("msg",result);
    
            //视图跳转
            mv.setViewName("test"); // WEB-INF/jsp/test.jsp
    
            return mv;
        }
    }
    

**注意:**输出文件中有没有jar包,需要在WEB-INF下创建lib目录存放jar包

3.2 springMVC注解开发

  • web.xml

    <?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"
             metadata-complete="true">
    	<!--  配置DispatcherServlet  -->
        <servlet>
            <servlet-name>springmvcAnno</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--绑定spring配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvcAnno-Servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvcAnno</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>
    
  • springmvcAnno-Servlet.xml(spring配置文件)

    <?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
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    	<!--自动扫描指定包使用的注解-->
        <context:component-scan base-package="com.nych.controller"/>
        <!--默认servlet处理器-->
        <mvc:default-servlet-handler/>
        <!--注解驱动-->
        <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>
    
  • contorller

    @Controller
    @RequestMapping("/hello")  @RequestMapping表示请求地址
    public class TestController {
    
        @RequestMapping("/h1")
        public String test1(Model model){
            model.addAttribute("msg","hello springMVC Annotation!!");
            return "test";
        }
    //请求地址: http://localhost:8080/hello/h1
    }
    

4. RestFul 风格

  • 传统操作

    http://localhost:8080/selectitem?id=1&id=2	get
    http://localhost:8080/saveitem.action   post
    
  • restfull操作

    http://localhost:8080/item/1    get
    http://localhost:8080/item		post
    http://localhost:8080/item		put
    http://localhost:8080/item/1	delete
    
@Controller
public class RestFullController {

    //原: http://localhost:8080/add?a=1&b=2
    @RequestMapping("add")
    public String test01(Model model, int a, int b){
        int res = a + b;
        model.addAttribute("res",res);
        return "test";
    }

    
    //restfull:  http://localhost:8080/addTwo/2/3
    //@PathVariable定义的变量在@RequestMapping中用{}指定
    //method可以指定请求方式,或者直接使用@GetMapping
    
    //@RequestMapping(value="/add2/{a}/{b}", method = RequestMethod.GET)
    @GetMapping(value="/addTwo/{a}/{b}")
    public String test02(Model model, @PathVariable int a, @PathVariable int b){
        int res = a + b;
        model.addAttribute("res",res);
        return "test";
    }

    
    //只接受post提交方式
    @PostMapping("/addThree")
    public String test03(int a, int b, Model model){
        int res = a + b;
        model.addAttribute("res",res);
        return "test";
    }
}

5. springMVC 结果跳转方式

ModelAndView:

设置ModelAndView对象,根据viewName,和视图解析器跳转到指定页面;

视图解析器前缀 + viewName + 视图解析器后缀 = 页面地址

Servlet API:

重定向:

rsponse.sendRedirect("/index.html")

转发:

request.setAttribute("msg","hello world");
request.getRequestDispatcher("/WEB-INF/static/jsp/test.jsp");

测试代码:

@Controller
public class ServletController {

    @RequestMapping("sc/t1")
    public String test1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        session.setAttribute("msg","hello world!");
        return "test";
    }

    @RequestMapping("sc/t2")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {

        HttpSession session = request.getSession();
        session.setAttribute("msg","内容......");
        response.sendRedirect("/test2.jsp");
    }

    @RequestMapping("sc/t3")
    public void test3(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.setAttribute("msg","10000010100101010101");
        request.getRequestDispatcher("/test2.jsp").forward(request,response);
    }

}

SpringMVC转发/重定向:

  • 无需视图解析器 (需要注释掉视图解析器)

  • 等同于servlet的重定向和转发

  • 转发

//返回正确的路径,且没有视图解析器,则代表转发
@RequestMapping("smc/t4")
public String test04(Model model){
    model.addAttribute("msg","转发1");
    return "/WEB-INF/jsp/test.jsp"; //转发
}
//在路径前加forward: 也表示转发
@RequestMapping("smc/t2")
public String test02(Model model){
    model.addAttribute("msg","转发2");
    return "forward:/test2.jsp"; //转发
}
  • 重定向
@RequestMapping("smc/t3")
public String test03(Model model){
    model.addAttribute("msg","重定向");
    //重定向
    return "redirect:/test2.jsp";
}

6. 参数传递

  • 接收数据

    @Controller
    @RequestMapping("/u")
    public class ParameterController {
    
        //localhost:8080/u/t1?name=张三
        @RequestMapping("t1")
        public String test01(String name, Model model){
            //前端参数
            System.out.println("参数为: "+ name);
            model.addAttribute("msg",name);
            return "test";
        }
        
    
        // @RequestParam("username") 指定前端传过来的参数名
        //localhost:8080/u/t1?username=张三
        @RequestMapping("t2")
        public String test02(@RequestParam("username") String name, Model model){
            //前端参数
            System.out.println("参数为: "+ name);
            model.addAttribute("msg",name);
            return "test";
        }
        
    
        //@RequestParam("username") 指定前端传过来的参数名
        //http://localhost:8080/u/t3?id=1&name=张三&age=21
        @RequestMapping("t3")
        public String test03(User user, Model model){
            //前端参数
            System.out.println(user.toString());
            return "test";
        }
    }
    
  • 数据回显

    • ModelAndView

    • Model

    • ModelMap

      @RequestMapping("t4")
      public String test04(ModelMap modelMap){
          modelMap.addAttribute("msg","1111");
          return "test";
      }
      

7. 解决中文乱码

1. 自定义过滤器:

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() {

    }
}
  • 在web.xml中配置自定义过滤器:
<!-- 配置自己定义的过滤器 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.nych.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. 使用spring的过滤器:

<filter>
    <filter-name>encoding1</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>encoding1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8. Json

前后端分离

json是一种数据交换格式,使用广泛

json是以键值对来表示的,json是javaScript的一种对象表示方式

{
    "name":"张三",
    "age":3,
    "sex":"男"
}

Json和javaScript对象互相转换:

Json转换为JavaScript对象,使用JSON.parse()方法

var jsonStr = '{"a":"Hello", "b":"world"}';
var obj = JSON.parse(jsonStr);

JavaScript对象转换为Json字符串,使用JOSN.stringify()方法

var obj = {
    a:'hello',
    b:1
};
var jsonStr = JSON.stringify(obj);
  • 测试代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    </body>
    </html>
    
    <script type="text/javascript">
        //javascript对象
        let obj = {
            name : "张三",
            sex : "男",
            age : 21
        }
        console.log(obj);
    
        //转换为json字符串
        let jsonStr = JSON.stringify(obj);
        console.log(jsonStr)
    
        //将json字符串转换为对象
        let obj2 = JSON.parse(jsonStr);
        console.log(obj2)
    
    </script>
    

9. Java接口返回json

  • 返回json数据需要使用到解析工具
  • json解析工具有 jackson,阿里巴巴的fastjson等等(或自己写)

Jackson:

  • 导入jackson的jar包

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.12.3</version>
    </dependency>
    
  • controller

    • @ResponseBody //就不会走视图解析器了(不进行视图跳转了),会直接返回定义的数据
    • @RequestMapping(value = “/t1”, produces = “application/json;charset=utf-8”): 解决返回中文乱码问题
    @Controller
    @RequestMapping("/j")
    public class Controller01 {
        @RequestMapping(value = "/t1", produces = "application/json;charset=utf-8")
        @ResponseBody
        public String jsonTest01() throws JsonProcessingException {
    
            User user = new User(1,"张三",21);
            //jackson对象
            ObjectMapper objectMapper = new ObjectMapper();
    
            //使用jackson对象的writeValueAsString方法,将对象转换为json字符串返回
            return objectMapper.writeValueAsString(user);
        }
    
    }
    

如果每个请求都要配置解决中文乱码问题就非常麻烦,spring配置可以解决这一问题

<!--解决json返回中文乱码,不需要记,知道如何解决即可-->
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg name="defaultCharset" 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>

以下是返回不同数据类型的不同写法:

  • @RestController: 等同于 @Controller + @ResponseBody
@RestController
@RequestMapping("/j")
public class Controller01 {
    
    @RequestMapping("/t1")
    public String jsonTest01() throws JsonProcessingException {
        User user = new User(1,"张三",21);
        //jackson对象
        ObjectMapper objectMapper = new ObjectMapper();
        //使用jackson对象的writeValueAsString方法,将对象转换为json字符串返回
        return objectMapper.writeValueAsString(user);
    }

    
    @RequestMapping("/t2")
    public String jsonTest02() throws JsonProcessingException {

        List<User> userList = new ArrayList<>();
        User user1 = new User(1,"张三",20);
        User user2 = new User(2,"李四",22);
        User user3 = new User(3,"王五",21);
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);

        ObjectMapper objectMapper = new ObjectMapper();

        return objectMapper.writeValueAsString(userList);
    }
    

    @RequestMapping("/t3")
    public String jsonTest03() throws JsonProcessingException {
        //返回时间戳
        Date date = new Date();
        //自定义时间格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        ObjectMapper objectMapper = new ObjectMapper();

        return objectMapper.writeValueAsString(dateFormat.format(date));
    }

    
    //使用自己二次封装的类,实现格式化时间
    @RequestMapping("/t4")
    public String jsonTest04(){
        Date date = new Date();
        return JsonUtil.getJson(date, "yyyy-MM-dd HH:mm:ss");
    }
    

    //使用自己二次封装的类,返回json数据
    @RequestMapping("/t5")
    public String jsonTest05(){
        User user = new User(1,"张三",23);
        return JsonUtil.getJson(user);
    }
    

    //使用自己二次封装的类,实现格式化时间
    @RequestMapping("/t6")
    public String jsonTest06(){
        Date date = new Date();
        return JsonUtil.getJson(date);
    }

}

对Jackson的二次封装:

public class JsonUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private JsonUtil(){

    }

    public static String getJson(Object object){
       return getJson(object,"yyyy-MM-dd HH:mm:ss");
    }

    public static String getJson(Object object, String dateFormat){
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        objectMapper.setDateFormat(format);
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 导入jackson包,并且使用@RestController注解,直接返回java对象,自动会转换为json格式数据

FastJson:

  • fastjson是阿里开发的一款专门用于java开发的包,可以方便的实现json对象与javaBean对象的转换等功能。

导入依赖包:

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
//fastjson
@RequestMapping("/t7")
public String jsonTest07(){

    List<User> userList = new ArrayList<>();
    User user1 = new User(1,"张三",20);
    User user2 = new User(2,"李四",22);
    User user3 = new User(3,"王五",21);
    userList.add(user1);
    userList.add(user2);
    userList.add(user3);

    //对象转json
    String str = JSON.toJSONString(userList);
    
    return str;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值