SpringMVC

基本介绍

SpringMVC是Spring这个框架的一个模块 即Web MVC

该模块对Servlet进行了封装 简化了Servlet操作 是Controller层的一个解决方案

代码实现

导包

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.1.3.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
    <scope>provided</scope>
</dependency>

配置spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.0.xsd">
​
 <context:component-scan base-package="com.qfedu.edu.controller" />
</beans>

配置web.xml

<web-app>
    <display-name>Archetype Created Web Application</display-name>
​
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
    </servlet>
​
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>
</web-app>

Controller

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/test.action")
    @ResponseBody
    public Object test(){
        return "buliyat....";
    }
}

测试

参数封装

键值对

@RequestMapping("/parameter01.action")
@ResponseBody
public Object parameter01(String username,String password){
    System.out.println("username:"+username+"---password:"+password);
    return "buliyat...";
}

对象

@RequestMapping("/parameter02.action")
@ResponseBody
public Object parameter02(User user){
    System.out.println("username:"+user);
    return "buliyat...";
}

数组

@RequestMapping("/parameter03.action")
@ResponseBody
public Object parameter03(String[] habbits){
    System.out.println("username:"+ Arrays.toString(habbits));
    return "buliyat...";
}

集合

@RequestMapping("/parameter04.action")
@ResponseBody
public Object paramete0r5(UserList userList){ // private List<User> users;
    System.out.println("user:"+ userList);
    return "buliyat...";
}
<form action="/user/parameter04.action" method="post">
    用户名:<input type="text" name="users[0].username"> <br>
    密码:<input type="text" name="users[0].password"> <br>
​
    用户名:<input type="text" name="users[1].username"> <br>
    密码:<input type="text" name="users[1].password"> <br>
​
    用户名:<input type="text" name="users[2].username"> <br>
    密码:<input type="text" name="users[2].password"> <br>
    <input type="submit" name="提交"> <br>
</form>

同址异参

@RequestMapping("/parameter05.action")
@ResponseBody
public Object parameter05(UserAndAdmin userAndAdmin){
    System.out.println("user:"+ userAndAdmin.getUser());
    System.out.println("admin:"+ userAndAdmin.getAdmin());
    return "buliyat...";
}
用户数据:<br>
<form action="/user/parameter05.action" method="post">
    用户名:<input type="text" name="user.username"> <br>
    密码:<input type="text" name="user.password"> <br>
    <input type="submit" name="提交"> <br>
</form>
​
管理员数据:<br>
<form action="/user/parameter05.action" method="post">
    用户名:<input type="text" name="admin.username"> <br>
    密码:<input type="text" name="admin.password"> <br>
    <input type="submit" name="提交"> <br>
</form>

JSON

@RequestMapping("/parameter06.action")
@ResponseBody
public Object parameter06(@RequestBody User user){
    System.out.println("user:"+ user);
    return new User(1,"buliyat","123");
}
<!-- 配置消息转换器 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <!-- 返回一个字符串非Java对象的时候使用的消息转换器 -->
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes" value="text/plain;charset=UTF-8"/>
        </bean>
        <!-- 返回Java对象转换成JSON格式的时候使用的消息转换器 -->
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes" value="application/json;charset=UTF-8"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

返回值

Jsp页面

@RequestMapping("/back01.action")
public String back01(){
    return "/buliyat.jsp";
}
@RequestMapping("/back02.action")
public void back02(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.getRequestDispatcher("/buliyat.jsp").forward(req,resp);
}

转发和重定向

@RequestMapping("/back01.action")
public String back01(){
    return "redirect:http://www.baidu.com"; // 重定向
}
@RequestMapping("/back02.action")
public String back02(){
    return "http://www.baidu.com";  // 转发
}
Model
@RequestMapping("/back01.action")
public String back01(Model model){
    model.addAttribute("username","buliyat");
    return "/buliyat.html";
}

ModelAndView

@RequestMapping("/back01.action")
public ModelAndView back01(ModelAndView modelAndView){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("/buliyat.html");
    model.addAttribute("username","buliyat");
    return ModelAndView;
}

JSON

@RequestMapping("/back01.action")
@ResponseBody
public Object back01(){
    return new User(1,"buliyat","123");
}

方法约束

@GetMapping         // 只能使用get方法请求
@PostMapping        // 只能使用post方法请求
@PutMapping         // 只能使用put方法请求
@DeleteMapping      // 只能使用delete方法请求
@ResponseBody       // 返回格式为JSON
public String method01(){
    return "/buliyat.jsp";
}

拦截器

Intercepter(Spring Web MVC)

public class MyInterceptor implements HandlerInterceptor {
​
    // 控制器方法执行前 认证 鉴权
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        System.out.println("------------preHandle------------");
        return true;
    }
​
    // 控制器方法执行后 干预结果
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
        modelAndView.addObject("username","铁蛋");
        System.out.println("------------postHandle------------");
    }
    
    // 控制器方法出现异常时
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (ex != null) {
            System.out.println("------------afterCompletion------------");
        }
    }
}
​
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/user/**"/>
        <mvc:exclude-mapping path="/user/method01.action"/>
        <mvc:exclude-mapping path="/user/method01.action"/>
        <bean class="com.qcy.buliyat.interceptor.MyInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

Intercepter(Spring Framework)

public class MyWebRequestInterceptor implements WebRequestInterceptor {
​
    public void preHandle(WebRequest webRequest) throws Exception {
        System.out.println("--MyWebRequestInterceptor----preHandle--------");
    }
​
    public void postHandle(WebRequest webRequest, ModelMap modelMap) throws Exception {
        System.out.println("--MyWebRequestInterceptor----postHandle-------");
        
    public void afterCompletion(WebRequest webRequest, Exception e) throws Exception {
        if (e != null) {
            System.out.println("--MyWebRequestInterceptor----afterCompletion-");
        }
    }
}
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/dept/add.action"/>
        <bean class="com.qcy.buliyat.interceptor.MyWebRequestInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

全局异常

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:bean-*.xml</param-value>
</context-param>
​
<listener>
    <listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       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
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
       ">
​
    <!-- 设置扫描的包 -->
    <context:component-scan base-package="com.buliyat.qcy" />
</beans>

全局异常

@Component
public class GlobleException implements HandlerExceptionResolver {
​
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse resp, Object o, Exception e) {
​
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 100);
        jsonObject.put("message", "出现异常了");
​
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = null;
        try {
            writer = resp.getWriter();
            writer.write(jsonObject.toJSONString());
            writer.flush();
            writer.close();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        return null;
    }
}

上传下载

上传

导包

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

spring-mvc.xml

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"></property>
    <property name="maxUploadSizePerFile" value="100000000"></property>
    <property name="maxUploadSize" value="200000000000"></property>
</bean>

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <form action="/user/fileUpload.action" method="post" enctype="multipart/form-data">
​
            用户名:<input type="text" name="username"> <br>
            密  码:<input type="text" name="password"> <br>
            头  像:<input type="file" name="file"> <br>
​
            <input type="submit" name="提交"> <br>
        </form>
        <hr/>
    </body>
</html>

Controller

@PostMapping("/fileUpload.action")
@ResponseBody
public Object fileUpload(@RequestParam("file") MultipartFile file,User user) throws IOException {
    System.out.println("用户数据:" + user);
    file.transferTo(new File("G:\\buliyat.png"));
    return "文件上传成功";
}

下载

@RequestMapping("/moethod01.action")
public void moethod01(HttpServletResponse resp) throws IOException {
    resp.setHeader("Content-Disposition","attachment;filename=xxxx.jpg");
    File file = new File("G:\\buliyat.png");
    
    FileInputStream in = new FileInputStream(file);
    ServletOutputStream out = resp.getOutputStream();
    
    byte[] buf=new byte[8192];
    int length=0;
    while ((length=in.read(buf))!=-1){
        out.write(buf,0,length);
    }
    
    in.close();
    out.close();
}
@RequestMapping("/moethod02.action")
public ResponseEntity<byte[]> moethod02() throws IOException {
    HttpHeaders httpHeaders=new HttpHeaders();
    httpHeaders.add("Content-Disposition","attachment;filename=xxxx.jpg");
    return new ResponseEntity<byte[]>(FileCopyUtils.copyToByteArray(new File("G:\\buliyat.png")),httpHeaders, HttpStatus.OK);
}

前置后置

前置处理

@ControllerAdvice
public class MyRequestBodyAdviser implements RequestBodyAdvice {
​
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }
​
    // RequestBody之前执行
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        System.out.println("解密了.....");
        return httpInputMessage;
    }
​
    // RequestBody之后执行
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        System.out.println("已经将JSON转换成了Java对象之后 执行的方法");
        return o;
    }
​
    // 传递了空参数
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
}

后置处理

@ControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice {
​
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return true;
    }
​
    // ResponseBody之后执行
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        System.out.println("返回数据加密了....");
        return o;
    }
}

运行原理

  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。

  2. DispatcherServlet 根据请求信息调用 HandlerMapping 。HandlerMapping 根据 URL 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。

  3. DispatcherServlet调用 HandlerAdapter适配器执行 Handler 。

  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给DispatcherServlet,`ModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。Model 是返回的数据对象,View 是个逻辑上的 View。

  5. ViewResolver 会根据逻辑 View查找实际的 View。

  6. DispaterServlet 把返回的 Model传给 View(视图渲染)。

  7. 把 View 返回给请求者(浏览器)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值