当前位置: 首页 > news >正文

SpringMVC学习使用

在这里插入图片描述

一、SpringMVC简单理解

1.1 Spring与Web环境集成

1.1.1 ApplicationContext应用上下文获取方式

应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。

在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。

1.1.2 Spring提供获取应用上下文的工具

上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。

所以我们需要做的只有两件事:

①在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)

②使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

1.1.3 导入Spring集成web的坐标

        <!-- spring必要依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><!-- spring web依赖注意使用mvc后倒入webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.2</version></dependency><!--Jsp坐标--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version></dependency><!-- Servlet坐标 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency>

1.1.4 配置ContextLoaderListener监听器

 <!--全局参数-->
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的监听器-->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

1.1.5 通过工具获得应用上下文对象

@WebServlet(name = "TestServlet", value = "/test")
public class TestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = request.getServletContext();WebApplicationContext spring = WebApplicationContextUtils.getWebApplicationContext(servletContext);System.out.println(spring.getBean("user"));}
}

知识要点

Spring集成web环境步骤

①配置ContextLoaderListener监听器
②使用WebApplicationContextUtils获得应用上下文
③spring-web提供的监听器spring-webmvc页提供(同时使用会冲突)

1.2 SpringMVC的简介

1.2.1 SpringMVC概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

通过属性java类交由spring容器管理,通过注解定义url实现对应的方法执行,简化了servlet定义与书写

1.2.2 SpringMVC简单实现

使用servlet进行控制层处理每一个请求都需要书写一个servlet,每个servlet只修改处理请求的方法与名称,其余没有修改,springMVC可以看做提供了一个中央控制器对这些servlet进行统一的分发管理并简化servlet的书写

①将所有的方法书写在一个java类中 并书写相应地址映射

import java.util.HashMap;//将所有需要执行的方法书写在当前类中
public class AllController {HashMap<String,String> map=new HashMap<>();public void a(){System.out.println("a方法执行");}public void b(){System.out.println("b方法执行");}
}

②书写核心控制器(应该是处理所有请求的servlet)

@WebServlet("/*")
public class AllServlet extends HttpServlet {AllController allController=new AllController();@Overridepublic void init() throws ServletException {HashMap<String, String> map = allController.map;map.put("/day0924/a","a");map.put("/day0924/b","b");}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取实际请求的uriString requestURI = request.getRequestURI();System.out.println("requestURI:"+requestURI);HashMap<String, String> map = allController.map;String methodName = map.get(requestURI);//通过反射调用对应方法Class<AllController> allControllerClass = AllController.class;try {Method declaredMethod = allControllerClass.getDeclaredMethod(methodName);//执行对应方法declaredMethod.invoke(allController);} catch (Exception e) {}}
}

1.2.3 SpringMVC快速入门

需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

开发步骤

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

代码实现

①导入Spring和SpringMVC的坐标、导入Servlet和Jsp的坐标

 <!--Spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.8.RELEASE</version></dependency><!--SpringMVC坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.8.RELEASE</version></dependency><!--Jsp坐标--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version></dependency><!-- Servlet坐标 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency>

②在web.xml配置SpringMVC的核心控制器与spring加载监听器

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!-- 配置springmvc前端控制器 --><servlet><servlet-name>springmvc</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>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

③创建Controller和业务方法

public class UserController {public ModelAndView select(ModelAndView mv,HttpServletRequest request){request.setAttribute("msg","查找返回的数据");mv.setViewName("/index.jsp");return mv;}public String update(ModelAndView mv,HttpServletRequest request){request.setAttribute("msg","更新返回的数据");return "/index.jsp";}
}

③创建视图页面index.jsp

<html>
<body><h2>Hello SpringMVC!</h2>${msg}
</body>
</html>

④配置注解

@Controller
@RequestMapping("/user")
public class UserController {@RequestMapping("/select.do")public ModelAndView select(ModelAndView mv,HttpServletRequest request){request.setAttribute("msg","查找返回的数据");mv.setViewName("/index.jsp");return mv;}@RequestMapping("/update.do")public String update(ModelAndView mv,HttpServletRequest request){request.setAttribute("msg","更新返回的数据");return "/index.jsp";}
}

⑤创建spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"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"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置注解扫描--><context:component-scan base-package="com.yunhe.controller"/>
</beans>

二、SpringMVC常用功能与使用

2.1 SpringMVC的执行流程

在这里插入图片描述

①用户发送请求至前端控制器DispatcherServlet。
②DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
④DispatcherServlet调用HandlerAdapter处理器适配器。
⑤HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
⑥Controller执行完成返回ModelAndView。
⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ViewReslover解析后返回具体View。
⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

2.1.1 SpringMVC组件解析

  1. 前端控制器:DispatcherServlet
    ​ 用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

  2. 处理器映射器:HandlerMapping
    ​ HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

  3. 处理器适配器:HandlerAdapter

​ 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

  1. 处理器:Handler
    ​ 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。

  2. 视图解析器:View Resolver
    ​ View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

  3. 视图:View
    ​ SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

2.1.2 SpringMVC注解解析

@RequestMapping
作用:用于建立请求 URL 和处理请求方法之间的对应关系
位置:
类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

属性:
value:用于指定请求的URL。它和path属性的作用是一样的
method:用于指定请求的方式
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

例如:
​ params = {“accountName”},表示请求参数必须有accountName
​ params = {“moeny!=100”},表示请求参数中money不能是100

2.1.3 SpringMVC的XML配置解析

  1. mvc命名空间引入
命名空间:xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"
约束地址:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
  1. 组件扫描

SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=“com.yh.controller"/>进行组件扫描。
SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀
  1. 视图解析器
    我们可以通过属性注入的方式修改视图的的前后缀
<!--配置内部资源视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"></property><property name="suffix" value=".jsp"></property>
</bean>

2.2 SpringMVC的数据响应

数据响应方式

1) 页面跳转
①直接返回字符串
②通过ModelAndView(HttpServletRequest)对象返回

2) 回写数据
①直接返回字符串
②返回对象或集合

页面跳转-返回字符串形式

第一种形式:
在这里插入图片描述

这种方式进行页面跳转一般与HttpServletRequest对象一起使用,在参数列表中声明,将数据存储至作用域中进行传递

第二种形式:

@RequestMapping(value="/quick4")public String save4(Model model){model.addAttribute("username","二狗子");return "success";}

这种方式同样会进行页面跳转,但是数据传递使用model对象,model对象的使用方式与HttpServletRequest类似,可以在jsp中使用el表达式通过key进行获取

页面跳转-通过ModelAndView对象返回

在Controller中方法返回ModelAndView对象,并且设置视图名称

@RequestMapping(value="/quick2")public ModelAndView save2(){/*Model:模型 作用封装数据View:视图 作用展示数据*/ModelAndView modelAndView = new ModelAndView();//设置模型数据modelAndView.addObject("username","二狗子");//设置视图名称modelAndView.setViewName("success");return modelAndView;}

这种方法就是直接将返回的视图与数据一同交由视图解析器进行自动处理

当然也可以不创建ModelAndView对象而是在方法中声明,在Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

 @RequestMapping(value="/quick3")public ModelAndView save3(ModelAndView modelAndView){modelAndView.addObject("username","华华");modelAndView.setViewName("success");return modelAndView;}

回写数据-直接返回字符串

通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数据,此时不需要视图跳转,业务方法返回值为void将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架通知视图解析器,方法返回的字符串不是跳转是直接在http响应体中返回

@RequestMapping(value="/quick7")@ResponseBody  //告知SpringMVC框架 不进行视图跳转 直接进行数据响应public String save7() throws IOException {return "hello yh";}@RequestMapping(value="/quick6")public void save6(HttpServletResponse response) throws IOException {response.getWriter().print("hello yh");}

json字符串也是字符串,所以也可以通过这种方式返回json字符串数据

@RequestMapping(value="/quick8")@ResponseBodypublic String save8() throws IOException {return "{\"username\":\"zhangsan\",\"age\":18}";}

手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串,我们可以使用web阶段学习过的json转换工具类进行转换后回写字符串(一般不用手动转换的方式)

回写数据-返回对象或集合

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property></bean>
@RequestMapping(value="/quick10")@ResponseBody//期望SpringMVC自动将User转换成json格式的字符串public User save10() throws IOException {User user = new User();user.setUsername("张三");user.setAge(18);return user;}

这样配置还是比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置

<mvc:annotation-driven/>

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用<mvc:annotation-driven />替代注解处理器和适配器的配置。同时使用<mvc:annotation-driven />默认底层就会集成jackson进行对象或集合的json格式字符串的转换

2.3 SpringMVC的数据请求

客户端请求参数的格式是:name=value&name=value……
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数
①基本类型参数
②类类型参数
③数组类型参数
④集合类型参数

2.3.1 基本类型参数的获取

springmvc会自动进行解析,只需要在controller中的业务方法的参数名称与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;
自动的类型转换是指从String向其他类型的转换(注意类型转换失败的情况)

@RequestMapping(value="/quick11")@ResponseBodypublic void save11(String username,int age){System.out.println(username);System.out.println(age);}

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。

当然也可以手动的进行配置获取请求指定的参数,使用RequestParam注解
@RequestParam有以下三个参数:
value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将抛出异常;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,设置该参数时,自动将required设为false。

public String requestparam(@RequestParam(value="username",required=false) String username)

2.3.2 类类型参数的获取

package com.yunhe.pojo;
public class User {private String username;private int age;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", age=" + age +'}';}
}
@RequestMapping(value="/quick12")@ResponseBodypublic void save12(User user){System.out.println(user);}

2.3.3 数组类型参数的获取

在前台页面提交的数据中,多个数据name相同,springmvc会自动解析成数组,但要求controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

@RequestMapping(value="/quick13")@ResponseBodypublic void save13(String[] strs) throws IOException {System.out.println(Arrays.asList(strs));}

2.3.4 集合类型参数的获取

springmvc会自动将对个name相同的数据解析为数组,所以在进行集合获取时需要将集合参数包装到一个POJO中才可以。

<form action="${pageContext.request.contextPath}/user/quick14" method="post"><%--表明是第一个User对象的username age--%><input type="text" name="userList[0].username"><br/><input type="text" name="userList[0].age"><br/><input type="text" name="userList[1].username"><br/><input type="text" name="userList[1].age"><br/><input type="submit" value="提交"></form>
package com.yh.domain;import java.util.List;public class VO {private List<User> userList;public List<User> getUserList() {return userList;}public void setUserList(List<User> userList) {this.userList = userList;}@Overridepublic String toString() {return "VO{" +"userList=" + userList +'}';}
}
@RequestMapping(value="/quick14")@ResponseBodypublic void save14(VO vo) throws IOException {System.out.println(vo);}

这种使用方式太过繁琐,对于不同的pojo类需要创建对应的集合类

使用ajax提交json数据获取集合类型参数数据

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script><script>var userList = new Array();userList.push({username:"zhangsan",age:18});userList.push({username:"lisi",age:28});$.ajax({type:"POST",url:"${pageContext.request.contextPath}/user/quick15",data:JSON.stringify(userList),contentType:"application/json;charset=utf-8"});</script>
@RequestMapping(value="/quick15")@ResponseBodypublic void save15(@RequestBody List<User> userList) throws IOException {System.out.println(userList);}

2.4 SpringMVC静态资源的访问

当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

•在spring-mvc.xml配置文件中指定放行的资源

<mvc:resources mapping="/js/**"location="/js/"/>

•使用<mvc:default-servlet-handler/>标签

<!--开发资源的访问--><!--<mvc:resources mapping="/js/**" location="/js/"/><mvc:resources mapping="/img/**" location="/img/"/>--><mvc:default-servlet-handler/>

2.5 SpringMVC配置编码过滤器

使用springmvc与servlet一样,当编码不一致时会出现乱码问题,springmvc提供了CharacterEncodingFilter全局过滤器进行全局的编码配置

<!--配置全局过滤的filter--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

2.6 SpringMVC配置参数绑定

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显式的绑定

<form action="${pageContext.request.contextPath}/quick16" method="post"><input type="text" name="name"><br><input type="submit" value="提交"><br>
</form>
@RequestMapping(value="/quick16")@ResponseBodypublic void save16(@RequestParam(value="name",required = false,defaultValue = "yh") String username) throws IOException {System.out.println(username);}

属性:
value :页面数据的name
required :是否必填(如果页面没有传递则报错默认为false)
defaultValue :默认值,当页面没有传递数据时的赋值(默认为数据 类型默认值)

2.7 SpringMVC配置请求类型转换器

SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。

@component
public class DateConverter implements Converter<String, Date> {public Date convert(String dateStr) {//将日期字符串转换成日期对象 返回SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date date = null;try {date = format.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return date;}
}
@RequestMapping(value="/quick18")@ResponseBodypublic void save18(Date date) throws IOException {System.out.println(date);}
    <mvc:annotation-driven conversion-service="conversionService"/><bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><set><ref bean="dateConverter"/></set></property></bean>

2.8 请求头信息信息的获取

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
value:请求头的名称
required:是否必须携带此请求头

@RequestMapping(value="/quick20")@ResponseBodypublic void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {System.out.println(user_agent);}

2.9 请求头cookie数据的获取

使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下:
value:指定cookie的名称
required:是否必须携带此cookie

    @RequestMapping(value="/quick21")@ResponseBodypublic void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {System.out.println(jsessionId);}

三、SpringMVC使用RESTful风格参数的获取

Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:
GET:用于获取资源
POST:用于新建资源
PUT:用于更新资源
DELETE:用于删除资源

例如:
/user/1 GET : 得到 id = 1 的 user
/user/1 DELETE: 删除 id = 1 的 user
/user/1 PUT: 更新 id = 1 的 user
/user POST: 新增 user

上述url地址/user/1中的1就是要获得的请求参数,form表单提交数据的方式支持get与post,但是在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

http://localhost:8080/springmvc1/quick17/zhangsan

@RequestMapping(value="/quick17/{name}")
@ResponseBodypublic void save17(@PathVariable(value="name") String username) throws IOException {System.out.println(username);}

springmvc使用RESTful风格就是使用占位符的形式,将数据与地址进行绑定,通过@PathVariable注解进行获取,完成通过对不同路径请求完成类似功能的需求

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

使用axios发送不同的请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title><script src="js/axios.min.js"></script>
</head>
<body><button id="btn1">GET请求</button><button id="btn2">POST请求</button><button id="btn3">PUT请求</button><button id="btn4">DELETE请求</button>
</body>
<script>document.getElementById("btn1").onclick=function (){var obj={};axios({// 请求方式method: 'get',url: 'user/1',// 传递参数 data使用流发送数据 params台servlet可以直接获取data: obj,//响应的数据格式 默认就是json 可以省略responseType: 'text'}).then(response => {// 请求成功let res = response.data;console.log(res);}).catch(error => {// 请求失败,console.log(error);// 一般不用});}document.getElementById("btn2").onclick=function (){var obj={id:2,name:"张三"};axios({// 请求方式method: 'post',url: 'user',// 传递参数 data使用流发送数据 params台servlet可以直接获取data: obj,//响应的数据格式 默认就是json 可以省略responseType: 'json'}).then(response => {// 请求成功let res = response.data;console.log(res);}).catch(error => {// 请求失败,console.log(error);// 一般不用});}document.getElementById("btn3").onclick=function (){var obj={id:2,name:"张三2"};axios({// 请求方式method: 'put',url: 'user',// 传递参数 data使用流发送数据 params台servlet可以直接获取data: obj,//响应的数据格式 默认就是json 可以省略responseType: 'json'}).then(response => {// 请求成功let res = response.data;console.log(res);}).catch(error => {// 请求失败,console.log(error);// 一般不用});}document.getElementById("btn4").onclick=function (){var obj={};axios({// 请求方式method: 'delete',url: 'user/4',// 传递参数 data使用流发送数据 params台servlet可以直接获取data: obj,//响应的数据格式 默认就是json 可以省略responseType: 'text'}).then(response => {// 请求成功let res = response.data;console.log(res);}).catch(error => {// 请求失败,console.log(error);// 一般不用});}
</script>
</html>

四、SpringMVC拦截器简单使用

4.1 概念

SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
(1)过滤器:

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

(2)拦截器:

依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。

1、常见应用场景

1)日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

3)性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

5)OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。

…………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

SpringMVC提供的拦截器接口:HandlerInterceptor

public interface HandlerInterceptor {boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;
}

拦截器一个有3个回调方法,而一般的过滤器Filter才两个:

preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器才会执行afterCompletion。

拦截器适配器:HandlerInterceptorAdapter

有时我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,此时spring提供了一个HandlerInterceptorAdapter适配器(一种适配器设计模式的实现),允许我们只实现需要的回调方法

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {}public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {}public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {}
}

4.2 简单使用

①自定义两个拦截器(继承拦截器适配器:HandlerInterceptorAdapter):HandlerInterceptor1 和 HandlerInterceptor2

public class HandlerInterceptor1 extends HandlerInterceptorAdapter{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {System.out.println("--1--HandlerInterceptor1.preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {System.out.println("--1--HandlerInterceptor1.postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {System.out.println("--1--HandlerInterceptor1.afterCompletion");}
}

②在 springmvc.xml 配置文件中配置拦截器:
(1)拦截所有Controller类里的所有处理方法

	<!-- 配置拦截器:--><mvc:interceptors><!-- 会拦截所有Controller类里的所有处理方法 --><bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean><bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean></mvc:interceptors>

(2)只拦截某个请求路径的处理方法

	<!-- 配置拦截器:--><mvc:interceptors><!-- 会拦截所有Controller类里的所有处理方法 --><bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean><mvc:interceptor><!-- 只拦截该路径 --><mvc:mapping path="/users"/><bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean></mvc:interceptor></mvc:interceptors>

(3)拦截器深入配置:注意 /** (任意分层路径下) ,/* (该任意单路径下) 和 配置順序(先所有后排除)

	<!-- 配置拦截器:--><mvc:interceptors><!-- 会拦截所有Controller类里的所有处理方法 --><bean class="com.yunhe.interceptor.HandlerInterceptor1"></bean><mvc:interceptor><!-- 只拦截该路径 --><mvc:mapping path="/users"/><bean class="com.yunhe.interceptor.HandlerInterceptor2"></bean></mvc:interceptor><mvc:interceptor><!-- 拦截所有请求,排除拦截 /toAdd 请求 --><mvc:mapping path="/**"/><mvc:exclude-mapping path="/toAdd"/><bean class="com.yunhe.interceptor.HandlerInterceptor3"></bean></mvc:interceptor></mvc:interceptors>

# 五、SSM整合项目创建

①导入相应的依赖坐标

    <!-- spring核心依赖坐标 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.5</version></dependency><!-- springaop织入依赖 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><!-- lombok工具依赖 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.2</version></dependency><!-- spring jdbc依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.5</version></dependency><!-- mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.39</version></dependency><!-- Druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!-- springmvc依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.5</version></dependency><!-- servlet依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><!-- jsp依赖 --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version></dependency><!-- jackson依赖 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency><!-- mybatis依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!--  mybatis sping整合依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency><!--log4j依赖--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>

②创建相应的包

在这里插入图片描述

③书写mybatis核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 加载properties配置文件 --><!--<properties url=""></properties>--><!-- 为指定的包下的类设置别名(设置pojo 使用首字母小写形式的别名) --><!--<typeAliases><package name=""/></typeAliases>--><!-- 配置mybatis数据源选择操作 --><!--<environments default=""><environment id=""><transactionManager type=""></transactionManager><dataSource type=""></dataSource></environment></environments>--><!-- mybatis的全局配置 基本使用默认 其他可以通过mapper配置文件进行设置 --><settings><setting name="lazyLoadingEnabled" value="true"/><!-- 开启懒加载 --><setting name="aggressiveLazyLoading" value="false"/><!-- 设置懒加载侵入方式 --><setting name="logImpl" value="STDOUT_LOGGING"/><!-- 使用mybatis 自带的日志管理 --></settings><!-- 配置mybatis扫描xml文件所在的包 --><!--<mappers><package name=""/></mappers>--></configuration>

④书写log4j与数据连接配置文件

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

⑤配置spring相关核心配置文件

<?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:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- spring组件扫描 --><!-- 将含有对应注解的类交由spring管理 可以实现IOC与DI AOP也必须切入由spring管理的类 --><context:component-scan base-package="com.yunhe"/><!-- 加载properties --><!-- 可以在当前的配置文件中使用${key}的形式获取对应的value值 --><context:property-placeholder location="classpath:db.properties"/><!-- 配置数据源 --><!-- 使用指定的连接池对数据源进行管理 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!-- 配置spring与mybatis整合 --><!-- 配置SqlSessionFactoryBean对象,整合加载mybatis配置文件 使用mybatis进行数据源操作 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 将数据源交由mybatis进行管理 --><property name="dataSource" ref="dataSource"/><!-- 配置mybatis配置文件 --><!-- 加载mybatis核心配置文件(进行修改时) --><property name="configLocation" value="classpath:mybatis.xml"/><!-- 配置mapper映射文件 --><!-- 在创建mybatis时加载所有的mapper.xml --><property name="mapperLocations" value="classpath:mapper/*.xml"/></bean><!-- mybatis.spring自动映射,DAO接口所在包名,Spring会自动查找其下的类 --><!-- 根据加载的mapper.xml创建相应的实现类 并交由spring容器管理 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.yunhe.mapper" /></bean><!--平台事务管理器--><!-- 创建相应的事务代理对象交由spring容器管理 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 开启事务的注解驱动 --><!-- 将拥有事务处理的方法进行事务代理 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 设置aop织入自动代理 --><!-- 才会将相应的切面类织入指定的切入点(方法) --><aop:aspectj-autoproxy/><!-- springmvc视图解析器 --><!-- 在controller返回的视图名进行拼接返回对应视图 --><!-- 如果需要使用其他的视图模板或插件也是在视图解析器进行配置 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/view/"></property><property name="suffix" value=".jsp"></property></bean><!-- 开启springmvc注解驱动 --><mvc:annotation-driven/><!-- 开启静态资源默认过滤 --><mvc:default-servlet-handler/><!-- 指定静态资源过滤 --><!--<mvc:resources mapping="" location=""></mvc:resources>--></beans>

⑥配置web.xml

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!-- springmvc编码控制器 --><filter><filter-name>Encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class></filter><filter-mapping><filter-name>Encoding</filter-name><url-pattern>*</url-pattern></filter-mapping><!-- springmvc前端控制器 --><servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>mvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

⑦书写相应的代码测试ssm整合是否成功

User.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private int uid;private String uusername;private String upassword;
}

UserMapper.java

public interface UserMapper {ArrayList<User> selectAll();
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunhe.mapper.UserMapper"><select id="selectAll" resultType="com.yunhe.pojo.User">select * from user</select></mapper>

UserService.java

public interface UserService {public ArrayList<User> findAll();
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic ArrayList<User> findAll() {return userMapper.selectAll();}
}

UserController.java

@Controller
public class UserController {@Autowiredprivate UserService userServiceImpl;@RequestMapping("/all")public String find(HttpServletRequest request){request.setAttribute("msg",userServiceImpl.findAll());return "success";}
}

success.jsp

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

UserController.java

@Controller
public class UserController {@Autowiredprivate UserService userServiceImpl;@RequestMapping("/all")public String find(HttpServletRequest request){request.setAttribute("msg",userServiceImpl.findAll());return "success";}
}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head><title>Title</title>
</head>
<body>
${msg}
</body>
</html>
<select id="selectAll" resultType="com.yunhe.pojo.User">select * from user
</select>
```

UserService.java

public interface UserService {public ArrayList<User> findAll();
}

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic ArrayList<User> findAll() {return userMapper.selectAll();}
}

UserController.java

@Controller
public class UserController {@Autowiredprivate UserService userServiceImpl;@RequestMapping("/all")public String find(HttpServletRequest request){request.setAttribute("msg",userServiceImpl.findAll());return "success";}
}

success.jsp

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

UserController.java

@Controller
public class UserController {@Autowiredprivate UserService userServiceImpl;@RequestMapping("/all")public String find(HttpServletRequest request){request.setAttribute("msg",userServiceImpl.findAll());return "success";}
}

success.jsp

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

相关文章:

SpringMVC学习使用

一、SpringMVC简单理解 1.1 Spring与Web环境集成 1.1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的&#xff0c;但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(sp…...

10、《文件上传与下载:MultipartFile与断点续传设计》

文件上传与下载&#xff1a;MultipartFile与断点续传设计 一、基础文件上传与MultipartFile解析 1.1 Spring MVC文件上传基础 PostMapping("/upload") public String handleFileUpload(RequestParam("file") MultipartFile file) {if (!file.isEmpty())…...

DeepSeek 本地部署(电脑安装)

1.先安装Ollama 开源框架 网址链接为:Ollama 2.点中间的下载 3.选系统 4.下载好就安装 5.输入命令ollama -v 6.点击Model 7.选如下 8.选版本 9.复杂对应命令 10.控制台粘贴下载 11.就可以问问题啦 12.配置UI界面(在扩展里面输入) 13.配置完即可打开 14.选择刚才安装的就好啦…...

DeepSeek、Kimi、文心一言、通义千问:AI 大语言模型的对比分析

在人工智能领域&#xff0c;DeepSeek、Kimi、文心一言和通义千问作为国内领先的 AI 大语言模型&#xff0c;各自展现出了独特的特点和优势。本文将从技术基础、应用场景、用户体验和价格与性价比等方面对这四个模型进行对比分析&#xff0c;帮助您更好地了解它们的特点和优势。…...

Docker compose 以及镜像使用

Docker compose 以及镜像使用 高级配置 使用 Docker Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。以下是一个 docker-compose.yml 示例&#xff1a; version: 3 services:web:image: my-appbuild: .ports:- "8000:8000"volumes:- …...

HCIA项目实践--RIP相关原理知识面试问题总结回答

9.4 RIP 9.4.1 补充概念 什么是邻居&#xff1f; 邻居指的是在网络拓扑结构中与某一节点&#xff08;如路由器&#xff09;直接相连的其他节点。它们之间可以直接进行通信和数据交互&#xff0c;能互相交换路由信息等&#xff0c;以实现网络中的数据转发和路径选择等功能。&am…...

使用Python进行云计算:AWS、Azure、和Google Cloud的比较

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行云计算&#xff1a;AWS、Azure、和Google Cloud的比较 随着云计算的普及&am…...

c++ 实现矩阵乘法

矩阵乘法的基本实现方法是三层循环&#xff0c;但不同的循环顺序会影响性能&#xff0c;比如i-j-k和i-k-j的顺序。然后&#xff0c;参考内容里提到了一些优化方法&#xff0c;比如调整循环顺序来提高缓存命中率&#xff0c;使用一维数组存储矩阵&#xff0c;或者利用SIMD指令如…...

无线4G多联机分户计费集中控制系统

拓森无线4G多联机集中控制系统应用于宝龙广场多联机计费集中控制节能改造项目&#xff0c;包括多联机集中控制&#xff0c;分户计费&#xff0c;空调监控管理、告警管理、节能管控、统计报表、能效分析、空调远程开关机等功能。项目的成功实施&#xff0c;不仅提升了维护管理效…...

文字转语音(一)各种实现说明

记录下文字转语音的各种方式及优缺点 目前只了解了调用 Windows PowerShell&#xff08;System.Speech.Synthesis&#xff09;、FreeTTS、JACOB&#xff08;Java COM Bridge&#xff09;库实现文字转语音。 其他的方式就是顺带记录了解下 Windows PowerShell&#xff08;System…...

大语言模型多代理协作(MACNET)

大语言模型多代理协作(MACNET) Scaling Large-Language-Model-based Multi-Agent Collaboration 提出多智能体协作网络(MACNET),以探究多智能体协作中增加智能体数量是否存在类似神经缩放定律的规律。研究发现了小世界协作现象和协作缩放定律,为LLM系统资源预测和优化…...

【笛卡尔树】

笛卡尔树 笛卡尔树定义构建性质 习题P6453 [COCI 2008/2009 #4] PERIODNICF1913D Array CollapseP4755 Beautiful Pair[ARC186B] Typical Permutation Descriptor 笛卡尔树 定义 笛卡尔树是一种二叉树&#xff0c;每一个节点由一个键值二元组 ( k , w ) (k,w) (k,w) 构成。要…...

Java堆外内存的高效利用与性能优化

在Java开发中&#xff0c;堆外内存&#xff08;Direct Memory&#xff09;是除Java堆以外的内存区域。它允许Java程序直接分配和管理非堆内存&#xff0c;这为高性能的数据处理提供了可能。 1、 什么是堆外内存&#xff1f; 堆外内存&#xff0c;也称为直接内存&#xff08;D…...

【Unity3D优化】使用ASTC压缩格式优化内存

在Unity3D手游开发中&#xff0c;合理选择纹理压缩格式对于优化内存占用、提高渲染效率至关重要。本文将记录近期在项目内进行的图片压缩格式优化过程&#xff0c;重点介绍从ETC2到ASTC 5x5的优化方案及其带来的收益。 1. 现状分析&#xff1a;从ETC2到ASTC 6x6 block 在项目…...

iptables网络安全服务详细使用

iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具。 centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件firewalld&#xff08;zone&#xff09; iptables主要工作在OSI七层的二、三、四层&#xff0c;如果重新编译内核&…...

MiC建筑引领未来:中建海龙的探索与实践

随着全球城市化进程的加速推进&#xff0c;建筑行业正面临着前所未有的挑战与机遇。如何高效、环保地建造高质量的建筑&#xff0c;成为了行业内外普遍关注的焦点。在此背景下&#xff0c;MiC&#xff08;Modular Integrated Construction&#xff0c;模块化集成建筑&#xff0…...

清华精品资料:DeepSeek从入门到精通、DeepSeek赋能职场

今天电脑天空给大家推荐2份清华大学专家编写的DeepSeek的使用手册&#xff0c;分别是《DeepSeek从入门到精通》和《DeepSeek赋能职场》。 《DeepSeek从入门到精通》是一本系统化的技术指南&#xff0c;旨在帮助用户从零基础到精通掌握通用人工智能模型DeepSeek的核心功能与应用…...

Nginx进阶篇 - nginx多进程架构详解

文章目录 1. nginx的应用特点2. nginx多进程架构2.1 nginx多进程模型2.2 master进程的作用2.3 进程控制2.4 worker进程的作用2.5 worker进程处理请求的过程2.6 nginx处理网络事件 1. nginx的应用特点 Nginx是互联网企业使用最为广泛的轻量级高性能Web服务器&#xff0c;其特点是…...

SpringBoot初始化8个常用方法

在 Spring Boot 中&#xff0c;初始化方法通常是在应用程序启动时被调用的&#xff0c;可以用来执行应用启动时的一些准备工作。以下是几种常见的初始化方法&#xff1a; 一、顺序 1. 图解 ┌─────────────────────────────┐│ Spring Boot…...

boolen盲注和时间盲注

获取当前数据库名 import requestsdef inject_database(url):namemax_length20low{a: 97, z: 122, A: 65, Z: 90, 0: 48, 9: 57, _: 95}high{97: a, 122: z, 65: A, 90: Z, 48: 0, 57: 9, 95: _}for i in range(1, max_length 1):low_val32high_val122while low_val < hi…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...