springmvc笔记

1、springmvc基础知识

1.1、什么是springmvc(what)

Spring为展现层提供的基于MVC设计理念的web框架,是目前最主流的MVC框架之一

1.2、为什么要使用springmvc(why)

它是一个典型的教科书式的mvc构架,而不像struts等都是变种或者不是完全基于mvc系统的框架,对于初学者或者想了解mvc的人来说我觉得 spring是最好的,它的实现就是教科书!

spring框架已经是java web开发很主流的框架,这个框架有很多优点当然也有它的不足之处,比于之前的servlet,它一定程度上简化了开发人员的工作,使用servlet的话需要每个请求都去在web.xml中配置一个servlet节点,而Spring 中的DispatcherServlet他会拦截所有的请求,进一步去查找有没有合适的处理器,一个前端控制器就可以。

1.3、怎样使用springmvc(how)

第二章,代码书写部分

1.4、springmvc知识点

  1. springmvc的工作流程
    在这里插入图片描述

过程说明:
1、 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
2、DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
3、DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
4、HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
6、DispatcherServlet将模型数据填充到视图中
7、DispatcherServlet将结果响应给用户

组件说明:

DispatcherServlet:前端控制器,也称为中央控制器,它是整个请求响应的控制中心,组件的调用由它统一调度。
HandlerMapping:处理器映射器,它根据用户访问的 URL 映射到对应的后端处理器 Handler。也就是说它知道处理用户请求的后端处理器,但是它并不执行后端处理器,而是将处理器告诉给中央处理器。
HandlerAdapter:处理器适配器,它调用后端处理器中的方法,返回逻辑视图 ModelAndView 对象。
ViewResolver:视图解析器,将 ModelAndView 逻辑视图解析为具体的视图(如 JSP)。
Handler:后端处理器,对用户具体请求进行处理,也就是我们编写的 Controller 类。

  1. @RequestMapping注解
  1. @RequestMapping注解使用在类上表示为此类中所有方法的请求路径添加了一个基准
@RequestMapping("/haha")
@Controller
public class MyFirstController {

   @RequestMapping("/hello")
   public String myfirstRequest(){
       //方法体
   }
}
//表示请求地址为/haha/hello才可访问到此方法,若只使用/hello访问不到此方法


  1. method属性:限定请求方式,只有请求使用的是method属性限定的方式才可以访问到此方法

在这里插入图片描述

3.produces属性:指定响应内容的类型,相当于规定响应头的Content - type
4. headers属性:规定请求头,用法:headers={“xxx”},请求头满足此属性才可以执行此方法
5. consumes属性:只接受内容为指定类型的请求,相当于规定请求头中的Content - type

  1. @PathVariable注解的使用

@RequestMapping注解的路径上可以使用占位符,用法:将某一层路径写为{变量名},如:
@RequestMapping("/user/{id}") 表示请求地址为/user/xxx访问到的是此方法
@PathVariable注解就是获取这个占位符的值

   @RequestMapping("/user/{id}")
   public String pathVariableTest(@PathVariable("id")String id){
       System.out.println("路径上的占位符的值"+id);
       return "xxx";
   }
//当浏览器的地址为/user/abc时,输出:路径上的占位符的值abc


  1. Resultful风格

用请求方式来区分对一个资源是CRUD中的哪一种:
如果是GET请求方式-----查询
如果是PUT请求方式------更新
如果是DELETE请求方式-----删除
如果是POST请求方式-----添加

步骤:

  1. 使用的时候需要配置一个过滤器
   <filter>
       <filter-name>HiddenHttpMethodFilter</filter-name>
       <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>HiddenHttpMethodFilter</filter-name>
       <!-- 拦截所有请求 -->
       <url-pattern>/*</url-pattern>
   </filter-mapping>


  1. 在index.jsp页面上进行配置
<!-- 发送GET请求 -->
<form action="book/1" method="get">
   <input type="submit" value="查询"/>
</form><br/>

<!-- 发送POST请求 -->
<form action="book/1" method="post">
   <input type="submit" value="添加"/>
</form><br/>

<!-- 发送DELETE请求 -->
<form action="book/1" method="post">
   <input name="_method" value="delete"/>
   <input type="submit" value="删除"/>
</form><br/>

<!-- 发送PUT请求 -->
<form action="book/1" method="post">
   <input name="_method" value="put"/>
   <input type="submit" value="更新"/>
</form><br/>



  1. 在controller类上进行配置
@Controller
public class BookController {
   
   //处理查询请求
   @RequestMapping(value="/book/{bid}",method=RequestMethod.GET)
   public String getBook(@PathVariable("bid")Integer id) {
       System.out.println("查询到了"+id+"号图书");
       return "xxx";
   }
   
   //处理删除请求
   @RequestMapping(value="/book/{bid}",method=RequestMethod.DELETE)
   public String deleteBook(@PathVariable("bid")Integer id) {
       System.out.println("删除了"+id+"号图书");
       return "xxx";
   }

   //处理更新请求
   @RequestMapping(value="/book/{bid}",method=RequestMethod.PUT)
   public String updateBook(@PathVariable("bid")Integer id) {
       System.out.println("更新了"+id+"号图书");
       return "xxx";
   }

   //处理添加请求
   @RequestMapping(value="/book",method=RequestMethod.POST)
   public String addBook() {
       System.out.println("添加了新的图书");
       return "xxx";
   }
}


  1. 如果出现了报错信息,那么需要在jsp页面的首部进行添加

在这里插入图片描述

  1. 自动封装类型使用
  1. 写出User类
package com.domain;

public class User {

    private String userName;
    private String password;
    private Integer age;

    public User() {
    }

    public User(String userName, String password, Integer age) {
        this.userName = userName;
        this.password = password;
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

2.配置一个index.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/addToList" method="post">
  姓名:<input name="userName" type="text"> <br />
  密码:<input name="password" type="password"> <br>
  年龄:<input name="age" type="text"> <br>
  <input type="submit" value="提交">
  <input type="reset" value="取消">

</form>
</body>
</html>

3.写出controller类

package com.controller;

import com.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

    /*
        进行前端页面数据的接受
     */
    @RequestMapping("/addToList")
    public String userView(User user, Model model){

        model.addAttribute("age", user.getAge());
        model.addAttribute("password",user.getPassword());
        model.addAttribute("userName", user.getUserName());
        return "UserView";
    }
}

  1. 运行并查看结果

在这里插入图片描述
在这里插入图片描述

  1. 参数传递问题

@RequestParam注解:此注解用来获取请求参数的值,默认情况下注解中声明的参数请求中必须携带,否则报错
方法中的注解表示:String username = request.getParameter(“user”);

对比一下:
@RequestParam获取的是请求参数的值 (地址中?之后的内容)
@PathVariable获取的是请求路径的值 (地址中?之前的内容)

  1. 解决中文乱码问题

在这里插入图片描述

我们会在web.xml文件中配置一个过滤器进行配置。

  1. 拦截器调用

SpringMVC提供了拦截器HandlerInterceptor,允许目标方法执行之前进行一些拦截工作,或者目标 方法执行之后进行一些其他处理
HandlerInterceptor是一个接口,其中的方法:
preHandle:目标方法执行之前自动调用;返回true,允许执行目标方法,返回false,不允许执 行目标方法
postHandle:目标方法执行之后自动调用
afterCompletion:整个请求过程完成,来到目标页面之后自动调用

  1. 返回值类型为ModelAndView类型
public ModelAndView mov1(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","消息");
        modelAndView.setViewName("HelloWorld");

        return modelAndView;
    }
  1. 重定向和转发

情况1:
在这里插入图片描述
情况2:
在这里插入图片描述
情况3:
在这里插入图片描述

  1. 文件上传

index.jsp

	<form method="post" enctype="multipart/form-data" action="/upload">
		用户头像:<input type = "file" name = "headerimg"/> <br/>
		用户名:<input type = "text" name = "username"/> <br/>
		<input type = "submit"/>
	</form>

dispatch-servlet.xml

	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 限制文件大小为20MB -->
		<property name="maxUploadSize" value="#{1024 * 1024 * 20}"></property>
		<!-- 设置默认编码格式 -->
		<property name="defaultEncoding" value="utf-8"></property>
	</bean>

controller

@Controller
public class FileUploadController {

	//MultipartFile封装了当前文件的信息	
	public String upload(String username, Model model, @RequestParam("headerimg") MultipartFile file) {
		//transferTo将文件下载到磁盘中
		//getOriginalFilename得到文件的名称
		try {
			//上传正常的情况
			file.transferTo(new File("G:\\haha\\" + file.getOriginalFilename()));
			model.addAttribute("msg", "文件上传成功!");
		}catch (IOException e) {
			//上传出错的情况
			model.addAttribute("msg", "文件上传失败!" + e.getMessage());
		}
		return "forward:/index.jsp";
	}
}

  1. 异常处理

全局异常

  1. 使用SimpleMappingExceptionResolver
    <bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <-- 默认的异常界面,如果不是特殊指定的异常,都显示这个界面 -->
        <property name="defaultErrorView" value="/exception/handle/errorGlobal" />
        <-- 异常的名称,界面上可以使用这个来输出异常信息 -->
        <property name="exceptionAttribute" value="e" />
        <-- 指定特殊异常,并为特殊异常指定特定的界面 -->
        <property name="exceptionMappings">
            <props>
                <prop
                    key="xyz.zeling.exception.handle.modules.exception.handle.UserNotFoundException">/exception/handling/errorUser</prop>
            </props>
        </property>
    </bean>
  1. @ResponseStatus方法

自定义类异常

//value属性指定状态码
@ResponseStatus(reason="用户被拒绝登陆",value=HttpStatus.NOT_ACCEPTABLE) 
public class UserNameNotFoundException extends RuntimeException {
	private static final long serialVersionUID = 1L;
}

创建一个处理器方法

	@RequestMapping("/handle02")
	public String handle02(@RequestParam("username") String username) {
		if (!"admin".equals(username)) {
			throw new UserNameNotFoundException();
			//如果出现异常会跳转至此异常指定的页面
		}
		return "success";
	}

  1. @ExceptionHandler注解的使用
	//注解中写上用来处理哪一种异常,多个用逗号隔开
	
	@ExceptionHandler(value = { NullPointerException.class })
	//方法中参数的异常对象用来接收发生的异常
	
	public ModelAndView handleException01(Exception exception) {
		
		//myerror是自定义的jsp页面(展示错误信息)
		ModelAndView view = new ModelAndView("myerror");
		view.addObject("ex", exception);
		
		return view; //出异常之后会跳转到自定义页面,而不是servlet的错误页面
	}
	
	//第二个处理异常的方法
	
	@ExceptionHandler(value = { Exception.class })
	public ModelAndView handleException02(Exception exception) {
		//执行其中的方法
	}
	
	//注:当类中有多个方法处理异常时,异常类型越精确的越优先

  1. 静态资源的处理:

在使用SSM框架做web开发时,遇到SpringMVC拦截了静态资源(如js,css,img等文件),导致jsp页面在浏览器上不能正常显示。

第一种方式:

<mvc:default-servlet-handler/>

第二种方式:

在这里插入图片描述

2、springmvc的代码书写

公共部分:

  1. 导入spring有关的jar:因为是idea创建,会自动下载有关的jar包。

在这里插入图片描述

  1. 修改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>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  1. 修改dispatch-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"
       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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!--    添加包扫描-->
    <context:component-scan base-package="com.controller"/>

<!--    开启注解-->
    <mvc:annotation-driven/>

<!--    拦截静态资源-->
    <mvc:default-servlet-handler/>

<!--    配置视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>


</beans>

2.1、我们创建一个简单的springmvc代码

  1. 创建一个controller类
@Controller
public class HelloController {

    @RequestMapping("/hello1")
    public String sayHello1(){
        System.out.println("这个是hello1的处理器");
        return "index";
    }
}

  1. 运行、查看结果

在这里插入图片描述

2.2、我们点击一个按钮或超链接跳转到一个页面中

  1. 创建一个demo2.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
     <a href="${pageContext.request.contextPath}/demo2_in">点我</a>
    <form action="${pageContext.request.contextPath}/demo2_out">
        <input type="submit" value="提交">
    </form>
</body>
</html>
  1. 编写controller类
package com.controller;

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

@Controller
public class Demo2 {

    @RequestMapping("/demo2_in")
    public String in(){
        System.out.println("这个是超链接跳转的结果");
        return "demo2_in";
    }

    @RequestMapping("/demo2_out")
    public String out(){
        System.out.println("这个是form表单跳转的结果");
        return "demo2_out";
    }
}

  1. 编写结果jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        这个是超链接返回的结果
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        这个是form表单跳转的 结果
</body>
</html>
  1. 查看结果

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

2.3、编写一个接受参数并返回给页面的代码

  1. 编写输入的jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/addToList" method="post">
  姓名:<input name="userName" type="text"> <br />
  密码:<input name="password" type="password"> <br>
  年龄:<input name="age" type="text"> <br>
  <input type="submit" value="提交">
  <input type="reset" value="取消">

</form>
</body>
</html>

  1. 编写controller类,实体类与之对应
package com.domain;

public class User {

    private String userName;
    private String password;
    private Integer age;

    public User() {
    }

    public User(String userName, String password, Integer age) {
        this.userName = userName;
        this.password = password;
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

package com.controller;

import com.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

    /*
        进行前端页面数据的接受
     */
    @RequestMapping("/addToList")
    public String userView(User user, Model model){

        model.addAttribute("age", user.getAge());
        model.addAttribute("password",user.getPassword());
        model.addAttribute("userName", user.getUserName());
        return "UserView";
    }
}

  1. 编写结果页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>这个是userView的界面</h1>
    姓名:${userName}
    年龄:${age}
    密码:${password}
</body>
</html>

  1. 查看运行结果

在这里插入图片描述
在这里插入图片描述

2.4、拦截器的使用

  1. 创建拦截器类
package com.intercept;

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

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

public class FirstIntercept implements HandlerInterceptor {

    @Override
    public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }
}

  1. 注册拦截器(dispatch-servlet.xml)
<!--    配置拦截器-->
    <mvc:interceptors>
        <bean class="com.intercept.FirstIntercept"></bean>
    </mvc:interceptors>
  1. 查看结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值