Springmvc总结


1、springmvc是什么?

springmvc全称是spring web mvc,是spring框架一部分,是专门做web开发的。主要把业务逻辑从界面中解耦,降低耦合度。

2、springmvc架构原理

 原理简写:DispatcherServlet-->映射器-->适配器-->视图解析器-->页面

3、springmvc入门

项目地址:https://github.com/zhongyushi-git/spring-collection.git。下载代码后,示例代码在maven-springmvc-demo文件夹下。

3.1 导入依赖

新建一个maven的web项目,在pom.xml导入

properties>
    UTF-8
    1.8
    1.8
    5.3.4
  

  
    
      junit
      junit
      4.11
      test
    
    
      commons-logging
      commons-logging
      1.1.1
    
    
      org.springframework
      spring-beans
      ${spring.version}
    
    
      org.springframework
      spring-context
      ${spring.version}
    
    
      org.springframework
      spring-core
      ${spring.version}
    
    
      org.springframework
      spring-expression
      ${spring.version}
    
    
      org.springframework
      spring-web
      ${spring.version}
    
    
      org.springframework
      spring-webmvc
      ${spring.version}
    
    
      javax.servlet
      servlet-api
      2.5
    
    
      javax.servlet
      jsp-api
      2.0
    
  

3.2编写配置文件

1)编写web.xml

在web.xml中配置如下内容:

        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >




DispatcherServlet
org.springframework.web.servlet.DispatcherServlet


contextConfigLocation
classpath:springmvc.xml



DispatcherServlet
/

其中servlet是用来拦截请求,交给spring管理;init-param来加载配置文件;url-pattern常用/。

2)编写springmvc.xml

在src目录下创建springmvc.xml文件,引入如下约束信息:


<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

3.3开发Controller类

新建包com.zxh.controller,包下创建一个HelloController类,来处理请求,相当于servlet。


package com.zxh.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloController2 implements Controller {

@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test");//设定视图,相对的是web
return modelAndView;
}
}

3.4新建页面并配置

1)在webapp下新建views文件夹,在文件夹下新建test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


你好啊

2)配置视图解析器

在springmvc.xml中配置视图解析器,代码如下:

 
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        "prefix" value="/views/">
        "suffix" value=".jsp">
    

3.5使用xml方式配置接口

在springmvc.xml中配置:










hello


配置后添加tomcat并启动,在浏览器访问http://localhost:8080/maven_springmvc_demo_war/hello看到test.jsp编写的内容,说明xml配置成功。

3.6使用注解方式配置接口

除了上面xml方式外,还可以使用注解方式。

1)在springmvc.xml配置

以上代码可以简写为两行:




2)开发controller类

然后新建一个HelloController类:

package com.zxh.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController2 {

@RequestMapping("/hello2")
public ModelAndView hello(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test");
return modelAndView;
}
}

3)配置后添加tomcat并启动,在浏览器访问http://localhost:8080/maven_springmvc_demo_war/hello2看到test.jsp编写的内容,说明xml配置成功。

3.7其他配置

1.编码处理:设置一个编码过滤器,参数等不在乱码。web.xml中配置:


    CharacterEncodingFilter             
  class>org.springframework.web.filter.CharacterEncodingFilterclass> encoding utf-8 forceEncoding true
CharacterEncodingFilter /*

4、参数绑定

4.1什么是参数绑定

springmvc接收请求的key/value串(比如:id=2&type=101),经过类型转换,将转换后的值赋值给controller方法的形参,这个过程就叫参数绑定。

4.2默认支持的类型

在controller方法形参中如下类型是可以直接绑定成功,springmvc框架给以下类型的参数直接赋值:

HttpServletRequest:通过request对象获取请求信息

HttpServletResponse:通过response处理响应信息

HttpSession:通过session对象得到session中存放的对象

4.3简单数据类型参数绑定

1)简单数据类型

Integer、string、boolean、float等

2)绑定规则

当请求的参数的名称和controller方法的形参名一致时可以绑定成功。

3)绑定的注解

@RequestParam:取别名

@RequestBody:把请求体中的数据封装到对象中,请求体中的内容必须是json格式。

@Valid:数据校验,如验证对象的某一属性是否为空。

如果每个方法都有返回值,那么可以在这个类的上面添加@RestController,它其实是@Controller+@ResponseBody的组合。它的返回值已经是json格式的数据了。

4)数据验证案例:验证前端传入的对象的密码是否是空

第一步:添加需要的依赖


            org.projectlombok
            lombok
            1.18.18
        
        
            javax.validation
            validation-api
            2.0.1.Final
        
        
            org.hibernate
            hibernate-validator
            5.3.6.Final
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.10.0
        
        
            com.fasterxml.jackson.core
            jackson-core
            2.10.0
        
        
            com.fasterxml.jackson.core
            jackson-annotations
            2.10.0
        

第二步:创建User对象并在实体类的密码属性上加注解

package com.zxh.entity;

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;


@Data
public class User {
@NotBlank
private String username;

private String password;
}

第三步:创建UserController并在controller的方法里面加注解和错误判断

package com.zxh.controller;

import com.zxh.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;
import java.util.List;

@Controller
public class UserController {


@RequestMapping(value = "/add",method = RequestMethod.POST)
public void add(@Valid @RequestBody User user, BindingResult errors) {
//是否验证不通过
if (errors.hasErrors()) {
List allErrors = errors.getAllErrors();
for (ObjectError err : allErrors) {
System.out.println(err);
}
} else {
System.out.println(user);
}
}
}

使用postman使用post请求发送json数据,当username没有传值时就会打印错误信息。

  5)别名绑定

如果请求的参数的名称和controller方法的形参名不一致时,如何绑定?就要使用@RequestParam进行绑定。

加入传递的参数是id,而接收的参数是ids,要@RequestParam将请求的参数名为ids的值绑定方法形参的id上,Value可以省略。

@RequestMapping("/get")
public void get(@RequestParam(value = "id") int ids) {
System.out.println(ids);
}

6)多个参数绑定

多个参数就直接把参数的名称和类型列举出来。

@RequestMapping("/get2")
public void get2(String username, String password) {
System.out.println(username + " " + password);
}

4.4简单pojo参数绑定

简单pojo:pojo中都基本类型,如上述的User对象,已经举例,在此略。

4.5包装pojo类型

一个类中不仅有简单数据类型,还有对象属性。那么页面需要使用相应的类标识属性名,如下:

"get" action="add2"> "text" name="name"> "text" name="user.username"> "text" name="user.password"> "submit">

实体类

package com.zxh.entity;

@Data
public class OtherUser { private String name; private User user; }

获取内容

@RequestMapping("/add2")
public void login5(OtherUser otherUser){
    System.out.println(otherUser);
}

4.6数组类型参数绑定

"get" action="add3"> "checkbox" name="hobby" value="篮球">篮球 "checkbox" name="hobby" value="足球">足球 "checkbox" name="hobby" value="羽毛球">羽毛球 "submit">

获取选中的内容

@RequestMapping("/add3")
public void login3(String[] hobby){
    for (String s : hobby) {
        System.out.println(s);
    }
}

5、RequestMapping的设置

requestMapping注解的作用:对controller方法进行映射。

5.1通用映射

URL路径映射:requestMapping指定url,对controller方法进行映射,如@RequestMapping("/login")  

为了更好的管理url,为了避免url冲突,可以在类上再使用requestMapping指定根url,如下,使用/user/login进行访问:

@Controller
@RequestMapping("/user")
public class UserController {
  @RequestMapping(
"/login")   public void login2(User user){   System.out.println(user);   }
}

5.2限定请求方法

 通过requestMapping的method限制http的请求方法,可以提高系统安全性,只允许通过指定的请求才能访问,如下代码指定只能通过get请求访问:

@RequestMapping(value="/login",method = RequestMethod.GET)
public void login(String username,String password){
    System.out.println(username+" "+password);
}

不过一般不使用这种方式,即它有优化后的用法。

映射的注解 说明
@GetMapping 只接受get请求,用于查询
@PostMapping 只接受post请求,用于添加
@PutMapping 只接受put请求,用于修改
@DeleteMapping 只接受delete请求,用于删除

后期都会使用这种方式进行开发。

6.Controller方法返回值

6.1返回ModelAndView

controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定逻辑视图名。在入门案例就已介绍,在此略。

6.2返回Void

这样方式类似原始serlvet 的开发。响应结果有三种方法:

1)使用request转发页面,如下:request.getRequestDispatcher("index.html").forward(request, response);

2)通过response页面重定向:response.sendRedirect("url")

3)通过response指定响应结果,例如响应json数据如下:

response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");

6.3返回String(推荐使用)

1)页面转发方式:格式是forward:转发地址(不能写http://,只能写action的地址)。特点是转发的上一个请求request和要转发的地址共用request,转发后浏览器的地址是不变化。

@RequestMapping("/login")
public String login1(){
return "forward:views/login.jsp";
}

2)页面重定向方式:格式是redirect:重定向地址(比如:http://.....)。特点是重定向的上一个请求request和要重定向的地址不共用request,重定后浏览器的地址是变化的。

@RequestMapping("/login2")
public String login2(){
return "redirect:views/login.jsp";
}

3)表示逻辑视图名:返回一个string,如果即不是转发格式,也不是重定向的格式,就表示一个逻辑视图名。这里并没有写login.jsp,原因是在springmvc.xml中已经配置了视图解析器的前缀和后缀。

@RequestMapping("/login3")
public String login3(){
    return "login";
}

可以看出,重定向和页面转发都需要指定页面的全路径,页面后缀不能省略,而第三种方式就简单很多。

7.Springmvc文件上传

7.1导入依赖

在pom.xml加入

     
            commons-fileupload
            commons-fileupload
            1.3.2
        

7.2编写页面

1)编写文件上传的页面upload.jsp。在webapp下新建upload.jsp,内容如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    文件上传


    
    
"upload" enctype="multipart/form-data" method="post"> "file" name="file"> "submit">

2)编写上传提示的页面success.jsp。在views目录下新建success.jsp,内容如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    上传提示


文件上传成功

7.3创建controller

新建UploadController类,作为文件上传的接口

package com.zxh.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
public class UploadController {

    @RequestMapping("/upload")
    public String upload(MultipartFile file) throws IOException {
        //多文件上传MultipartFile[] file,遍历这个数组
        if (file != null && file.getOriginalFilename() != null && !file.getOriginalFilename().equals("")) {
            //获取文件的名字
            String fileName = file.getOriginalFilename();
            //获取文件的后缀名
            int index = fileName.lastIndexOf(".");
            //UUID这个方法是给文件命名,不重名
            String newFileName = UUID.randomUUID() + fileName.substring(index);
            File NewFile = new File("D:\\upload", newFileName);
            //把上传的文件的内容保写到保存的位置
            file.transferTo(NewFile);
        }
        return "success";

    }
}

需要注意,指定的路径是D:\\upload,此路径必须存在,否则会报错。

7.4配置文件解析器

在springmvc.xml中配置文件解析器



    
    
        5242880
    

启动项目,访问http://localhost:8080/maven_springmvc_demo_war/upload.jsp上传一张图片,会提示上传成功。

8.处理json数据

处理json数据需要用到两个注解@RequestBody和@ResponseBody。@RequestBody注解将json数据转成java对象 ,@ResponseBody注解实现将java对象转成json输出。

对于@RequestBody在前面参数绑定的章节已经使用过了,在此略,不过需要注意的是,必须导入处理json数据的依赖,如jackjson、falstjson。主要讲解@ResponseBody的作用。

8.1@ResponseBody的作用

在前面的controller中,我们都使用string返回的是视图或页面,那么能不能直接返回文字信息呢?当然这就是ResponseBody的作用了,且看下面的代码说明。

8.2处理器映射器和适配器

修改springmvc.xml文件,把标签修改如下



    "true">
        class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            "supportedMediaTypes" value="application/json"/>
            "features">
                
                    WriteMapNullValue
                    WriteDateUseDateFormat
                
            
        
    

8.3创建测试的接口

在HelloController2类中加入两个方法

  @ResponseBody
    @RequestMapping(value = "/hello3", produces = "text/html;charset=UTF-8")
    public String hello3() {
        return "你好啊,ResponseBody";
    }

    @ResponseBody
    @RequestMapping(value = "/hello4")
    public User hello4() {
        User user = new User();
        user.setPassword("123");
        user.setUsername("傻子");
        return user;
    }

这两个方法分别返回string类和对象类型,返回string类型时如有中文,需设置编码,否则访问时中文显示的是?。而返回对象类型就不需要,也是推荐的用法。分别访问这两个方法,可以看到返回的数据。

8.4注解优化

加入一个controller中的所有方法只是返回一个需要的对象,而不是页面,那么对于每个方法都加@ResponseBody也是可以的,但是显得非常的麻烦,这时就可以使用@RestController这个注解。它放在类上,那么就表明此类中的所有方法都返回json数据而不是页面,不能页面跳转。它等于@Controller+@ResponseBody,是不是简化了很多。

@RestController
public class HelloController2 {


    @RequestMapping(value = "/hello3", produces = "text/html;charset=UTF-8")
    public String hello3() {
        return "你好啊,ResponseBody";
    }

    @RequestMapping(value = "/hello4")
    public User hello4() {
        User user = new User();
        user.setPassword("123");
        user.setUsername("傻子");
        return user;
    }
}

9.springmvc对rest的支持

RESTful,即Representational State Transfer的缩写,表现层状态转化。所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。

9.1基本操作

1)GET用来获取资源,对应GetMapping。

2)POST用来新建资源(也可以用于更新资源),对应PostMapping

3)PUT用来更新资源,对应PutMaping(不常用)

4)DELETE用来删除资源。对应DeleteMapping

9.2 url模板映射

@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

映射的格式是@RequestMapping(value="/ user/{id}"):{×××}占位符,请求的URL可以是“/user/1”或“/user/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。其用法如下模板:

@GetMapping("/user/{abc}")
public void add(@PathVariable("abc") int id){
    System.out.println("获取数据"+id);
}

@PostMapping("/user/{abc}")
public void delete(@PathVariable("abc") int id){
    System.out.println("新建数据"+id);
}
@PutMapping(
"/user/{abc}") public void update(@PathVariable("abc") int id){ System.out.println("更新数据"+id); }
@DeleteMapping(
"/user/{abc}") public void newRes(@PathVariable("abc") int id){ System.out.println("删除数据"+id); }

注意事项:使用restful时,web.xml中url-pattern必须是/,不能是其他的,那么这样又会拦截一些需要的静态资源,所以需要在springmvc.xml中配置来加载静态资源:

mapping代表映射文件目录,**表示当前以及子类的所有文件夹,*只是当前文件夹。

"/js/**" location="/js/">
"/css/**" location="/css/">

10.springmvc拦截器

10.1拦截器的作用

springmvc提供拦截器实现对Handler进行面向切面编程,可以Handler执行之前、之后、之中添加代码,这种方式就是切面编程。可以拦截静态资源和请求的接口,不能拦截jsp页面。需要使用过滤器来拦截jsp页面。

10.2使用拦截器步骤

1)定义一个类实现HanlderInterceptor接口,此代码作为参考示例,后面会添加业务逻辑

package com.zxh.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class MyIntercept implements HandlerInterceptor {
//preHandle:在Handler执行之前调用
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("pre...");
//return true代表放行
//return flase代表拦截

return true;
}

//postHandle:在Handler中方法执行一半时调用(return ModelAndView前),可以更改跳转的视图
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("post...");
}

//afterCompletion:在Handler执行完毕之后调用,可以用于异常的处理
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("after...");
}
}

2)在springmvc.xml中配置拦截器










11.springmvc过滤器

11.过滤器的作用

springmvc过滤器可以过滤所有的请求,范围大,但有局限性。获取不到session的值。

11.2使用拦截器步骤

1)定义一个类实现HanlderFilter接口,此代码作为参考示例,后面会添加业务逻辑

package com.zxh.config;


import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {

    }

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

    @Override
    public void destroy() {

    }
}

2)在web.xml中配置

    
        loginFilter
        class>com.zxh.config.MyFilterclass>
    
    
        loginFilter
        /
    

11.3过滤器与拦截的差异

相同点:都可以拦截请求,过滤请求,应用了过滤器(责任链)设计模式。。

不同点:filter范围比较大,在web.xml中配置;intercepter范围比较小,在springmvc.xml中配置。在进入springmvc处理之前会先处理web.xml的配置,因此会先进入过滤器,故此时获取不到session中的值,只能是拦截器中获取。

13、SSM框架整合

 dao层:mybatis+spring

service层:spring

controller层:springmvc+spring

 整合步骤:

  1. 新建一个web项目,在WEB-INF目录下创建一个lib目录,为它添加包依赖
  2. 导入所有的jar包到lib中
  3. 在根目录下新建一个config目录,设置为资源目录,用于存放配置文件
  4. 把所有需要的配置文件放到config目录中,修改部分配置
  5. 在web.xml配置加载spring容器
  6. 新建所有的类和接口进行测试

相关