Spring MVC 学习

Spring MVC

1:什么是Spring MVC!!

学习路线:spring + mybatis + SpringMVC + Vue + spring boot + spring cloud + linux

MVC:Model(模型), View(视图), controller(控制器)

职责分析:

Model:模型,分为数据Dao层和服务层service,用来提供要展示的数据

  1. 业务逻辑
  2. 保存数据的状态

View:视图,一般是我们见到的用户界面(jsp)

  1. 显示页面

Controller:控制层,接受用户请求,委托给模型进行处理,然后把模型返回来的模型数据返回给视图,充当了调度员的作用(servlrt)

  1. 取得表单数据

  2. 调用业务逻辑

  3. 转向指定的页面

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJVC5JJe-1604802369111)(C:\Users\Justin Boy\AppData\Roaming\Typora\typora-user-images\image-20201012165948046.png)]一次请求的步骤:

    1:用户发起请求

    2:Servlet接受请求的数据,取得表单数据,并调用相应的业务逻辑方法(service)

    3:业务逻辑处理数据,返回处理好的数据给servlet

    4:servlet转交给jsp,由jsp渲染页面

    5:响应给前端,渲染页面

全栈:后台 + 前端 + 数据库 + 运维

代码:全部用注解来编程

2020.10.12 bug原因找了一下午

tomcat运行问题:tomcat正常部署,代码也没有错误,但是页面显示404打不开,需要在WEB-INF里新建lib包,然后把包导进去就可以了

2:springMVC项目步骤

2.1配置版

  1. 新建一个maven项目

    1. 不要点create from archetype
    2. Groupid: com.kuang
    3. Artfactid和projectid要一致
  2. 删除src

  3. 导入依赖

  4. 新建modules,步骤和上方一致

  5. 右击add frameword support

  6. 在WEB-INF里建包lib,并在lib里导入架包

  7. 配置web.xml,注册DispatcherServlet(前端控制器)

  8. 编写spring MVC的配置文件:在resources里创建springmvc-servlet.xml,并导入处理映射器,处理器适配器,视图解析器。

  9. 在com.kuang.controller下创建controller,编写控制层

  10. 创建视图层:在WEB-INF下创建jsp文件夹,在创建一个jsp文件

  11. 配置tomcat运行

2.2:Spring MVC执行流程解析

Spring MVC 本质上还是一个servlet

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McPwIGhn-1604802369115)(C:\Users\Justin Boy\AppData\Roaming\Typora\typora-user-images\image-20201012185555907.png)]

2.2.1:springmvc主要文件

1:web.xml:注册前端控制器(DispatcherServlet)

​ 1.1:需要配置servlet 和 servlet-mapping

​ 1.2:servlet标签里需要绑定springmvc-servlet文件(init-param),设置启动顺序(load-on-startup)

​ 1.3: servlet-mapping用于拦截请求

2:springmvc-servlet.xml:配置处理器映射器,处理器适配器,视图解析器,与前端控制器进行交互

​ 2.1:其中,处理器适配器会去寻找controller文件

3:controller:编写业务代码和跳转界面,返回ModelandView

4:jsp文件:用户界面

2.2.2:第一次编写springmvc出现的问题

1:导入错误的HandlerAdapter

2:网址路径前一定要加上“/”

3:spring中的bean只能创建一个类对象,而不能创建一个接口

4:如果实现一个接口后,类下alt+insert找不着对应的重写方法,可能是导错包了

5:使用注解开发时,如果输入字母后没有出现提示,可能是首字母没有大写

2.2.3:HandlerMapper与HandlerAdpter做的事情(易惑点)

1:HandlerMapper只是找到了具体的handler,并生成对象并返回,但并没有执行

2:HandlerAdpter是执行了对应的handler,也就是我们的controller

2.2.4:HandlerMapper执行流程(难点)

1:解析请求的url

2:根据参数找到具体的处理器

3:生成处理器对象(handler)和处理器拦截器

4:返回对象给Dispatcherservlet

2.2.5:注解bean方式

@Component 任何层次

@Repository Dao层(数据访问层)

@Service 业务层

@Controller 控制层

3:Restful 风格

3.1:作用

1:网址路径由原来的http://localhost:8080/hello?a=1&b=1转变为了http://localhost:8080/hello/1/1

2:使用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

3.2:优点

1:安全,不会吧暴露代码

2:简洁

所有的地址栏请求默认都会是 HTTP GET 类型的。

3.3:知识点

1:@PathVariable(路径变量)可以使方法获取到用户传来的网址路径参数

2:组合注解

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

4:转发和重定向

重定向:不需要视图解析器,本质上是重定向到另一个网页

//重定向  不需要视图解析器,本质是重新请求一个新的网页
return "redirect:/index.jsp";

转发:转移到用户请求的网页

return "test";                      //走视图解析器
return "forward:/test.jsp";         //不走视图解析器

5:数据处理

5.1:接受前端的参数

1:前端传来的参数与处理方法的参数名一致,那么可以直接接收到参数

2:前端传来的参数与处理方法的参数名不一致,需要使用@RequestParam(“传来的参数名”)

3:前端传来的参数是一个对象,如果参数名和对象属性名不一致,那么为nul

http://localhost:8080/user/t2?id=123&name=www&age=20

5.2:数据显示到前端

1:ModelandView

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
	ModelAndView mv = new ModelAndView();

	mv.addObject("msg","HelloSpringMVC!");
	mv.setViewName("hello"); 

	return mv;
   }

2:Model

public String handlerRequest(Model model){
        model.addAttribute("msg","anan is so lovely");
        return "anan";
    }

3:Modelmap

public String hello(String name, ModelMap model){
   //封装要显示到视图中的数据
   model.addAttribute("msg","anan is so beautiful");
   System.out.println(name);
   return "anan";
}

对比

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

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

ModelAndView 可以在储存数据的同时,可以进行设置视图跳转

6:Json

6.1:概念

数据交换格式,是js对象的字符串表示法,本质上是一个字符串

6.2:格式

{"name":"anan"}

6.3:Json与js对象互转

//把Json字符串转化为js对象
var obj = JSON.parse();

//把js对象转化为Json字符串
var json = JSON.stringify();

6.4:Jackson --json解析工具

6.4.1:Jackson使用步骤

1:导入依赖

2:json处理乱码

<mvc:annotation-driven>
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.StringHttpMessageConverter">
           <constructor-arg value="UTF-8"/>
       bean>
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                   <property name="failOnEmptyBeans" value="false"/>
               bean>
           property>
       bean>
   mvc:message-converters>
mvc:annotation-driven>

3:编写工具类

package com.kuang.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.text.SimpleDateFormat;

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

    public static String getJson(Object object,String DataFormat){
        ObjectMapper mapper = new ObjectMapper();
        //不使用时间戳
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DataFormat);
        mapper.setDateFormat(simpleDateFormat);
        try{
            return mapper.writeValueAsString(object);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}

4:调用工具类,传递参数

5:测试

6.4.2:新知识

1:@RestController放在类上,可以是类中的所有方法都返回字符串,不走视图解析器

2:@ResponseBody放在方法上,可以不走视图解析器,配合@Controller使用

3:Jackson的使用

  • 首先要实例化一个jackson的对象映射器ObjectMapper,用来解析数据
  • 调用mapper.writeValueAsString()方法,把对象解析成json字符串

4:mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); 不使用时间戳

5:mapper.setDateFormat(simpleDateFormat); 设置数据格式

6:使用工具类来简化代码的思想,工具类里使用重载的方式的思想

6.5 FastJson

实现json对象,JavaBean对象,json字符串之间的相互转换

依赖

<dependency>
   <groupId>com.alibabagroupId>
   <artifactId>fastjsonartifactId>
   <version>1.2.60version>
dependency>

方法使用:

JSON.toJSONString();      java对象转化为JSON字符串
    
JSON.parseObject()        JSON字符串转化为java对象
    
JSON.toJSON()             java对象转化为JSON对象
    
JSON.toJavaObject()       JSON对象转化为java对象

7:SSM框架整合

7.1:步骤

1:新建maven项目

2:配置pom.xml

  • 导入相关依赖
  • 静态资源导出问题

3:Mybatis层的整合:配置Resources

  • Mybatis的核心配置文件:mybatis-config.xml
  • spring的核心配置文件:applicationContext.xml
  • 数据库连接配置文件:db.properties

4:Mybatis层的整合:建立基本框架

  • com.kuang.pojo:普通的java类
  • com.kuang.dao:持久层,也叫数据访问层,负责与数据库的数据进行交互,实现数据持久化
    • BookMapper接口
    • BookMapper.xml文件
  • com.kuang.service:业务层,用于实现操作的具体方法
    • BookService接口
    • BookServiceImpl接口实现类
  • com.kuang.controller:控制层,调用service中的接口控制具体的业务流程
  • com.kuang.filter:过滤层,解决乱码问题(可选)
  • com.kuang.utils:工具类,实现代码的复用(可选)

5:spring层的整合

  • spring-dao
    • 关联数据库配置文件db.properties
    • 连接池
    • sqlSessionFactory
    • MapperScannerConfiguer:自动扫描包中的接口,生成映射器 ?
  • spring-service
    • context:component-scan 自动扫描包 + 注解完成bean的装配
    • 接口实现类的bean
    • 声明式事务管理配置 ?
    • aop事务支持

6:springmvc层的整合

  • 添加web支持

  • 导入架包

  • 配置web.xml

    • Dispatcherservlert 前端控制器
    • 乱码过滤
    • 设置session过期时间
  • 配置spring-mvc.xml

    • context:component-scan 自动扫描包
    • mvc:annotation-driver 注解驱动
    • 静态资源过滤
    • 视图解析器

    至此,环境搭配完毕

7:编写Controller层

  • ​ controller层调service层

8:编写jsp视图层

7.2:问题

1:显示全部书籍报错

解决:tomcat从新载入项目

2:查询书名查询不出来

解决:jsp的属性name要与controller的参数名字一致

黑科技:bootstrap可视化布局

8:Ajax

概念

异步无刷新请求

JQuery

通过 jQuery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON – 同时您能够把这些外部数据直接载入网页的被选元素中。

jQuery.ajax(...)
      部分参数:
            url:请求地址
            type:请求方式,GET、POST(1.9.0之后用method)
        headers:请求头
            data:要发送的数据
    contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
          async:是否异步
        timeout:设置请求超时时间(毫秒)
      beforeSend:发送请求前执行的函数(全局)
        complete:完成之后执行的回调函数(全局)
        success:成功之后执行的回调函数(全局)
          error:失败之后执行的回调函数(全局)
        accepts:通过请求头发送给服务器,告诉服务器当前客户端可接受的数据类型
        dataType:将服务器端返回的数据转换成指定类型
          "xml": 将服务器端返回的内容转换成xml格式
          "text": 将服务器端返回的内容转换成普通文本格式
          "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
        "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
          "json": 将服务器端返回的内容转换成相应的JavaScript对象
        "jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
      

9:拦截器

概念

用于拦截请求,是AOP思想的具体应用

错误:一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到、

解决:说明没有导入lib包,tomcat运行不起来

步骤

1:需要继承HandlerInterceptor 接口,就是一个拦截器

2:重写HandlerIntervrptor接口的方法

3:在springmvc的配置文件里配置拦截器


<mvc:interceptors>
   <mvc:interceptor>
       
       
       
       <mvc:mapping path="/**"/>
       
       <bean class="com.kuang.interceptor.MyInterceptor"/>
   mvc:interceptor>
mvc:interceptors>

4:运行测试

知识点

1:return true 表示继续往下执行

​ return false 表示终端后面的所有操作

2:HttpSession session = request.getSession()可以获取请求的很多参数方法

3:request. 会获取很多关于请求的方法

4:request.getRequestDispatcher().forward(request,response);跳转到某个界面

标签含义

<html>html> 之间的文本描述网页
<body>body> 之间的文本是可见的页面内容
<h1>-<h6>定义html标题
<p>标签定义html段落
<a>标签定义html链接
<img>标签定义html图像
<br />标签用于换行
html属性在开始标签里定义,比键值对的方式出现
<table>定义html的表格
<hr />标签在html页面里创建水平线
<q>用于引用  在旁边加上引号
<nav>定义导航链接的部分
<span>用来组合文档中的行内元素
<div>用来组合文档中的块级元素
<li>定义列表项目
<ul>有序列表
<ol>无序列表
<footer>定义页脚部分
<script>用来导入javaScript代码
<button>定义按钮
<label>为input元素定义标注
<input>用于获取用户信息
<form>定义供用户输入的html表单  会进行网址的跳转-?
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory

一定是没有导入架包的问题

10:文件上传和文件下载

代码是死的

applicationContext.xml配置

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

文件上传

//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    //批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);

        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流

        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }

    /*
     * 采用file.Transto 来保存上传的文件
     */
    @RequestMapping("/upload2")
    public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        //上传文件地址
        System.out.println("上传文件保存地址:"+realPath);

        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));

        return "redirect:/index.jsp";
    }

文件下载

 /*文件下载*/
    @RequestMapping(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String  path = request.getServletContext().getRealPath("/upload");

        /*秩序修改这里的名字即可  其他东西都是死的*/
        String  fileName = "1.jpg";

        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));

        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();

        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }

11:第一次部署ssm框架出现的错误

1:spring整合dao层和service层不熟练,导包不准确 --多练

2:mapper里没有写namespace

3:spring-dao.xml配置数据库文件时没有加classpath:,导致运行不成功

你可能感兴趣的:(java,spring,web,springmvc)