SpringMVC

SpringMVC

一、项目配置

1.web.xml配置

在这里插入图片描述

首先再web.xml中配置SpringMvc的前端控制器DispatcherServlet,对浏览器发送的请求进行统一处理

    <servlet>  
        <!-- 配置DispatcherServlet -->  
        <servlet-name>DispatcherServlet</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
            <!-- 指定spring mvc配置文件位置 不指定使用默认情况 -->  
            <init-param>     
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring/spring-mvc.xml</param-value>
            </init-param>  
        <!-- 设置启动顺序 -->  
        <load-on-startup>1</load-on-startup>  
    </servlet>

    <!-- ServLet 匹配映射 -->
    <servlet-mapping>
    <!-- 要与上面的servlet-name一致 -->
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

2. springmvc.xm配置

扫描包中的的组件,并配置thymeleaf视图解析器

<!--   扫描组件 -->
    <context:component-scan base-package="com.zzx.mvc"></context:component-scan>
<!--    开启mvc注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

<!--    thymeleaf视图解析器-->
    <!--    配置视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    
        <property name="characterEncoding" value="UTF-8"></property>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

总结:

在这里插入图片描述

二、基本注解

@RequestMapping

当浏览器发送请求到服务器,再通过DisPatcherServlet接收到请求之后,将请求地址和控制器方法所使用的注解@RequestMapping的value属性值进行匹配,如果能匹配成功当前的方法就是处理请求的方法,而再这个方法里返回的字符串配成为试图名称,再又试图解析器进行解析,并加上视图前缀和视图后缀找到相对应的html文件,最后再通过thymeleaf解析之后响应到浏览器。

1. @RequestMapping在方法上的话 value值是唯一的

@RequestMapping的位置 可以在类上也可以在方法名上

//这样浏览器匹配的请求就为 localhost:8080/zhixun/index/test
//在使用@RequestMapping时 必须要填写value值 否则会异常 报错 404
@Controller
@RequestMapping("/zhixun")
public class T{
	
	@RequestMapping("/index")
	public String index(){
		return "test";
	}
    
    // 源码 String[] value
    // 说明可以用多个不相同的请求 使用一个方法
    @RequestMapping(
    	value = {"index1","index2"}
    )
	public String index(){
		return "test";
	}
    
    
}
2. @RequestMapping的method属性

@RequestMapping的method属性通过请求方式(get / post)匹配请求映射

get: 在请求时,参数会拼接在请求地址后面,以问号进行拼接后面为&请求参数名=请求参数值,类似于(localhost:8080/index?id=1),get的参数是有限的,相比之下post的参数相当于无限。在文件上传中,是无法使用get请求的,因为是文件所以无法进行拼接,只会拼接文件名。

post: 在请求时不会将参数进行拼接,而是将参数放在请求体中,但在请求体中格式依然跟get一样name=value&name=value 。但是相比之下post请求比get请求更为安全。既然get不安全,所以在传输中get请求是比post请求速度快的,因为它是伴随着请求地址传过去的。

在form表单中 method只有get/post 如果想使用put/delete 需要导入RESTful API。

@Controller
@RequestMapping("/zhixun")
public class T{
	
    // 源码 String[] value
    // 说明可以用多个不相同的请求 使用一个方法
    @RequestMapping(
    	value = {"index1","index2"},
         // 源码 String[] method  
        //当满足value属性 缺不满足method属性 浏览器报错405错误,错误信息:Request method 'POST' not supported
        //在不写method属性的话 任何请求都允许匹配
        method = {"RequestMapping.GET,RequestMapping.POST"}
    )
	public String index(){
		return "test";
	}
    
    
}
image-20231009201710877
  1. PUT 请求
    • PUT 请求用于向服务器发送数据,以更新或创建资源。
    • 它通常用于更新指定的资源,客户端需要提供完整的资源表示,包括要更新的信息以及资源的标识。
    • 如果服务器已经有了指定标识的资源,PUT 请求会用新的数据替代旧的数据。
    • 如果服务器没有指定标识的资源,PUT 请求会创建一个新的资源。
    • PUT 请求是幂等的,多次调用相同的 PUT 请求应该产生相同的结果。
  2. DELETE 请求
    • DELETE 请求用于请求服务器删除指定的资源。
    • 它通常用于删除不再需要的资源,客户端需要提供要删除资源的标识。
    • 当服务器接收到 DELETE 请求时,它应该删除指定标识的资源,并返回成功的响应。
    • DELETE 请求也是幂等的,多次调用相同的 DELETE 请求应该产生相同的结果。

需要注意的是,PUTDELETE 请求不像 GETPOST 请求那样常见,通常用于特定的RESTful API或需要资源更新和删除的Web应用程序。此外,对于 DELETE 请求,需要谨慎使用,因为它会永久删除资源,可能导致数据丢失。在使用这些请求时,应该仔细考虑安全性和业务逻辑。

3. @RequestMapping的Params属性

@RequestMapping的params属性通过请求的请求参数匹配请求映射

@Controller
@RequestMapping("/zhixun")
public class T{
	
    // 源码 String[] value
    // 说明可以用多个不相同的请求 使用一个方法
    @RequestMapping(
    	value = {"index1","index2"},
         // 源码 String[] method  
        //当满足value属性 缺不满足method属性 浏览器报错405错误,错误信息:Request method 'POST' not supported
        //在不写method属性的话 任何请求都允许匹配
        method = {"RequestMapping.GET,RequestMapping.POST"}
        // 源码 String params
        //加了params属性就好比 localhost:8080/index?后面必须得有username这个属性且必须等于admin 否则匹配不上这个方法
        //如果是!username 那就是不能有username这个属性。
        //如果是!username=admin,那就是username属性必须不能等于admin 否则匹配不上
        //匹配不成功 报错信息 400
        params = {"username=admin"}
    )
	public String index(){
		return "test";
	}
    
    
}

thymeleaf测试

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
    <body>
    		<!-- 传Params的值 -->
        	<!-- localhost:8080/index?username=admin&password=123 -->
          <a th:href="@{/index(username='admin',password='123')}"></span>
          
    </body>
    
</html>

         
4. @RequestMapping的headers属性

@RequestMapping的params属性通过请求的请求头信息匹配请求映射 匹配不成功报错 404

5. @RequestMapping支持ant风格格式
?: 表示任意的当个字符
*: 表示任意的0个或者多个字符
**: 表示任意一层或者多层目录
注意: 在使用**时,只能使用/**/XXX的方式
@Controller
@RequestMapping("/zhixun")
public class T{
	
    // localhost:8080/a[任意的单个字符]a/test
    @RequestMapping(/a?a/testAnt")
	public String index(){
		return "test";
	}
    
    
}
6. SpringMVC支持路径中的占位符(重点!!)

原始方式: /delete?id=1

rest方式: /delete/1

SpringMVC路径中的占位符常用于result风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符(xxx)表示传输的数据,在通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参。

<a th:href="@{/zhixun/index/1/admin}">测试路径中的占位符</a>
@Controller
@RequestMapping("/zhixun")
public class T{
	
    // localhost:8080/a[任意的单个字符]a/test
    @RequestMapping(/index/{id}/{username}")
	public String index(@PathVariable("id") Integer id,@PathVariable("username") String username){
		return "test";
	}
    
    
}

三、SpringMVC获取请求参数

1. 通过servletAPI获取

将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文对象

@Controller
@RequestMapping("/zhixun")
public class T{
	
    // localhost:8080/a[任意的单个字符]a/test
    @RequestMapping(/index")
	public String index(HttpServletRequest request){
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
		return "test";
	}
    
    
}
2. 通过形参名字与请求名字一致
<a th:href="@{/zhixun/index(username = 'admin',password = '123')}">测试路径中的占位符</a>

当形参的名称和请求里的名称一样,可以直接获取

@Controller
@RequestMapping("/zhixun")
public class T{

    @RequestMapping(/index")
    // 如果获取的类型是数组(相同的名字却有多个值)可以通过数组,
    // 也可以通过String类型获取,如果是String类型的话,SpringMVC会自动用逗号隔开
	public String index(String username,String password){
        System.out.println("username" + username + ", " + "password" + password);
		return "test";
	}
    
    
}
3. 通过@RequestParams

当请求里的参数与方法中的形参不相同时,就无法使用第二种方法进行参数获取,此时我们可以使用@RequestParams注解将请求参数与方法中的形参进行绑定,从而获取到参数值。

@Controller
@RequestMapping("/zhixun")
public class T{

    @RequestMapping(/index")
    // 将请求参数和形参进行绑定
	public String index(
        // @RequestParams(value = "user_name",required = false)默认为true 必须传输
        // 就是说 当为false的时候不传user_name这个参数也可以正常运行
        // 也可以加一个defaultValue 当不传输时 会有一个默认值
        /// @RequestParams(value = "user_name",required = false,defaultValue="zhixun")
        @RequestParams("user_name") String username,
        @RequestParams("pwd") String password
    ){
        System.out.println("username" + username + ", " + "password" + password);
		return "test";
	}
    
    
}

4. 通过@RequestHeader
5. 通过@CookieValue

Session依赖于Cookie,Cookie是客户端的会话技术而session是服务端的会话技术。每当调用getsession方法的时候,就会创建一个key为JSessionID。

当第一次使用getSession方法时,Cookie会存在当前的响应报文中,因为在第一次进行getSession方法的时候,会先检测一下请求报文中是否含有JSessionIDCookie,如果没有就说明此次会话中第一次创建session对象。创建好的Cookie会存放在服务器中的Map集合,并创建一个keyJSessionID,值为随机序列的Map对象。还会将HttpSession对象存储到服务器维护的Map集合中,以及Cookie的值作Map集合的key,把session对象作为Map集合的值进行存储。最后在把cookie响应到浏览器。

6. 通过POJO获取请求参数

可以在控制方法中的形参位置写一个实体对象,此时若浏览器传输的请求参数的名称和实体类中的属性名一致,就会自动为此属性赋值

<form th:action="@{/index}" method = "post">
	用户名:<input type = "text" name="username"/>
	密  码:<input type = "text" name="pwd"/>
	<button type="submit"></button>
</form>
@Controller
public class T{
	
    @RequestMapping(/index")
    // User -> username,pwd
	public String index(User user){
        System.out.println("username" + user.getUserName() + ", " + "password" + user.getPwd());
		return "test";
	}
    
    
}
7. 乱码处理

get请求导致的乱码,需要去tomcat中修改

找到tomcat的安装路径下的config/server.xml文件

post请求导致的乱码,需要在web.xml中配置filter属性

在这里插入图片描述

四、域对象共享数据

application(当前服务器) > session(当前浏览器) > request(当前会话)

在session中有一个机制,钝化/活化

钝化:当我们服务器关闭了,浏览器没关闭说明会话在继续,我们存储在session中的数据会经过序列化到磁盘上。

活化:如果浏览器仍然没有关闭,但是服务器又重新开启了。它就会将钝化文件的内容重新读取到session中。

所以session中的数据跟服务器关闭没有关系,只跟浏览器关闭有关系。

1. 属于ServletAPI向request域对象共享数据
@RequestMapping("/index")
public String test(HttpServletRequest request){
	request.setAttribute("test","hhhh");
	return "index";
}
2. 使用ModelAndView向request域对象共享数据

@ReqestMapping("/index")
public ModelAndView test(){
	/*
	* ModeAndView又model和View功能
	* Model主要用于向请求域共享数据
	* View主要用于设置视图,实现页面跳转
	*/
	
	ModelAndView mav = new ModelAndView();
	// 向请求域共享数据
	mav.addObject("testScope","hello,ModelAndView");
	//设置视图,实现页面跳转
	mav.setViewName("success");
	return mav;
	
}

3. 使用形参的方式向request域对象共享数据
@ReqestMapping("/index")
public String test(Model model){
	/*
	* 用形参的方式,就不需要设置视图
	*/

	// 向请求域共享数据
	mav.addObject("testScope","hello,ModelAndView");
	return "success";
	
}
4. 使用map向request域对象共享数据
@ReqestMapping("/index")
public String test(Map<String,Object> map){
	/*
	* 用形参的方式,就不需要设置视图
	*/

	// 向请求域共享数据
	map.put("testScope","hello,ModelAndView");
	return "success";
	
}
5. 使用ModelMap向request域对象共享数据
@ReqestMapping("/index")
public String test(ModelMap modelMap){
	// 向请求域共享数据
	map.put("testScope","hello,ModelAndView");
	return "success";
	
}
6. Map/Model/ModelMap 底层实现

它们在向request域对象共享数据,都是通过BindingAwareModelMap实现的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

7. 向Session域中共享数据
  1. 第一种通过原生servletAPI的方式
@ReqestMapping("/testSession")
public String test(HttpSession session){
	// 向请求域共享数据
	session.setAttribute("testSessionScope","hhhh");
	return "success";
	
}
<p th:text="${session.testSessionScope}" />
  1. 通过@SessionAttributes注解
方式一:通过注解的value属性:

@Controller 
@SessionAttributes("user")	//将ModelMap中key为user的属性共享到session中
public class DemoController {
	@RequestMapping("/hello")  
	public String hello(ModelMap model) {
		//向ModelMap中添加key为user和user1的属性
        model.addAttribute("user", new User("zhixun", "hhhh"));
        return "result";
    }
}

方式二:通过注解的types属性:

@SessionAttributes(types = {User.class})
@Controller
public class DemoController{
    @RequestMapping("/hello")
    public String hello(Map<String, Object> map){
        map.put("user", new User("zhixun", "hhhh"));
        return "hello";
    }
}


8. 向application域中共享数据
@ReqestMapping("/testApplication")
public String test(HttpSession session){
	// 创建ServletContext对象
	ServletSession application = session.getServletContext();
	application.setAttribute("testSessionScope","hhhh");
	return "success";
	
}

五、SpringMVC视图

在这里插入图片描述

1. ThymeleafView

当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和后缀所得到最终路径,会通过转发的方式实现跳转。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. InternalResourceView 转发视图
@ReqestMapping("/testApplication")
public String test(HttpSession session){
	// 创建ServletContext对象
	ServletSession application = session.getServletContext();
	application.setAttribute("testSessionScope","hhhh");
	return "success";
	
}

@ReqestMapping("/index")
public String test(HttpSession session){
	// 通过forward进行转发资源
	return "forward:/testApplication";
	
}

3. 重定向视图

转发和重定向的区别:

转发:浏览器发送一次请求,转发是发送服务器内部的跳转,所以请求还是浏览器第一次的请求。转发可以获取请求域中的数据,重定向不可以。转发能访问WEB-INF中的请求,重定向不可以。转发不能跨越,重定向可以。因为转发是发送在服务器内部的,它只能访问服务器内部的资源,而重定向是浏览器发送的两次请求,浏览器可以访问任何资源。

重定向:浏览器发送了两次请求,第一次访问servlet,第二次访问重定向的请求。最终地址为重定向的地址。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4. 视图控制器view-controller

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示。

<!--
	在Spring-mvc.xml中配置
	path: 设置处理的请求地址
	view-name: 设置请求地址所对应的视图名称
-->

<!-- !!注意 如果在spring-mvc.xml中配置了 view-controller会导致 Controller类里面配置所有映射将全部失效-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>

<!-- !!必须添加,才能保证不失效 -->
<mvc:annotation-driven />

六、 RESTFul

1. RESTFul简介

在这里插入图片描述

2. RESTFul的实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. put请求

若想发送put请求,需要在web.xml文件中配置HiddenHttpMethodFilter过滤器

<!--  一定要放在在 编码配置后面 -->
<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>

七、 HttpMessageConverter

HttpMessageConverter,报文信息转换器,将请求报文转换为java对象,或将java对象转换为响应报文。HttpMessageConverter提供了两个注解和两个类型:@RequestBody,@ResponseBody,RequestEntity,ResponseEntity。

@RequestBody: 将请求报文转换为java对象。

@ResponseBody: 将java对象转换为响应体。

RequestEntity: 请求实体,可以接收整个请求报文(既可以接收请求头,也能接收请求体)。

ResponseEntity: 可将此对象转换为响应报文。

1. @RequestBody

@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值。

<form th:action="@{/testRequestBody}" method="post">
	用户名:<input type = "text" name = "username"><br>
	密码:<input type = "password" name = "password"><br>
	<input type="submit"/>
</form>
@ReqestMapping("/test")
	//@ResponseBody 将请求报文转换为java对象
public String test(@ResponseBody String requestBody){
	System.out.println("requestBody:" + requestBody);
	return "success";
	
}
//输出结果
requestBody:username=admin&password=123
2. RequestEntity

RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就会赋值给该形参,可以通过getHeaders()获取请求头信息,通过getBody()获取请求体信息

@ReqestMapping("/test")
	//@ResponseBody 将请求报文转换为java对象
public String test(RequestEntity<String> requestEntity){
    //requestEntity表示整个请求报文的信息
	System.out.println("requestHeader:" + requestEntity.getHeaders());
    System.out.println("requestBody:" + requestEntity.getBody());
	return "success";
	
}
//输出结果
requestBody:username=admin&password=123
3. @ResponseBody

@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器

@ReqestMapping("/test")
	//@ResponseBody 将请求报文转换为java对象
	//放回的值就是页面显示的数据
public String test(RequestEntity<String> requestEntity){
	return "success";
	
}
4. SpringMvc处理json
@ReqestMapping("/test")
	//@ResponseBody
	//返回的是user对象 直接返回会报500错误 需要转为json格式
public User test(RequestEntity<String> requestEntity){
	return "success";
	
}

需要加入依赖
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
</dependency>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实体类转json为json对象 list转json为json 数组

5. 处理ajax

请求超链接

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过vue和axios处理点击事件

6. @RestController注解

@RestController注解是springMvc提供的一个复合注解,标识在控制器类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponeseBody注解

7. @ResponseEntity

ResponseEntity用于控制器方法的返回值,该控制器方法的返回值就是响应到浏览器的响应报文。

器方法的返回值,该控制器方法的返回值就是响应到浏览器的响应报文。

八、文件上传和下载

1.文件下载

使用ResponseEntity实现下载文件的功能

文件下载:从服务器将文件给下载到客户端/浏览器端

文件上传: 从浏览器端上传到服务器端,但是不管是下载还是上传,底层都是文件赋值。

文件下载:

文件上传:
在这里插入图片描述

  1. 添加上传jar依赖

  2. 配置文件解释器

    在这里插入图片描述

  3. @RequestMapping("/testUp")
    //一定要配置文件解析器 通过id来进行匹配 
    //不配置 就无法接收MultipartFile这种类型
    //因没有文件服务器,所有只能传输到tomcat服务器,获取服务器需要session
    public String testUp(MultipartFile photo,HttpSession seesion) throws IOException{
        //获取上传文件的文件名
    	String fileName = photo.getOriginalFilename(); 
        //获取上传的文件的后缀名
        String suffixName = fileName.subString(fileName.lastIndexof("."));
        //将UUID作为文件名 防止相同名字文件互相覆盖
        String uuid = UUID.randomUUID().toString();
        //将UUID和后缀名拼接,做为最终的文件名
        fileName = uuid + suffixName;
        //通过ServletContext获取服务器中photo目录的路径
        ServletContext context = session.getServletContext();
        
        String photoPath = context.getRealPath("photo");
        File file = new File(photoPath);
        //判断photoPath路径是否存在
        if(!file.exists()){
            //若不存在,创建目录
            file.mkdir();
        }
        String finalPath = photoPath + File.separator + fileName;
        //资源转移
    	photo.transfetTo(new File(finalPath));
    
    }
    

九、拦截器

1. 拦截器的配置

public class FirstInterceptor implements HandlerInterceptor{
	
    //重写三种方法
    //controller方法之前执行
    public boolean preHandle(){}
    
     //controller方法之后执行
    public void postHandle(){}
    
     //视图渲染之后执行
    public void afterCompletion(){}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值