SpringMVC学习笔记
发布日期:2021-05-09 09:24:34 浏览次数:19 分类:博客文章

本文共 23736 字,大约阅读时间需要 79 分钟。

目录

SpringMVC

SpringMVC:

  • controller:控制器
    • 获得表单数据
    • 调用业务逻辑
    • 转向指定页面
  • model:模型
    • 业务逻辑
    • 保存数据的状态
  • view:视图
    • 显示页面

SpringMVC优点:

  • 轻量级,简单易学
  • 高效,基于请求响应的MVC框架
  • 与 Spring 兼容性好,无缝集成
  • 约定优于配置
  • 功能强大:restful,数据验证,格式化等
  • 将业务逻辑,数据,显示分离,降低各个模块之间的耦合,

初识SpringMVC

Spring的web框架围绕DispatcherServlet调度Servlet设计。

HelloSpringMVC项目搭建,pom.xml中导入spring-webmvc,servlet-api,jstl-api,jstl的jar包

web.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/

springmvc-servlet.xml

HelloController

//注意:导入org.springframework.web.servlet.mvc.Controller;public class HelloController implements Controller {    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {        //模型和视图        ModelAndView mv = new ModelAndView();        //封装对象,放在ModelAndView中        mv.addObject("msg","HelloSpringMVC!");        //封装要跳转的视图        mv.setViewName("hello");  ///WEB-INF/jsp/hello.jsp        return mv;    }}

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>    Title    ${msg}    

注意:如果访问http://localhost:8080/hello出现404

选中自己的项目名,在WEB-INF下新建lib文件夹,点击+号,将项目的依赖添加到lib中,重启项目!!!

SpringMVC执行流程

  1. DispatcherServlet表示前置控制器,是整个SpringMVC控制的中心,用户发出请求,DispatcherServlet接收请求并拦截请求。
  2. HandlerMapping为处理器映射器,根据处理器请求url查找Handler,由DispatcherServlet调用。
  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器。
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
  5. HandlerAdapter表示处理器适配器,按特定的规则执行Handler。
  6. Handler让具体的Controller执行。
  7. Controller将执行的信息返回给HandlerAdapter,如ModelAndView。
  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  11. 视图渲染呈现给用户。

使用注解开发SpringMVC

控制器Controller

  • 控制器负责提供访问应用程序的行为,通常通过接口定义或注解定义两种方式实现。

  • 控制器负责解析用户的请求并将其转化为一个模型。

  • 在SpringMVC中一个控制器类可以包含多个方法。

web.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/

springmvc-servlet.xml

HelloController

@Controllerpublic class HelloController {    @RequestMapping("/h1")    public String hello(Model model){        //封装数据        model.addAttribute("msg","HelloSpringMVCAnnotation");        return "hello"; //视图解析器处理    }}

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>    Title	${msg}

RestFul风格

概念:RestFul就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

URL定义

资源:互联网所有的事物都可以被抽象为资源

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。

传统方式操作资源

新增,POST
更新,POST
删除,GET或POST

使用RestFul操作资源:可以通过不同的请求实现不同的效果!

[ 查询,GET

[ 新增,POST
[ 更新,PUT
[ 删除,DELETE

学习测试

  1. 新建一个测试类RestFulController,在方法参数前面加@PathVariable注解,让方法参数的值对应绑定到一个URL模板变量上。

    @Controllerpublic class RestFulController {    @RequestMapping("/add/{a}/{b}")    public String test(@PathVariable int a, @PathVariable int b, Model model){        int res = a + b;        model.addAttribute("msg","结果为"+res);        return "test";  //test.jsp    }}

请求地址相同,得到结果不同的情况

//@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.DELETE)//@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)@GetMapping("/add/{a}/{b}")public String test(@PathVariable int a, @PathVariable int b, Model model){    int res = a + b;    model.addAttribute("msg","结果1为"+res);    return "test";}@PostMapping("/add/{a}/{b}")public String test2(@PathVariable int a, @PathVariable int b, Model model){    int res = a + b;    model.addAttribute("msg","结果2为"+res);    return "test";}

web下a.jsp

web/WEB-INF/jsp/test.jsp

${msg}

重定向和转发

ModelAndView:根据view的名字,和视图解析器跳转到指定的页面。

使用springmvc来实现转发和重定向-----无视图解析器

@Controllerpublic class ModelTest1 {    @RequestMapping("/m1/t1")    public String test(Model model){        model.addAttribute("msg","ModelTest1");        // return "/WEB-INF/jsp/test.jsp";        //转发        // return "forward:/index.jsp";        //重定向           return "redirect:/index.jsp";    }

使用springmvc来实现转发和重定向-----有视图解析器

@Controllerpublic class HelloController {    @RequestMapping("/h1")    public String hello(Model model){        //封装数据        model.addAttribute("msg","HelloSpringMVCAnnotation");        return "hello"; //视图解析器处理    }}

数据处理

User实体类

@Data@AllArgsConstructor@NoArgsConstructorpublic class User {    private int id;    private String name;    private int age;}

UserController类,使用@RequestParam("***")接收参数

@Controller@RequestMapping("/user")public class UserController {    //localhost:8080/user/t1?name=***    @RequestMapping("/t1")    public String test1(@RequestParam("name") String name, Model model){        //接收前端参数        System.out.println("接收到前端的参数为"+name);        //将结果传递给前端        model.addAttribute("msg",name);        //跳转视图        return "test";    }    /*    1.接收用户传递的参数,判断参数的名字,假设名字直接在方法上,就可以直接用    2.假设传递的是一个对象User,匹配User对象的字段名     */    //http://localhost:8080/user/t2?id=1&name=zzzrrr&age=20    //前端接受的是一个对象:id,name,age    @RequestMapping("/t2")    public String test2(User user){        System.out.println(user);        return "test";    }

乱码处理

在开发中,我们会经常遇到乱码问题,在Servlet阶段使用的是编写过滤器过滤。现在SpringMVC也给我们提供了一个过滤器,在xml中配置,然后重启服务器。

web下form.jsp

EncodingController

@Controllerpublic class EncodingController {    @PostMapping("/e/t1")    public String test1(String name, Model model){        model.addAttribute("msg",name);        System.out.println(name);        return "test";    }}

编码过滤器

encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encoding
/*

JSON

什么是JSON:

  • JSON(JavaScript Object Notation,js对象标记)是一种轻量级数据交换格式
  • 采用完全独立于编程语言的文本格式来存储和表示数据
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效提升网络传输速率
  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组
    
Title

Jackson的使用

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。Jackson 是最流行的 json 解析器之一 。

Jackson 最常用的 API 就是基于"对象绑定" 的 ObjectMapper。

使用前pom.xml加入依赖

com.fasterxml.jackson.core
jackson-databind
xml
2.10.0

web.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/
encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encoding
/*

springmvc-servlet.xml

User类

@Data@AllArgsConstructor@NoArgsConstructorpublic class User {    private String name;    private int age;    private String sex;}

UserController

@RestController    //不会走视图解析器,public class UserController {    //注解解决json乱码 建议在xml中解决乱码    // @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")    @RequestMapping("/j1")    //@ResponseBody  //不会走视图解析器,会直接返回一个字符串    public String json1() throws JsonProcessingException {        //jackson  ObjectMapper        ObjectMapper mapper = new ObjectMapper();        //创建一个对象        User user = new User("周周",20,"南");        String s = mapper.writeValueAsString(user);        return s;    }}

返回一个json数组,返回格式化时间(方法加在UserController类中)

@RequestMapping("/j2")public String json2() throws JsonProcessingException {    ObjectMapper mapper = new ObjectMapper();    List
list = new ArrayList
(); User user1 = new User("周周1",20,"南"); User user2 = new User("周周2",20,"南"); User user3 = new User("周周3",20,"南"); User user4 = new User("周周4",20,"南"); list.add(user1); list.add(user2); list.add(user3); list.add(user4); String s = mapper.writeValueAsString(list); return s;}@RequestMapping("/j3")public String json3() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); //自定义日期的格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); //return mapper.writeValueAsString(date); return mapper.writeValueAsString(sdf.format(date));}@RequestMapping("/j4")public String json4() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); //使用ObjectMapper 格式化输出 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); mapper.setDateFormat(sdf); Date date = new Date(); return mapper.writeValueAsString(date);}

封装思想

工具类

public class JsonUtil {        public static String getMapper(Object object,String dateFormat){        ObjectMapper mapper = new ObjectMapper();        //使用ObjectMapper  格式化输出        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);        mapper.setDateFormat(sdf);        try {            return mapper.writeValueAsString(object);        } catch (JsonProcessingException e) {            e.printStackTrace();        }        return null;    }    public static String getMapper(Object object){        return getMapper(object,"yyyy-MM-dd HH:mm:ss");    }}

测试工具类(方法加在UserController类中)

@RequestMapping("/j5")public String json5() {    Date date = new Date();    return JsonUtil.getMapper(date,"yyyy-MM-dd HH:mm:ss");}@RequestMapping("/j6")public String json6() {    List
list = new ArrayList
(); User user1 = new User("周周1",20,"南"); User user2 = new User("周周2",20,"南"); User user3 = new User("周周3",20,"南"); User user4 = new User("周周4",20,"南"); list.add(user1); list.add(user2); list.add(user3); list.add(user4); return JsonUtil.getMapper(list);}

FastJson

FastJson是阿里巴巴开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象de转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。

导包

com.alibaba
fastjson
1.2.74

FastJson三个主要的类

  • JSONObject 代表json对象,JSONObject实现了Map接口
  • JSONArray 代表json数组对象,内部是由list接口中的方法完成操作
  • JSON代表 JSONObject 和 JSONArray的转化
@RequestMapping("/j7")public String json7() {    List
list = new ArrayList
(); User user1 = new User("周周1",20,"南"); User user2 = new User("周周2",20,"南"); User user3 = new User("周周3",20,"南"); User user4 = new User("周周4",20,"南"); list.add(user1); list.add(user2); list.add(user3); list.add(user4); //java对象转json字符串 String s = JSON.toJSONString(list); System.out.println(s); String s1 = JSON.toJSONString(user1); System.out.println("s1: "+s1); //json字符串转java对象 User s2 = JSON.parseObject(s1,User.class); System.out.println("s2: "+s2.toString()); //java对象转json对象 JSONObject s3 = (JSONObject) JSON.toJSON(user2); System.out.println("s3: "+s3.toJSONString()); // json对象转java对象 User s4 = JSON.toJavaObject(s3, User.class); System.out.println("s4: "+s4); return "hello"; }}

整合SSM

新建maven一个项目ssmbuild

环境配置:

pom.xml中导入以下依赖和允许静态资源导出

......
src/main/resources
**/*.properties
**/*.xml
false
src/main/java
**/*.properties
**/*.xml
false

database.properties

jdbc.driver=com.mysql.jdbc.Driver#如果使用的是MySQL 8.0+,增加一个时区的配置jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=UTF-8jdbc.username=rootjdbc.password=123456

mybatis-config.xml

spring-dao.xml

spring-service.xml

applicationContext.xml

BookMapper.xml

insert into books (bookName,bookCounts,detail) values (#{bookName},#{bookCounts},#{detail});
delete from books where bookID=#{id};
update books set bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail} where bookID=#{bookID};

web.xml 【classpath:applicationContext.xml】bean的创建交给了applicationContext.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:applicationContext.xml
1
springmvc
/
encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encoding
/*
15

实体类

@Data@AllArgsConstructor@NoArgsConstructorpublic class Books {    private int bookID;    private String bookName;    private int bookCounts;    private String detail;}

BookMapper

public interface BookMapper {    //增加一本书    int addBook(Books books);    //删除一本书    int deleteBookById(@Param("id") int id);    //修改一本书    int updateBook(Books books);    //查询一本书    Books selectBookById(@Param("id") int id);    //查询全部    List
selectAllBook();}

BookService

public interface BookService {    //增加一本书    int addBook(Books books);    //删除一本书    int deleteBookById(@Param("id") int id);    //修改一本书    int updateBook(Books books);    //查询一本书    Books selectBookById(@Param("id") int id);    //查询全部    List
selectAllBook();}

BookServiceImpl

public class BookServiceImpl implements BookService{    //service调用dao层:组合dao层    private BookMapper bookMapper;    public void setBookMapper(BookMapper bookMapper) {        this.bookMapper = bookMapper;    }    public int addBook(Books books) {        return bookMapper.addBook(books);    }    public int deleteBookById(int id) {        return bookMapper.deleteBookById(id);    }    public int updateBook(Books books) {        return bookMapper.updateBook(books);    }    public Books selectBookById(int id) {        return bookMapper.selectBookById(id);    }    public List
selectAllBook() { return bookMapper.selectAllBook(); }}

Ajax

Ajax:异步,能在无需加载整个页面的情况下,更新部分网页的技术。

Ajax不是一种编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。

web.xml配置DispatcherServlet和encoding,spring-mvc.xml配置视图解析器,扫描包,支持注解驱动,静态资源支持

开启窗口

test.html

    
iframe测试体验页面无刷新

请输入地址:

Ajax的核心就是XMLHttpRequest。

Ajax异步加载数据

package com.zr.pojo;@Data@AllArgsConstructor@NoArgsConstructorpublic class User {    private int id;java    private String name;    private String sex;}

AjaxController

package com.zr.controller;@RestControllerpublic class AjaxController {    @RequestMapping("/t1")    public String test(){        return "hello";    }    @RequestMapping("/a")    public void a1(String name, HttpServletResponse response) throws IOException {        System.err.println("name--->>"+name);        if ("zr".equals(name)){            response.getWriter().println("true");        }else {            response.getWriter().println("false");        }    }}

index.jsp

    $Title$      <%--      --%>        <%--  失去焦点的时候,发送一个请求到后台--%>  用户名:  

test2.jsp

    Title        
<%-- 数据--%>
编号 姓名 性别

AjaxController

@RequestMapping("/a2")public List
a2(){ List
userList = new ArrayList
(); //添加数据 userList.add(new User(1,"周zrr","南")); userList.add(new User(2,"周","南")); userList.add(new User(3,"周周周","南")); return userList;}

Ajax验证用户名

login.jsp

    Title    <%--    --%>    

用户名:

密码:

AjaxController

@RequestMapping("/a3")public String a3(String name,String pwd){    String msg="";    if (name!=null){        //这些数据应该从数据库中查        if ("admin".equals(name)){            msg = "ok";        }else {            msg = "用户名输入错误";        }    }    if (pwd!=null){        if ("123456".equals(pwd)){            msg = "ok";        }else {            msg = "密码有误";        }    }    return msg;}

拦截器

SpringMVC中的拦截器类似于Servlet中的过滤器filter,用于对处理器进行预处理和后处理,开发者可以定义拦截器来实现特定的功能。

过滤器和拦截器的区别:拦截器是Aop思想的具体应用。

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置/*后,可以对所有要请求的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了该框架才可以使用
  • 拦截器只会拦截访问控制器的方法,访问静态资源不会拦截

搭建环境测试

application.xml

web.xml

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:applicationContext.xml
1
springmvc
/
encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encoding
/*

web下index.jsp

登录界面

首页

WEB-INF/jsp/login.jsp

用户名:
密码:

WEB-INF/jsp/main.jsp

<%--在WEB_INF下的所有界面,只能通过servlet或controller访问--%>

首页

${username}${pageContext.request.getSession("userinfo").getValue(username)}

注销

LoginController

package com.zr.controller;@Controller@RequestMapping("/user")public class LoginController {    @RequestMapping("/main")    public String main(){        return "main";    }    @RequestMapping("/gologin")    public String login(){        return "login";    }    @RequestMapping("/login")    public String login(String username, String password, HttpSession session, Model model){        //把用户的信息存在Session中        session.setAttribute("userInfo",username);        model.addAttribute("username",username);        System.out.println(model.getAttribute("username"));        return "main";    }    @RequestMapping("/goOut")    public String goOut(HttpSession session){        //把用户的信息删除        session.removeAttribute("userinfo");        return "main";    }}

配置拦截器LoginIntercepter

public class LoginIntercepter implements HandlerInterceptor {    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        System.out.println("登录拦截器==========");        HttpSession session = request.getSession();        //放行的判断        //登录页面要放行 包含login  即gologin和login        if (request.getRequestURI().contains("login")){            return true;        }        if (session.getAttribute("userinfo")!=null){            return true;        }        //判断什么情况下没有登录        System.out.println("返回登录页==========");        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);        return false;    }}

配置到application.xml中

文件上传

SpringMVC中配置CommonsMultipartResolver。

前端表单method设置为post,并将enctype设置为multipart/form-data。

对表单中enctype属性的详细说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的value属性值,采用这种编码方式的表单会将表单域中的值处理成URL编码方式。
  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的的内容也封装到请求参数中,不会对字符编码。
  • text/plain:除了把空格转化为 “+” 号外,其它字母都不做编码处理,这种方式适用直接通过表单发送文件。

在以上项目的pom文件中新增commons-fileupload,commons-io。

index.jsp

application.xml中增加文件上传配置

controller

package com.zr.controller;@RestControllerpublic class FileController {    //@RequestParam("file"),将name=file属性的文件封装成CommonsMultipartResolver对象    //批量上传CommonsMultipartFile    @RequestMapping("/upload")    public String Fileupload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {        //获取文件名        String uploadFileName = file.getOriginalFilename();        //如果文件名为空,直接回到首页        if ("".equals(uploadFileName)){            return "redirect:/index.jsp";        }        System.out.println("上传的文件名为:"+uploadFileName);        //上传路径保存设置        String path = request.getSession().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";    }}

上传方式二

@RequestMapping("/upload2")    public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {        //上传路径设置        String path = request.getSession().getServletContext().getRealPath("/upload");        File realPath = new File(path);        if (!realPath.exists()){            realPath.mkdir();        }        //上传文件地址        System.out.println("上传文件保存地址为:"+realPath);        //通过 的方法直接写文件(注意)        file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));        return "redirect:/index.jsp";    }

下载文件

@RequestMapping("/downLoad")public String downLoad(HttpServletResponse response,HttpServletRequest request) throws IOException {    //要下载的图片地址    String path = request.getSession().getServletContext().getRealPath("/upload");    String fileName = "1.jpg";    //设置respons响应头    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);    InputStream in = new FileInputStream(file);    ServletOutputStream out = response.getOutputStream();    //    int len = 0;    byte[] buffer = new byte[1024];    while ((len = in.read(buffer)) != -1) {        out.write(buffer, 0, len);        out.flush();    }    out.close();    in.close();    return null;}
上一篇:SpringBoot学习笔记
下一篇:Vue入门学习

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年04月26日 22时43分47秒