关于spring-mvc:SpringMVC使用MultipartFile对象实现文件上传

1、增加依赖<!-- https://mvnrepository.com/artifact/commons-fileupload/commonsfileupload --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency>2、在SpringMVC的配置文件中增加配置:<!--必须通过文件解析器的解析能力将文件转换为MultipartFile对象--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>3、控制器办法:@RequestMapping("/testUp")public String testUp(MultipartFile photo, HttpSession session)throws IOException {//获取上传的文件的文件名String fileName = photo.getOriginalFilename();//解决文件重名问题String hzName = fileName.substring(fileName.lastIndexOf("."));fileName = UUID.randomUUID().toString() + hzName;//获取服务器中photo目录的门路ServletContext servletContext = session.getServletContext();String photoPath = servletContext.getRealPath("photo");File file = new File(photoPath);if(!file.exists()){file.mkdir();}String finalPath = photoPath + File.separator + fileName;//实现上传性能photo.transferTo(new File(finalPath));return "success";}

January 5, 2023 · 1 min · jiezi

关于spring-mvc:SpringMVC实现下载功能

@RequestMapping("/test/down") public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException { //获取ServletContext对象 ServletContext servletContext = session.getServletContext(); //获取服务器中文件的实在门路 String realPath = servletContext.getRealPath("/static/img/123.jpg"); //创立输出流 InputStream is = new FileInputStream(realPath); //创立字节数组 byte[] bytes = new byte[is.available()]; //将流读到字节数组中 is.read(bytes); //创立HttpHeaders对象设置响应头信息 MultiValueMap<String, String> headers = new HttpHeaders(); //设置要下载方式以及下载文件的名字 headers.add("Content-Disposition","attachment;filename=1.jpg"); //设置响应状态码 HttpStatus statusCode = HttpStatus.OK; //创立ResponseEntity对象 ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers,statusCode); //敞开输出流 is.close(); return responseEntity; }

January 5, 2023 · 1 min · jiezi

关于spring-mvc:SpringMVC常见面试题

1、什么是Spring MVC ?简略介绍下你对springMVC的了解?Spring MVC是一个基于Java的实现了MVC设计模式的申请驱动类型的轻量级Web框架,通过把Model,View,Controller拆散,将web层进行职责解耦,把简单的web利用分成逻辑清晰的几局部,简化开发,缩小出错,不便组内开发人员之间的配合。 2、SpringMVC的流程?(1)用户发送申请至前端控制器DispatcherServlet; (2)DispatcherServlet收到申请后,调用HandlerMapping处理器映射器,申请获取Handler; (3)处理器映射器依据申请url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet; (4)DispatcherServlet 调用 HandlerAdapter处理器适配器,申请执行Handler; (5)HandlerAdapter 通过适配调用 具体处理器进行解决业务逻辑; (6)Handler执行实现返回ModelAndView; (7)HandlerAdapter将Handler执行后果ModelAndView返回给DispatcherServlet; (8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析; (9)ViewResolver解析后返回具体View; (10)DispatcherServlet对View进行渲染视图(行将模型数据填充至视图中) (11)DispatcherServlet响应用户。 前端控制器 DispatcherServlet:接管申请、响应后果,相当于转发器,有了DispatcherServlet 就缩小了其它组件之间的耦合度。 处理器映射器 HandlerMapping:依据申请的URL来查找Handler 处理器适配器 HandlerAdapter:负责执行Handler 处理器 Handler:处理器,须要程序员开发 视图解析器 ViewResolver:进行视图的解析,依据视图逻辑名将ModelAndView解析成真正的视图(view) 视图View:View是一个接口, 它的实现类反对不同的视图类型,如jsp,freemarker,pdf等等 3、Springmvc的长处:(1)能够反对各种视图技术,而不仅仅局限于JSP; (2)与Spring框架集成(如IoC容器、AOP等); (3)清晰的角色调配:前端控制器(dispatcherServlet) ,申请到处理器映射(handlerMapping),处理器适配器(HandlerAdapter),视图解析器(ViewResolver)。 (4) 反对各种申请资源的映射策略。 4、SpringMVC怎么样设定重定向和转发的?(1)转发:在返回值后面加"forward:",譬如"forward:user.do?name=method4" (2)重定向:在返回值后面加"redirect:",譬如"redirect:http://www.baidu.com" 5、 SpringMVC罕用的注解有哪些?@RequestMapping:用于解决申请 url 映射的注解,可用于类或办法上。用于类上,则示意类中的所有响应申请的办法都是以该地址作为父门路。 @RequestBody:注解实现接管http申请的json数据,将json转换为java对象。 @ResponseBody:注解实现将conreoller办法返回对象转化为json对象响应给客户。 6、SpingMvc中的控制器的注解个别用哪个?有没有别的注解能够代替?答:个别用@Controller注解,也能够应用@RestController,@RestController注解相当于@ResponseBody + @Controller,示意是体现层,除此之外,个别不必别的注解代替。 7、springMVC和struts2的区别有哪些?(1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。 (2)springmvc是基于办法开发(一个url对应一个办法),申请参数传递到办法的形参,能够设计为单例或多例(倡议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 (3)Struts采纳值栈存储申请和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request申请内容解析,并给办法形参赋值,将数据和视图封装成ModelAndView对象,最初又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认应用jstl。 8、如何解决POST申请中文乱码问题,GET的又如何解决呢?(1)解决post申请乱码问题:在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8; <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)get申请中文参数呈现乱码解决办法有两个: ①批改tomcat配置文件增加编码与工程编码统一,如下: <ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>②另外一种办法对参数进行从新编码: String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")ISO8859-1是tomcat默认编码,须要将tomcat编码后的内容按utf-8编码。 ...

November 23, 2022 · 1 min · jiezi

关于spring-mvc:如何使SpringMVC的表单和get请求参数支持json转换

该文章为原创(转载请注明出处):如何使SpringMVC的表单和get申请参数反对json转换? - 简书 (jianshu.com)实在业务场景前端申请须要表单传递json字符串或者get申请参数携带了json字符串的数据后端只能在格局上做斗争?例如: 前端表单userJson:{"name":"xxx", "phone":"123"}前端Get申请/user/test?userJson=%7B%22name%22%3A%22xxx%22%2C%20%22phone%22%3A%22123%22%7D 后端接管表单1@GetMapping("test.do")public RestResponse<Void> test(@ModelAttribute String userJson) { body.setUser(JSON.parseObject(userJson, User.class)); // service.handleUser(body);}@Datastatic class User { private String phone; private String name;}后端接管表单2@GetMapping("test.do")public RestResponse<Void> test(@ModelAttribute TestBody body) { body.setUser(JSON.parseObject(body.getUserJson(), User.class)); // service.handleUser(body);} @Datastatic class TestBody { private String userJson;}static class User { private String phone; private String name;}后端接管Get申请@GetMapping("test.do")public RestResponse<Void> test(@RequestParam String userJson) { body.setUser(JSON.parseObject(userJson, User.class)); // service.handleUser(body);}@Datastatic class User { private String phone; private String name;}反对json的解决方案利用springmvc提供的@ControllerAdvice切面,在WebDataBinder中退出应用json反序列化的形式来进行string与各种类型的转换 package com.nuonuo.accounting.guiding.support.spring;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.parser.ParserConfig;import com.alibaba.fastjson.util.TypeUtils;import org.springframework.core.convert.TypeDescriptor;import org.springframework.core.convert.converter.GenericConverter;import org.springframework.core.convert.support.GenericConversionService;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;import java.util.Set;import static java.util.Collections.singleton;/** * Fastjson来主动绑定参数 * 反对表单、get申请参数 * * @author uhfun * @see RequestMappingHandlerAdapter#initControllerAdviceCache() * 寻找@ControllerAdvice切面下@InitBinder注解的办法 * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#INIT_BINDER_METHODS * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDataBinderFactory(org.springframework.web.method.HandlerMethod) * 依据切面构建InitBinderMethod办法 * @see org.springframework.web.method.annotation.InitBinderDataBinderFactory#initBinder * 初始化binder时反射调用 * @see ModelAttribute */@ControllerAdvicepublic class StringToAnyObjectSupport { private static volatile boolean INITIALIZED = false; @InitBinder public void initStringToAnyObjectConverter(WebDataBinder dataBinder) { GenericConversionService conversionService; if (dataBinder.getConversionService() instanceof GenericConversionService) { if (!INITIALIZED) { conversionService = (GenericConversionService) dataBinder.getConversionService(); conversionService.addConverter(new StringToAnyObjectConverter()); INITIALIZED = true; } } else { throw new IllegalStateException("dataBinder的ConversionService不是GenericConversionService类型实例"); } } static class StringToAnyObjectConverter implements GenericConverter { @Override public Set<ConvertiblePair> getConvertibleTypes() { return singleton(new ConvertiblePair(String.class, Object.class)); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Class<?> type = targetType.getType(); if (TypeUtils.getClassFromMapping(type.getName()) != null) { return TypeUtils.cast(source, type, ParserConfig.getGlobalInstance()); } else { return JSON.parseObject((String) source, type); } } }}如何应用?后端接管表单1@GetMapping("test.do")public RestResponse<Void> test(@ModelAttribute("userJson") User user) {} static class User { private String phone; private String name;}后端接管表单2@GetMapping("test.do")public RestResponse<Void> test(@ModelAttribute TestBody body) { User user = body.getUserJson(); // service.handleUser(body);} @Datastatic class TestBody { private User userJson;}static class User { private String phone; private String name;}后端接管Get申请@GetMapping("test.do")public RestResponse<Void> test(@RequestParam User userJson) { }@Datastatic class User { private String phone; private String name;}该文章为原创(转载请注明出处):如何使SpringMVC的表单和get申请参数反对json转换? - 简书 (jianshu.com)

October 22, 2022 · 2 min · jiezi

关于spring-mvc:SpringMVC学习记录

回顾MVC什么是MVCMVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示拆散的办法来组织代码。MVC次要作用是升高了视图与业务逻辑间的双向偶合。MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差别。Model(模型):数据模型,提供要展现的数据,因而蕴含数据和行为,能够认为是畛域模型或JavaBean组件(蕴含数据和行为),不过当初个别都拆散开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查问和模型数据的状态更新等性能,包含数据和业务。 View(视图):负责进行模型的展现,个别就是咱们见到的用户界面,客户想看到的货色。 Controller(控制器):接管用户申请,委托给模型进行解决(状态扭转),处理完毕后把返回的模型数据返回给视图,由视图负责展现。也就是说控制器做了个调度员的工作。 最典型的MVC就是JSP + servlet + javabean的模式。 Model1时代在web晚期的开发中,通常采纳的都是Model1。Model1中,次要分为两层,视图层和模型层。 Model1长处:架构简略,比拟适宜小型我的项目开发; Model1毛病:JSP职责不繁多,职责过重,不便于保护; Model2时代Model2把一个我的项目分成三局部,包含视图、管制、模型。 用户发申请Servlet接管申请数据,并调用对应的业务逻辑办法业务处理完毕,返回更新后的数据给servletservlet转向到JSP,由JSP来渲染页面响应给前端更新后的页面职责剖析Controller:控制器获得表单数据调用业务逻辑转向指定的页面Model:模型业务逻辑保留数据的状态View:视图就一个 显示页面Model2这样不仅进步的代码的复用率与我的项目的扩展性,且大大降低了我的项目的保护老本。Model 1模式的实现比较简单,实用于疾速开发小规模我的项目,Model1中JSP页面身兼View和Controller两种角色,将管制逻辑和体现逻辑混淆在一起,从而导致代码的重用性非常低,减少了利用的扩展性和保护的难度。Model2打消了Model1的毛病。MVC框架要做哪些事件将url映射到java类或java类的办法 .封装用户提交的数据 .解决申请--调用相干的业务解决--封装响应数据 .将响应的数据进行渲染 . jsp / html 等表示层数据 .常见的服务器端MVC框架有:Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;常见前端MVC框架:vue、angularjs、react、backbone;由MVC演化出了另外一些模式如:MVP、MVVM 等等....回顾Servlet新建一个Maven工程springMVC当做父我的项目,而后新建一个maven子项目springMVC01-servlet,勾选模版maven-archetype-webapp编写pom.xml配置文件 <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>SpringMVC-Review01</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.7.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> </project>替换SpringMVC-Review/SpringMVC-Review01/src/main/webapp/WEB-INF/web.xml为如下内容 ...

September 24, 2022 · 5 min · jiezi

关于spring-mvc:地摊秘笈之Spring-MVC源码二解密请求流程

概述Spring MVC的流程次要是从Servlet的service办法作为入口,以时序图为例,将一些要害的办法表明大抵理解流程所做的解决。 申请先进入DispatcherServlet的父类FrameworkServlet的service办法,进行PATCH办法的解决,其余办法调用FrameworkServlet]的父类HttpServlet的service办法,进行不同GET或POST等办法的不同解决。之后调用FrameworkServlet的processRequest办法,进行公布一些事件和调用DispatcherServlet的doService办法。而doService办法次要往request外面set一些属性,最次要还是在doDispatch进行散发申请。调用DispatcherServlet的doDispatch办法进行散发申请。调用DispatcherServlet的getHandler办法。次要进行遍历全副映射器处理器,通过映射器处理器找到处理器(Controller)和拦截器(HandlerInterceptor)。调用DispatcherServlet的getHandlerAdapter办法.次要进行遍历处理器适配器,失去能够反对进行适配的适配器。调用HandlerExecutionChain的拦截器前置办法applyPreHandle。应用适配器HandlerAdapter进行调用Controller的办法。次要进行应用适配器进行参数的映射,同时执行处理器(Controller),返回ModelAndView (数据Model和逻辑视图)。调用DispatcherServlet的applyDefaultViewName办法,对于没有逻辑视图给予默认视图。调用HandlerExecutionChain的拦截器后置办法applyPostHandle调用DispatcherServlet的processDispatchResult办法,进行解决散发的后果,外面也会进行异样的解决。调用DispatcherServlet的render办法,遍历视图解析器解决视图的逻辑名称,返回视图(View),而后应用视图(View)进行视图的渲染,并且将响应实体写进Response调用DispatcherServlet的triggerAfterCompletion办法,进行调用拦截器HandlerInterceptor的afterCompletion办法。

September 14, 2022 · 1 min · jiezi

关于spring-mvc:DispatcherServlet

概述Servlet WebApplicationContext容器的初始化基于咱们配置的DispatcherServlet,DispatcherServlet是Servlet 的实现,当Servlet进行初始化调用DispatcherServlet的父类HttpServletBean的init办法进行Servlet的初始化。复写Servlet的init办法的关键步骤如下: 将web.xml外面的配置进行赋值能够通过4种不同的形式初始化Servlet WebApplicationContext容器,进行配置和刷新初始化HandlerMapping,HandlerAdapter等组件DispatcherServlet类的UML 咱们看要害的几个实现之间的关系和性能 HttpServletBean : 将ServletConfig外面的配置赋值到ServletFrameworkServlet : 初始化和配置刷新Servlet WebApplicationContext容器DispatcherServlet :初始化 Spring MVC的各个组件,以及解决申请整体流程Servlet WebApplicationContext容器的初始化产生在,DispatcherServlet调用HttpServletBean的init办法,进行Servlet的初始化。次要将ServletConfig外面的配置赋值到Servlet。之后调用FrameworkServlet的initServletBean办法进行初始化Servlet WebApplicationContext,并配置和刷新上下文最初调用DispatcherServlet的onRefresh办法,进行组件的初始化分步解释调用HttpServletBean的init办法,将 ServletConfig 外面的InitParameter赋值到以后Servlet对象中 将ServletConfig外面的InitParameter配置转为PropertyValues,同时校验必须配置的配置项将PropertyValues外面的配置赋值到Servlet//org.springframework.web.servlet.HttpServletBean public final void init() throws ServletException { // Set bean properties from init parameters. // 将ServletConfig外面的配置转为PropertyValues,同时校验必须配置的配置项 PropertyValues pvs \= new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); if (!pvs.isEmpty()) { try { BeanWrapper bw \= PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader \= new ServletContextResourceLoader(getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); initBeanWrapper(bw); // 将ServletConfig外面的配置赋值到Servlet bw.setPropertyValues(pvs, true); } catch (BeansException ex) { if (logger.isErrorEnabled()) { logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); } throw ex; } } // Let subclasses do whatever initialization they like. //FrameworkServlet进行了重载 initServletBean(); }将ServletConfig外面的InitParameter配置转为PropertyValues,同时校验必须配置的配置项 ...

September 14, 2022 · 5 min · jiezi

关于spring-mvc:Root-WebApplicationContext容器初始化和关闭

Root WebApplicationContext容器初始化和敞开概述Root WebApplicationContext的初始化是基于咱们配置的ContextLoaderListener,通过ContextLoaderListener实现了ServletContextListener监听Web容器启动触发contextInitialized办法,而后调用ContextLoader的initWebApplicationContext进行初始化。initWebApplicationContext关键步骤如下: 获取Root WebApplicationContext的Class类型,通过反射进行初始化配置和刷新Root WebApplicationContext将Root WebApplicationContext存储在ServletContext外面,用于上面的Servlet WebApplicationContext的父上下文。ContextLoaderListener类的UML ContextLoader :该类次要的性能通过调用initWebApplicationContext办法用来初始化Root WebApplicationContextServletContextListener :改接口是Servlet裸露进去的用于监听容器启动之后执行办法的监听器ContextLoaderListener:该类次要是ContextLoader和ServletContextListener的集成。所以从总体上看该类没有很多理论的性能,然而这样设计更加合乎繁多职责准则,逻辑更加的清晰,初始化和监听容器初始化进行离开。整体流程在web.xml配置的ContextLoaderListener实现了ServletContextListener接口,监听容器启动触发事件ServletContextEvent,触发ServletContextListener的contextInitialized办法调用ContextLoader的initWebApplicationContext进行初始化initWebApplicationContext办法次要蕴含以下两局部进行Root WebApplicationContext容器的初始化 调用ContextLoader的createWebApplicationContext办法,应用配置或者默认全类名应用反射进行创立Root WebApplicationContext上下文调用ContextLoader的configureAndRefreshWebApplicationContext进行配置Root WebApplicationContext上下文,并进行启动容器(也就是ConfigurableApplicationContext的refresh办法)将Root WebApplicationContext存储在ServletContext用于Servlet WebApplicationContext父上下文分步解释容器启动,ContextLoaderListener监听ServletContextEvent事件,调用ServletContextListener的contextInitialized办法进行初始化 //org.springframework.web.context.ContextLoaderListener @Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); } 调用ContextLoader的initWebApplicationContext进一步初始化 首先进行容器的初始化而后进行容器的配置和刷新最初将容器存在ServletContext//org.springframework.web.context.ContextLoader public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { if (servletContext.getAttribute(WebApplicationContext.ROOT\_WEB\_APPLICATION\_CONTEXT\_ATTRIBUTE) != null) { throw new IllegalStateException( "Cannot initialize context because there is already a root application context present - " + "check whether you have multiple ContextLoader\* definitions in your web.xml!"); } servletContext.log("Initializing Spring root WebApplicationContext"); Log logger \= LogFactory.getLog(ContextLoader.class); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); } long startTime \= System.currentTimeMillis(); try { // Store context in local instance variable, to guarantee that // it is available on ServletContext shutdown. if (this.context \== null) { //这里有两种状况 //1. 依据servletContext获取配置文件的contextClass获取全限定名应用个反射进行初始化 //2. 依据defaultStrategies配置文件默认的WebApplicationContext获取全限定名进行初始化 this.context \= createWebApplicationContext(servletContext); } if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac \= (ConfigurableWebApplicationContext) this.context; // 如果没有进行配置和激活,进行配置和激活 if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() \== null) { // The context instance was injected without an explicit parent -> // determine parent for root web application context, if any. ApplicationContext parent \= loadParentContext(servletContext); cwac.setParent(parent); } //配置和激活上下文 configureAndRefreshWebApplicationContext(cwac, servletContext); } } // 将RootWebApplicationContext存储在servletContext中   servletContext.setAttribute(WebApplicationContext.ROOT\_WEB\_APPLICATION\_CONTEXT\_ATTRIBUTE, this.context); ClassLoader ccl \= Thread.currentThread().getContextClassLoader(); if (ccl \== ContextLoader.class.getClassLoader()) { currentContext \= this.context; } else if (ccl != null) { currentContextPerThread.put(ccl, this.context); } if (logger.isInfoEnabled()) { long elapsedTime \= System.currentTimeMillis() \- startTime; logger.info("Root WebApplicationContext initialized in " + elapsedTime + " ms"); } return this.context; } catch (RuntimeException | Error ex) { logger.error("Context initialization failed", ex); servletContext.setAttribute(WebApplicationContext.ROOT\_WEB\_APPLICATION\_CONTEXT\_ATTRIBUTE, ex); throw ex; } }ContextLoader的createWebApplicationContext办法,进行初始化WebApplicationContext ...

September 14, 2022 · 3 min · jiezi

关于spring-mvc:从零搭建-Spring-MVC-项目-Validation

疾速开始1. 引入 Validation 依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId></dependency>2. 编写校验代码@Data 为 lombok 的注解,在此不做具体阐明。@Datapublic class UserRequest { @NotBlank private String name; @Min(0) @Max(200) private Integer age;}3. 申明校验参数@RestControllerpublic class UserController { @PostMapping("/api/users") public UserRequest createUser(@RequestBody @Validated UserRequest userRequest) { return userRequest; }}4. 捕获全局异样这一步不是必须的,目标是为了能不便查看校验后果。@ControllerAdvicepublic class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, Object>> handleMethodArgumentNotValidException( MethodArgumentNotValidException exception) { List<String> errorMessages = exception.getFieldErrors() .stream() .map(fieldError -> String.format("%s %s", fieldError.getField(), fieldError.getDefaultMessage())) .sorted() .collect(Collectors.toList()); Map<String, Object> errorMessageMap = CollectionUtils.newLinkedHashMap(2); errorMessageMap.put("code", HttpStatus.BAD_REQUEST.value()); errorMessageMap.put("message", errorMessages); return ResponseEntity.badRequest().body(errorMessageMap); }}5. 查看校验成果应用 curl 拜访接口: ...

August 20, 2022 · 3 min · jiezi

关于spring-mvc:从零搭建-Spring-MVC-项目-HelloWorld

1. 继承 Spring Boot 我的项目<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.2</version> <relativePath/></parent>2. 引入 Spring MVC 依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>3. 编写 Controller 代码@RestControllerpublic class HelloWorldController { @GetMapping("/hello") public String hello(@RequestParam(value = "name", defaultValue = "World") String name) { return String.format("Hello %s!", name); }}4. 编写启动类@SpringBootApplicationpublic class HelloWorldApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldApplication.class, args); }}5. 运行启动类运行启动类,在浏览器中输出:http://localhost:8080/hello?name=小穆 ,即可看到如下成果:

August 20, 2022 · 1 min · jiezi

关于spring-mvc:React组件应用于Spring-MVC工程

背景公司前端工程技术栈好处于React+Mobx与Spring MVC(freemarker+jQuery)两种技术栈共存的阶段,两种技术栈页面存在一些雷同的业务性能点,如果别离开发和保护,就须要双倍的人力老本,因而,下文将尝试将React业务组件在webpack、babel等利器的帮忙下利用于Spring MVC我的项目。 利用一、简略封装组件挂载与卸载办法React业务组件就是FunctionComponent或者ClassComponent,须要利用react-dom中的render办法解决,转化成Fiber双向链表树,造成虚构DOM,最初转成理论的HTMLElement追加到页面上。因而,在Spring MVC中应用须要抛出挂载与卸载的办法: // 引入polyfill,前面会将为什么不必@babel/polyfillimport 'react-app-polyfill/ie9';import 'react-app-polyfill/stable';import React from 'react';import ReactDOM from 'react-dom';import { MediaPreview } from './src/MediaPreview';// 引入组件库全副款式,前面会做css tree shaking解决import '@casstime/bricks/dist/bricks.development.css';import './styles/index.scss';;(function () { window.MediaPreview = (props, container) => { return { // 卸载 close: function () { ReactDOM.unmountComponentAtNode(container); }, // 挂载 open: function (activeIndex) { ReactDOM.render(React.createElement(MediaPreview, { ...props, visible: true, activeIndex: activeIndex || 0 }), container); // 或者 // ReactDOM.render(<MediaPreview {...{ ...props, visible: true, activeIndex: activeIndex || 0 }} />, container); }, }; };})();二、babel转译成ES5语法标准,polyfill解决兼容性apibabel在转译的时候,会将源代码分成syntax和api两局部来解决 ...

August 5, 2022 · 5 min · jiezi

关于spring-mvc:Spring-MVC流程简单解析

Spring MVC是以后Java Web应用最支流的架构模式,明天具体介绍下MVC的转发流程:1.首先当一个用户申请打过去,DispatcherServlet首先收到,将用户申请门路和参数封装,交给HandlerMaping进行查找匹配,期间如果有拦截器,则须要先通过定义的拦截器,HandlerMaping解决实现将后果返回DispatcherServlet。2.DispatcherServlet将返回后果交给HandlerAdapter进行解决,HandlerAdapter将工作转交给Controller进行解决,解决后的ModelAndView数据给HandlerAdapter,HandlerAdapter再转交给DispatcherServlet。3.DispatcherServlet调用View Reslover进行视图渲染解析,将渲染后的数据交给视图核心,视图核心将后果传递DispatcherServlet。4.此时数据渲染完结,由DispatcherServlet将渲染后的数据传递给用户。

July 20, 2022 · 1 min · jiezi

关于spring-mvc:Spring-Boot-ObjectMapper-配置不生效问题

问题后盾接管 Json 参数时有以下要求: 指定工夫格局疏忽不辨认的字段疏忽不辨认的枚举个别是配置 ObjectMapper 即可失效 配置 ObjectMapper@Bean@Primarypublic ObjectMapper objectMapper() { return new ObjectMapper() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL) .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));}如上配置没有失效 配置 Jackson2ObjectMapperBuilderCustomizer@Bean@Primarypublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return builder -> builder .featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .featuresToEnable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL) .simpleDateFormat("yyyy-MM-dd HH:mm:ss");}也不失效 解决方案解决方案援用自 Jackson2ObjectMapperBuilderCustomizer不失效解决不失效的起因个别是 MappingJackson2HttpMessageConverter 对象在程序启动时创立了多个,咱们只有将多余的去掉,并从新增加 MappingJackson2HttpMessageConverter 的 bean 就能够了 问题本源根底包中配置了 MappingJackson2HttpMessageConverter,导致应用服务工程中配置的 ObjectMapper 有效 @Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Autowired private RequestApiInterceptor requestApiInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(requestApiInterceptor).addPathPatterns("/**"); } @Bean public RequestApiInterceptor restfulApiInterceptor() { return new RequestApiInterceptor(); } /** * 解决controller返回string类型数据谬误 */ @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(0, new MappingJackson2HttpMessageConverter()); }}要害代码在应用服务工程中按如下配置性能失效 ...

June 17, 2022 · 1 min · jiezi

关于spring-mvc:Spring-MVC-前端控制器-DispatcherServlet处理流程

Spring MVC 申请解决流程 用户发动申请,到 DispatcherServlet;而后到 HandlerMapping 返回处理器链(蕴含拦截器和具体解决的 Handler);调用处理器链的适配器 HandlerAdapter 来解决;执行具体的办法,比方 @RequestMapper润饰的逻辑解决办法;返回后果的视图解析器;最初进行视图解析和渲染返回后果给用户; DispatcherServletDispatcherServlet是前置控制器,配置在web.xml文件中的。拦挡匹配的申请,Servlet拦挡匹配规定要本人定义,把拦挡下来的申请,根据相应的规定散发到指标Controller来解决,是配置spring MVC的第一步。DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中拜访点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而能够取得Spring的所有益处。源码剖析org.springframework.web.servlet.DispatcherServlet#doDispatch 办法是次要解决申请的源码如下:protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { try { try { // 文件上传相干 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // DispatcherServlet收到申请调用处理器映射器HandlerMapping。 // 处理器映射器依据申请url找到具体的处理器,生成处理器执行链HandlerExecutionChain(包含处理器对象和处理器拦截器)一并返回给DispatcherServlet。 mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } 4.DispatcherServlet依据处理器Handler获取处理器适配器HandlerAdapter, HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. HTTP缓存相干 String method = request.getMethod(); boolean isGet = HttpMethod.GET.matches(method); if (isGet || HttpMethod.HEAD.matches(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } // 前置拦截器 if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 返回false就不进行后续解决了 return; } // 执行HandlerAdapter解决一系列的操作,如:参数封装,数据格式转换,数据验证等操作 // 执行处理器Handler(Controller,也叫页面控制器)。 // Handler执行实现返回ModelAndView // HandlerAdapter将Handler执行后果ModelAndView返回到DispatcherServlet mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } // 如果没有视图,给你设置默认视图 json疏忽 applyDefaultViewName(processedRequest, mv); //后置拦截器 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } // DispatcherServlet将ModelAndView传给ViewReslover视图解析器 // ViewReslover解析后返回具体View // DispatcherServlet对View进行渲染视图(行将模型数据model填充至视图中)。 // DispatcherServlet响应用户。 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err));}finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } }}} 复制代码在doDispatch方中曾经涵盖了DispatcherServlet的主要职责:1、文件上传解析,如果申请类型是multipart将通过MultipartResolver进行文件上传解析;2、通过HandlerMapping,将申请映射到处理器(返回一个HandlerExecutionChain,它包含一个处理器、多个HandlerInterceptor拦截器);3、通过HandlerAdapter反对多种类型的处理器(HandlerExecutionChain中的处理器);4、通过ViewResolver解析逻辑视图名到具体视图实现;5、本地化解析;6、渲染具体的视图等;7、如果执行过程中遇到异样将交给HandlerExceptionResolver来解析。DispatcherServlet初始化的上下文加载的Bean是只对SpringMVC无效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,该初始化上下文只加载Web相干组件。DispatcherServlet初始化次要做了如下两件事件:1、初始化SpringMVC应用的Web上下文,并且可能指定父容器为(ContextLoaderListener加载了根上下文);2、初始化DispatcherServlet应用的策略,如HandlerMapping、HandlerAdapter等。 ...

May 28, 2022 · 2 min · jiezi

关于spring-mvc:SpringMVC-的五大核心组件

什么是 SpringMVC SpringMVC 是一个 WEB 层、管制层框架,次要用来负责与客户端交互,业务逻辑的调用。 SpringMVC 是 Spring 家族的一大组件.Spring 整合 SpringMVC 能够做到无缝集成。 特点,简略易用性能佳。 Java 全套学习材料支付链接:http://www.atguigu.com/download.shtml 为什么有了 Servlet 还要学 SpringMVC 1:Servlet 的开发配置绝对麻烦,servlet 特地多的时候 web.xml 文件将会十分臃肿 2:每个 Servlet 都只能解决一个性能,如果须要多个性能就须要开发多个 Servlet,我的项目中存在大量 Servlet 显得臃肿。 3:获取申请参数 进行类型转换 封装数据到 bean 的 过程比拟繁琐。 4:其余开发中不不便的中央,例如,乱码问题,数据格式解决,表单校验 SpringMVC 的组件 1:前端控制器(DispatcherServlet) 实质上是一个 Servlet,相当于一个中转站,所有的拜访都会走到这个 Servlet 中,再依据配置进行直达到相应的 Handler 中进行解决,获取到数据和视图后,在应用相应视图做出响应。 2:处理器映射器(HandlerMapping) 实质上就是一段映射关系,将拜访门路和对应的 Handler 存储为映射关系,在须要时供前端控制器查阅。 3:处理器适配器(HandlerAdapter) 实质上是一个适配器,能够依据要求找到对应的 Handler 来运行。前端控制器通过处理器映射器找到对应的 Handler 信息之后,将申请响应和对应的 Handler 信息交由处理器适配器解决,处理器适配器找到真正 handler 执行后,将后果即 model 和 view 返回给前端控制器 4:视图解析器(ViewResolver) 实质上也是一种映射关系,能够将视图名称映射到真正的视图地址。前端控制器调用处理器适配实现后失去 model 和 view,将 view 信息传给视图解析器失去真正的 view。 ...

April 19, 2022 · 1 min · jiezi

关于spring-mvc:编写Spring-MVC控制器的14个技巧

通常,在Spring MVC中,咱们编写一个控制器类来解决来自客户端的申请。而后,控制器调用业务类来解决与业务相干的工作,而后将客户端重定向到逻辑视图名称,该名称由Spring的调度程序Servlet解析,以出现后果或输入。这样就实现了典型的申请-响应周期的往返。 应用@Controller构造型这是创立能够解决一个或多个申请的控制器类的最简略办法。仅通过用构造型正文一个类@Controller ,例如: import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class HomeController { @RequestMapping("/") public String visitHome() { return "home"; }}如你所见,visitHome()办法通过重定向到名为home的视图来解决来自应用程序上下文门路(/)的申请。 留神:@Controller原型只能在Spring的配置文件中启用注解驱动时应用: <annotation-driven /> 启用正文驱动时,Spring容器主动在以下语句指定的包下扫描类: <context:component-scan base-package="net.codejava.spring" />由@Controller 正文正文的类被配置为控制器。这是最可取的,因为它很简略:无需在配置文件中为控制器申明bean。 留神:通过应用@Controller 注解,您能够领有一个多动作控制器类,该类可能解决多个不同的申请。例如: @Controllerpublic class MultiActionController { @RequestMapping("/listUsers") public ModelAndView listUsers() { } @RequestMapping("/saveUser") public ModelAndView saveUser(User user) { } @RequestMapping("/deleteUser") public ModelAndView deleteUser(User user) { }}正如你能够在下面的控制器类看,有解决三种不同的申请3种解决办法 /listUsers,/saveUser,和/deleteUser别离。 实现控制器接口在Spring MVC中创立控制器的另一种(兴许是经典的)办法是让类实现 Controller 接口。例如: import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;public class MainController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("Welcome main"); return new ModelAndView("main"); }}实现类必须重写该 handleRequest() 办法,当匹配申请进入时,该办法将由Spring调度程序Servlet调用。此控制器解决的申请URL模式在Spring的上下文配置文件中定义如下: ...

January 4, 2022 · 3 min · jiezi

关于spring-mvc:PathVariable和RequestParam的区别

简言之,@PathVariable用于接管在url门路中的参数,@RequestParam用于接管申请中的参数。例如: @RequestMapping("/hello/{id}")public String getDetails(@PathVariable(value="id") String id,@RequestParam(value="param1", required=true) String param1,@RequestParam(value="param2", required=false) String param2) {...}@RequestParam 反对上面四种参数defaultValue 如果本次申请没有携带这个参数,或者参数为空,那么就会启用默认值name 绑定本次参数的名称,要跟URL下面的一样required 这个参数是不是必须的value 跟name一样的作用,是name属性的一个别名 而@PathVariable 比@RequestParam少一个defaultValue

December 20, 2021 · 1 min · jiezi

关于spring-mvc:springmvc01Spring-MVC基本概念

1.1 Spring MVC基本概念 DispatcherServlet 前端控制器,前端用户的request申请通过DispatcherServlet分发给各个控制器来生成业务数据Model,再通过DispatcherServlet传递给View实现最终的页面出现。能够说Spring MVC将数据业务逻辑和页面出现拆散是通过DispatcherServlet实现的。HandlerAdapter Handler是DispatvherServlet外部应用的一个类,是DispatcherServlet调用Controller的一个两头过渡对象,能够看做是controller的一种表现形式,在Spring MVC中,通过各种annotation来辨认Controller,然而Spring MVC中没有相似于接口的controller或者interface来找到controller,最终controller以handler模式呈现。HandlerAdapter是适配器模式,将各种不同类型的handler适配成DispatcherServlet能够应用的handler,DispatcherServlet就能够很轻松的调用controller。HandlerInterceptor拦截器,在被拦挡对象的前后增加操作,这个接口有三种办法,preHandle,postHandle,afterCpmpletion。HandlerMappingMapping就是DispatcherServlet和Controller之间映射关系的一品种,负责通知DispatcherServlet在一个申请到来之后由哪一个Controller来响应本次申请。在HandlerMapping工作结束之后,会给DispatcherServlet返回一个HandlerAdapter,其中包含的内容一方面是某一个Controller具体的实例,另一方面是Controller被包裹的HnadlerInterceptor,形成了一个执行的链条HandlerExecutionChain往下走。HandlerExecutionChainModelAndView无论是Model还是Map,最终在DispatcherServlet中都会转换成ModelAndView,所以能够把ModelAndView看作Model的具体表现。

December 7, 2021 · 1 min · jiezi

关于spring-mvc:Spring-MVC-SortDefault多字段排序

在SpringMVC中,咱们能够应用@SortDefault或@PageableDefault来疾速的实现Pageable的默认排序。 咱们能查问到的大多数是对某一个字段进行排序: @PageableDefault(sort = {"weight"}, direction = Sort.Direction.DESC) Pageable pageable@SortDefault(sort = {"weight"}, direction = Sort.Direction.ASC) Pageable pageable或者对某几个字段进行排序,但排序的规定是雷同的(比方均为升序): @SortDefault(sort = {"weight", "createTime"}, direction = Sort.Direction.ASC) Pageable pageable如果咱们想设置多个排序字段,且各个排序字段的排序形式还不统一,则能够应用如下代码: public Page<Notice> page(@SortDefault.SortDefaults({ @SortDefault(sort = {"weight"}, direction = Sort.Direction.ASC), @SortDefault(sort = {"createTime"}, direction = Sort.Direction.DESC)}) Pageable pageable) {此时,上述代码便起到了先按weight进行升序排列,而后再按createTime进行逆序排序。

December 3, 2021 · 1 min · jiezi

关于spring-mvc:DispatchServlet源码解析

doDispatch()protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // 为以后申请匹配处理器(HandlerExecutionChain) mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 为以后申请匹配HandlerAdapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } ... processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } ... }HandlerExecutionChain.class处理器实质上蕴含了HandleMethod和HandlerInterceptor的执行链 ...

November 5, 2021 · 2 min · jiezi

关于spring-mvc:spring-mvc-关于对optional的处理和自定义处理

springmvc4.1+可能反对optional参数,但不反对对象内field的optional。 举个例子 //对于这种间接在办法上定义的optional的根本类型或者援用类型//比方参数里没有id,或者没有obj,那么spring mvc会设置一个空的Optional对象//咱们能够通过Optional对象进行空判断@GetMapping("/get")public void test1(Optional<String> id, Optional<Object> obj) { id.ifPresent(i->{ });} //然而对于援用类型里field的Optional的话,spring mvc不反对//定义一个对象,外面属性用Optional类型@Datapublic class TestVo { Optional<Integer> id; Optional<String> name; } //如果这时候参数传了id,那么testVo.getId().get()能够拿到值//然而如果没有传name,这时的testVo的name属性为null而不是Optional的empty类型@GetMapping("/get")public Object test(TestVo testVo) { System.err.println(testVo.getId().get()); System.err.println(testVo.getName().isPresent()); //报空指针异样 return testVo;}咱们来看看springmvc是怎么解决的? 对于办法参数,spring mvc是如何赋值的呢? mvc有个RequestMappingHandlerAdapter,名称能够看出申请映射解决适配,就是它匹配咱们拜访的url门路和controller的requestMapping门路的,其中蕴含了一个HandlerMethodReturnValueHandler,处理结果赋值,以及HandlerMethodArgumentResolver(咱们讲这个),解决办法参数解析,就是由它进行参数赋值的,它有很多实现类,比方PathVariableMapMethodArgumentResolver就是咱们在参数上定义一个 @PathVariable时进行赋值的实现,RequestParamMapMethodArgumentResolver就是咱们在参数上定义一个 @RequestParam时进行赋值的实现。 那么平时默认的没有注解的援用类型,是通过哪个解析器呢?通过断点可知是通过ServletModelAttributeMethodProcessor来实现的。外面有WebDataBinder(题外话,WebDataBinder里有个ConversionService,这是spring提供的一个转换接口,底层应用BeanWrapper进行bean的操作),理论实现类是ExtendedServletRequestDataBinder(该类就是进行数据绑定的),bind办法里就是获取request的参数列表,因为咱们只传了id,没有传name,所以这里返回的MutablePropertyValues时外面就只有id(问题就出在这里),并设置id的值。 对于援用类型会应用到PropertyDescriptor(一系列的,属于java bean的标准)类设置列属性的值,TypeDescriptor记录属性类型,而后会依据属性名和参数类型获取PropertyEditor(PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName)),如果editor为空的话,就会优先应用后面提到的ConversionService(ConversionService conversionService = this.propertyEditorRegistry.getConversionService())实现参数类型转换。断点能够看到对于id字段应用的是ObjectToOptionalConverter类型,其实对于web参数申请类型,源参数类型都为string类型,也就是(TypeDescriptor的类型为string)。 发现如果对象外面还有个援用类型的属性字段且是Optional类型,则springmvc会抛异样Auto-growing not allowed with private constructor: private java.util.Optional(),这是因为,在springmvc进行赋值时,首先会调用无参结构初始对象,这时候因为java的泛型擦除,只能获取到Optional类型,而不能获取到具体的类型,Optional的结构是公有的就报错了。。所以springmvc是不反对对象嵌套应用Optional的。 那咱们须要对象里的根本类型字段设置Optional怎么弄呢? 原本想着在执行完springmvc的赋值前或者赋值后,设置对象里为null的Optional字段,后果看了一下,代码里写的很死,不能扩大webDataBinder,除非重写RequestMappingHandlerAdapter的createDataBinderFactory办法,返回一个自定义的webdatabinder,这个就比拟麻烦不贴代码了。。

November 3, 2021 · 1 min · jiezi

关于spring-mvc:springmvc关于404的异常处理原理

默认url的话其实springmvc会有很多MappingHandler进行适配(HandlerAdapter), 像咱们通常的RequestHandlerMappingHandler(通过Controller和 RequestMapping注解定义的门路), 这时候如果咱们没有一个requestMapping的url是拜访的url,mvc就会匹配到一个ResourceHttpRequestHandler(查找动态文件的处理器), 所以mvc这时候不会报错,然而又其实又没有对应的动态文件。 通过所有filter之后,会来到tomcat的StandardWrapperValue来解决前面的逻辑(实际上就是dispatchServlet解决,之后交由tomcat来解决), tomcat也没有找到,这时候tomcat就会设置一些谬误参数javax.servlet.error.status_code等,就会用到tomcat的errorPage,属性,这里springmvc会本人加上/error门路(对应着springmvc的BasicController), 而后tomcat会重定向到/error,就会到BasicController解决

November 3, 2021 · 1 min · jiezi

关于spring-mvc:SpringMVCInitBinder

前言由@InitBinder注解润饰的办法用于初始化WebDataBinder对象,可能实现:从request获取到handler办法中由@RequestParam注解或@PathVariable注解润饰的参数后,如果获取到的参数类型与handler办法上的参数类型不匹配,此时能够应用初始化好的WebDataBinder对获取到的参数进行类型解决。一个经典的例子就是handler办法上的参数类型为Date,而从request中获取到的参数类型是字符串,SpringMVC在默认状况下无奈实现字符串转Date,此时能够在由@InitBinder注解润饰的办法中为WebDataBinder对象注册CustomDateEditor,从而使得WebDataBinder能将从request中获取到的字符串再转换为Date对象。 通常,如果在@ControllerAdvice注解润饰的类中应用@InitBinder注解,此时@InitBinder注解润饰的办法所做的事件全局失效(前提是@ControllerAdvice注解没有设置basePackages字段);如果在@Controller注解润饰的类中应用@InitBinder注解,此时@InitBinder注解润饰的办法所做的事件仅对以后Controller失效。本篇文章将联合简略例子,对@InitBinder注解的应用,原理进行学习。 SpringBoot版本:2.4.1 注释一. @InitBinder注解应用阐明以前言中提到的字符串转Date为例,对@InitBinder的应用进行阐明。 @RestControllerpublic class LoginController { private static final String DATE_STRING = "20200620"; private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); private final Student student; public LoginController() { student = new Student(); student.setName("Lee"); student.setAge(20); student.setSex("male"); try { student.setDate(dateFormat.parse(DATE_STRING)); } catch (ParseException e) { System.out.println(e.getMessage()); } } @RequestMapping(value = "/api/v1/student/date", method = RequestMethod.GET) public ResponseEntity<Object> getStudentByDate(@RequestParam(name = "date") Date date) { if (student.getDate().equals(date)) { return new ResponseEntity<>(student, HttpStatus.OK); } else { return new ResponseEntity<>(String.format("get student failed by date: %s", date.toString()), HttpStatus.BAD_REQUEST); } }}@Datapublic class Student { private String name; private int age; private String sex; private Date date;}下面写好了一个简略的Controller,其中有一个Student成员变量,用于客户端获取,getStudentByDate()接口实现从申请中获取日期并与Controller中的Student对象的日期进行比照,如果统一,则向客户端返回Student对象。 ...

June 10, 2021 · 4 min · jiezi

关于spring-mvc:Error-creating-bean-with-name-userDao

问题形容 “Error creating bean with name 'userDao': Unsatisfied dependency expressed through field 'jdbcTemplate'” 形似: Error creating bean with name “xxx”: unsatisfied dependency expressed throuh field “xxxx” ⚠️ 谬误状态下的 userDao 和 jdbcTemplate下是有红线报错的! 谬误剖析上述表明: 没有创立 userDao的 bean,不满足 依赖字段“jbdcTemplate” 没有设置 注解扫描器,则 扫描包时,无奈注入注解到ICO容器 次要起因是 存在两个 spring配置文件,此时须要应用的 是 另一个,而另一个没有写扫描器和其余bean配置 <!-- 创立dataSource数据源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"/> <!-- 创立spring对jdbc反对的工具类 jdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>⚠️ UserDao是jdbcTemplate实现的,如果没有写上述代码,就没有dataSource和 jdbcTemplate,所以 userDao就没有 ♂️: 这是应用spring来实现jdbc的配置,注入的形式 而不是 应用java原生的连贯jdbc 问题解决增加相干 依赖 <!-- 创立dataSource数据源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"/> <!-- 创立spring对jdbc反对的工具类 jdbcTemplate--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> ...

June 5, 2021 · 1 min · jiezi

关于spring-mvc:简述一下SpringMVC的执行流程多看几遍对你没有坏处

MVC简介MVC是一种软件设计规范,模型(Model)、视图(View)、控制器(Controller)的缩写.MVC是一种常见的架构模式,其目标是为理解耦!Model(模型):数据模型提供页面要展现的数据,也叫业务逻辑层。模型层是一个宽泛的概述,模型层包含Service层、Dao层。View(视图):负责进行数据模型 + 视图框架的展现,也就是咱们看到的网页!Controller(控制器):接管用户申请,委托给模型进行解决,处理完毕后把返回的模型数据返回给视图,由视图负责展现。在MVC架构提出之前,Web页面的开发是只有模型、视图两层;也就是说没有Controller管制层,上面先来看看为什么MVC会胜利取代传统的两层架构在这里集体整顿了一些材料,有须要的敌人能够间接点击支付。 Java基础知识大全 22本Java架构师外围书籍 从0到1Java学习路线和材料 1000+道2021年最新面试题 长处:架构简略,容易实现。 毛病:视图层的职责不繁多;不仅须要对数据进行封装,还须要编写逻辑代码调用模型层也就是说这里的视图层充当了视图 + 管制两个职责;视图层间接与模型层打交道页面及其的凌乱、不利于保护 MVC架构提出是为了将视图与模型层离开,二者不间接打交道;而是通过管制层来从当二者交互的桥梁; 视图层只须要专一于数据封装与展现 模型层专一于业务逻辑 管制层负责解决用户递交的申请,并且协调视图与模型层 SpringMVC执行流程SpringMVC框架的外围围绕着DispatcherServlet前端控制器进行开展,它用于协调所有的Servlet对用户的申请进行解析、查找对应的Servlet进行解决、最初给出响应!能够将DispatcherServlet性能相似于CPU处理器、人类的大脑… 用户通过视图页面或者是url地址门路发动申请,前端管制DispatcherServlet接管用户的申请开始运作!DispatcherServlet调用HandlerMapping找到最终用于执行的HandlerHandlerExecution中包含具体的执行器Handler、HandlerInterceptor处理器拦截器。将其返回交给前端控制器DispatcherServlet。将获取到的HandlerExecution对象匹配对应的处理器适配器HandlerAdapter,将其进行解析。处理器适配器HandlerAdapter最终胜利匹配到程序员写的Controller层的Servlet类。Controller层职责明显,调用模型层进行数据库的拜访,并且获取到最初须要响应给用户的数据、视图。Controller层中将数据、视图封装在ModelAndView对象中,而后将其返回给处理器适配器HandlerAdapter。处理器适配器HandlerAdapter接管到Controller返回后果进行解决,而后移交给前端控制器DispatcherServlet。前端控制器DispatcherServlet调用视图解析器ViewResolver;ViewResolver解析ModelAndView中的数据、解析响应的视图名、找到对应的视图、最初将数据封装到视图中!视图解析器ViewResolver将视图名字返回给前端控制器DispatcherServlet,最初前端控制器DispatcherServlet调用响应的视图展现给用户!第一个SpringMVC程序JSP页面<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h1>${message}</h1></body></html>编写对应的Servlet(Controller)public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { // 1. 创立模型-视图 ModelAndView mv = new ModelAndView(); //调用业务层 // 2. 封装数据对象 mv.addObject("message","Hello, SpringMVC!"); // 3. 封装要跳转的视图,放在ModelAndView中 mv.setViewName("hellomvc"); return mv; }}配置SpringMVC外围文件外围配置文件中,配置映射器、适配器、解析器;最初将申请的门路以及对应的Servlet类交给IOC容器托管。 <?xml version="1.0" encoding="UTF8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1. 配置处理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 2. 配置处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 3. 配置视图解析器 --> <bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/page/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean> <!-- 4. 将servlet交给IOC容器治理 --> <bean id="/hellomvc" class="com.controller.HelloController"/></beans>配置映射门路解决因为所有的Sevlet不在走各自的映射门路,而是对立由前端控制器DispatcherServlet调度,所以只须要在我的项目的web.xml中配置DispatcherServlet即可。而后将SpringMVC外围配置文件交给前端控制器DispatcherServlet主持! ...

May 17, 2021 · 1 min · jiezi

关于spring-mvc:SpringMVC基础之三SpringMVC的使用

1、SpringMVC的返回JSON数据 到目前为止咱们编写的所有Controller的办法的返回值都是String类型,然而大家应该都晓得,咱们有时候数据传递特地是在ajax中,咱们返回的数据常常须要应用json,那么如何来保障返回的数据的是json格局呢?应用@ResponseBody注解 pom.xml <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mashibing</groupId> <artifactId>springmv_ajax</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.3</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.3</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.10.3</version> </dependency> </dependencies></project>springmvc.xml ...

April 29, 2021 · 10 min · jiezi

关于spring-mvc:SpringMVC基础之三SpringMVC的使用

1、SpringMVC的返回JSON数据 到目前为止咱们编写的所有Controller的办法的返回值都是String类型,然而大家应该都晓得,咱们有时候数据传递特地是在ajax中,咱们返回的数据常常须要应用json,那么如何来保障返回的数据的是json格局呢?应用@ResponseBody注解 pom.xml <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mashibing</groupId> <artifactId>springmv_ajax</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.3</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.3</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.10.3</version> </dependency> </dependencies></project>springmvc.xml ...

April 26, 2021 · 10 min · jiezi

关于spring-mvc:HTTP-Status-500-–-Servletinit-for-servlet-springmvc-报错

近几天在做毕设的时候常常会呈现以下谬误HTTP Status 500 – Internal Server Error -Servlet.init() for servlet [springmvc] threw exception前一天关机前还能够失常运行,第二天重新启动时就报错。起初尝试clean了一下竟然就运行胜利了,然而还是不晓得是什么起因导致500

April 20, 2021 · 1 min · jiezi

关于spring-mvc:SpringMVC异常处理

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

April 16, 2021 · 1 min · jiezi

关于spring-mvc:传统JavaWeb的文件上传和SpringMVC提供额的文件上传

传统JavaWeb的文件上传1.前提 1.1form 表单的 enctype 取值必须是:multipart/form-data(用分隔符将表单分为几个局部,其中有表单元素的名称,也有你抉择的文件) (默认值是:application/x-www-form-urlencoded,它设置了将表单数据以键值对的模式上传) enctype:是表单申请注释的类型1.2 method 属性取值必须是 Post1.3 提供一个文件抉择域<input type=”file” />2.文件上传原理当 form 表单的 enctype 取值不是默认值后,request.getParameter()将生效。 enctype=”application/x-www-form-urlencoded”时,form 表单的注释内容是:key=value&key=value&key=value当 form 表单的 enctype 取值为 Mutilpart/form-data 时,申请注释内容就变成:每一部分都是 MIME 类型形容的注释-----------------------------7de1a433602ac 分界符Content-Disposition: form-data; name="userName" 协定头aaa 协定的注释-----------------------------7de1a433602acContent-Disposition: form-data; name="file"; filename="C:\Users\zhy\Desktop\fileupload_demofile\b.txt"Content-Type: text/plain 协定的类型(MIME 类型)bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-----------------------------7de1a433602ac-- 这时须要先解析表单传输的数据体,找到表单上传的文件的局部,能力进行上传。借助jar包能够不便解析 3.借助第三方组件实现文件上传应用 Commons-fileupload 组件实现文件上传,须要导入该组件相应的撑持 jar 包:Commons-fileupload 和commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时须要 commons-io 包的反对导入依赖 <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>SpringMVC的文件上传 与传统文件上传的区别在于,SpringMVC框架可能代替咱们去解析request,拿到须要上传的文件。为应用该性能只须要引入SpringMVC曾经创立好的一个用于解析request的类:CommonsMultipartResolver1.编写用于上传文件的jsp页面 <h3>SpringMVC形式上传</h3> <form name="upload" action="work/upload2" method="post" enctype="multipart/form-data"> 抉择文件:<input type="file" name="upload"/><br> <input type="submit" value="上传"/> </form>2.在springmvc.xml中配置CommonsMultipartResolver: ...

April 16, 2021 · 1 min · jiezi

关于spring-mvc:SpringMVC框架搭建过程

一 创立maven工程,选中webapp,批改项名 二 补全目录构造 三 导入依赖 1.批改版本号<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target></properties>2.版本锁定<properties> <spring.version>5.0.2.RELEASE</spring.version></properties>3.导入依赖<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency></dependencies>四 创立ContextConfiguration.xml 五 配置web.xml <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:ContextConfiguration.xml</param-value> </init-param></servlet><servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern></servlet-mapping>六 创立Collector类七 配置ContextConfiguration.xml

April 9, 2021 · 1 min · jiezi

关于spring-mvc:Spring微服务项目实现优雅停机平滑退出

Spring微服务项目实现优雅停机(平滑退出)为什么要优雅停机(平滑退出) 不论是生产环境还是测试环境,在公布新代码的时候,不可避免的进行我的项目的重启 kill -9 `ps -ef|grep tomcat|grep -v grep|grep server_0001|awk '{print $2}' 以上是我司生产环境停机脚本,能够看出应用了 kill -9 命令把服务过程杀掉了,这个命令是十分暴力的,相似于间接按了这个服务的电源,显然这种形式对进行中的服务是很不友善的,当在停机时,正在进行RPC调用、执行批处理、缓存入库等操作,会造成不可挽回的数据损失,减少前期保护老本。 所以就须要优雅停机出场了,让服务在收到停机指令时,从容的回绝新申请的进入,并执行完当前任务,而后敞开服务。Java优雅停机(平滑退出)实现原理linux信号机制 简略来说,信号就是为 linux 提供的一种解决异步事件的办法,用来实现服务的软中断。 服务间能够通过 kill -数字 PID 的形式来传递信号 linux信号表kill -l 能够通过 kill -l 命令来查看信号列表: 取值名称解释默认动作1SIGHUP挂起 2SIGINT中断 3SIGQUIT退出 4SIGILL非法指令 5SIGTRAP断点或陷阱指令 6SIGABRTabort收回的信号 7SIGBUS非法内存拜访 8SIGFPE浮点异样 9SIGKILLkill信号不能被疏忽、解决和阻塞10SIGUSR1用户信号1 11SIGSEGV有效内存拜访 12SIGUSR2用户信号2 13SIGPIPE管道破损,没有读端的管道写数据 14SIGALRMalarm收回的信号 15SIGTERM终止信号 16SIGSTKFLT栈溢出 17SIGCHLD子过程退出默认疏忽18SIGCONT过程持续 19SIGSTOP过程进行不能被疏忽、解决和阻塞20SIGTSTP过程进行 21SIGTTIN过程进行,后盾过程从终端读数据时 22SIGTTOU过程进行,后盾过程想终端写数据时 23SIGURGI/O有紧急数据达到以后过程默认疏忽24SIGXCPU过程的CPU工夫片到期 25SIGXFSZ文件大小的超出下限 26SIGVTALRM虚构时钟超时 27SIGPROFprofile时钟超时 28SIGWINCH窗口大小扭转默认疏忽29SIGIOI/O相干 30SIGPWR关机默认疏忽31SIGSYS零碎调用异样 Java通过ShutdownHook钩子接管linux停机信号 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { logger.info("========收到敞开指令========"); logger.info("========登记Dubbo服务========"); shutdownDubbo(); logger.info("========登记ActiveMQ服务========"); shutdownActiveMQ(); logger.info("========登记Quartz服务========"); shutdownQuartzJobs(); } }, SHUTDOWN_HOOK));//public static final String SHUTDOWN_HOOK = "Manual-ShutdownHook-@@@" java提供了以上办法给程序注册钩子(run()办法外部为自定义的清理逻辑),来接管停机信息,并执行停机前的自定义代码。 ...

March 12, 2021 · 5 min · jiezi

关于spring-mvc:假装是小白之重学Spring-MVC二

在伪装是小白之重学Spring MVC(一)中曾经介绍了Spring MVC比拟罕用的知识点,然而还是有些脱漏,比方将申请放入Session,在配置文件中配置太烦了,咱们是否将配置文件挪动至配置类中,又比方SSM(Spring Spring MVC MyBatis)整合。本篇的次要内容就是介绍这些,将配置文件转换成配置类须要懂一些Spring的外围注解,比方@Import,这个注解在欢迎光临Spring时代(一) 上柱国IOC列传曾经介绍过了,不懂的能够再翻一下这篇文章。放入session中咱们如何将数据放入session中呢? 在原生Servlet时代,咱们从HttpServletRequest中获取HttpSession对象就好,像上面这样: 当然你在Spring MVC框架还能够接着用,Spring MVC又提供了@SessionAttributes注解用于将数据放入Session中,@SessionAttribute用于将session中的值,通过翻阅源码,咱们能够发现@SessionAttributes只能作用于类上,在翻阅源码的过程中发现了@SessionAttribute注解,原本认为和@SessionAttributes是一样的用途 ,起初翻源码才发现,这个是用来取出Session中的值放到办法参数中,只能作用办法参数上。又通过看源码的正文,咱们能够看到SessionAttributes的两个value和name是同义语,假如有申请域(申请域中的数据都是呈K、V对模式,我门当初谈的就是key)中有和value值雷同的数据,那么就会将该数据也会放到Session中。而Type属性则是,只有是申请域的数据是该类型的,就放入到Session中。咱们当初来测试一下@SessionAttributes: ControllerSessionAttributes(value = "password")public class SessionDemoController { @RequestMapping(value = "/session", method = RequestMethod.GET) public String testGet(@RequestParam(value = "name") String userName, @RequestParam(value = "password") String password ,Model model) { System.out.println("username:" + userName); System.out.println("password:" + password); model.addAttribute("password",password); return "success"; }}success.jsp: <%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body><h1> success </h1><h1> username: ${sessionScope.userName}</h1><h1> password: ${sessionScope.password}</h1></body></html>url: http://localhost:8080/studySpringFrameWork_war_exploded/session?name=aa&&password=aaa 测试后果: SessionAttribute: RequestMapping(value = "/servlet", method = RequestMethod.GET) public String testGet(@RequestParam(value = "name") String userName, @SessionAttribute(value = "password")String password) { System.out.println("username:" + userName); System.out.println("password:" + password); return "success"; }url: http://localhost:8080/studySpringFrameWork_war_exploded/servlet?name=aaa测试后果: 能够看到url中没有password,password仍然打印进去有值,这个就是session中的值。 ...

March 10, 2021 · 3 min · jiezi

关于spring-mvc:假装是小白之重学Spring-MVC一

在编码一段时间之后,再从新看之前学过的框架,发现有新的认知,像Spring,我就重新学习了一把: 欢迎光临Spring时代-绪论欢迎光临Spring时代(一) 上柱国IOC列传代理模式-AOP绪论欢迎光临Spring时代(二) 上柱国AOP列传这次重学的是Spring MVC,以前学习Spring MVC的时候是在B站看的视频,的确不错,让我疾速入门了,然而我还是感觉不是很零碎,感觉知识点四分五裂,我心愿用我的形式将这些形式串联起来。在学习本篇之前,须要有Java EE和Spring Framework的根底,如果没有Java EE的根底,能够参看JavaWeb视频教程,如果没有Spring Framework的根底,请参看我下面的文章,如果感觉四篇有点多,能够先只看 欢迎光临Spring时代(一) 上柱国IOC列传,如果能够的话,还是倡议先看完下面四篇文章来看这四篇文章。 原生Servlet时代的问题简略的说Servlet是Java中的一个接口,位于javax.servlet下。咱们来看一下Servlet上的正文: A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients,usually across HTTP, the HyperText Transfer Protocol. Servlet是一个运行在Web 服务器中的一个小Java程序,Servlet接管和解决Web 客户端的申请,通常用于Http协定。咱们通常用的是它的实现类HttpServlet,而后重写doGet和doPost办法,像上面这样:WebServlet(name ="/servlet")public class ServletDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getParameterNames(); req.getParameter("username"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决post申请 super.doPost(req, resp); }}它有哪些痛点呢? 第一个就是取参数的问题,取参数只有这一种形式,参数一多就有点让人心烦了,不是那么的合乎面向对象的思维,程序员除了关怀业务逻辑的,还要关注如何获取参数,确实HttpServletRequest外面搁置的参数很多了,很全很全: 那getParameterNames去哪里了? HttpServletRequest 是一个接口,getParameterNames从ServletRequest继承而来。是否让程序员更加专一于业务逻辑一点呢,让取参数变的更简略一些,比方我想用学生类对象接管,又比方我须要的参数只有一个Long类型的id,接管参数的时候是否就间接让用Long id来接管呢。这是咱们提出的第一个问题,取参数是否变的简略一些。除了取参数,在Ajax技术曾经广泛利用的明天,是否让我响应前端的Ajax申请在简略一些呢? 在原生Servlet,咱们解决Ajax,咱们在响应中的设置编码,设置响应的类型,而后通过一些Java的JSON库将咱们的对象转成JSON模式,发送给前端,大抵上要这么做: ...

March 10, 2021 · 5 min · jiezi

关于spring-mvc:SpringMVC

1.MVC概述MVC(Model–view–controller)是软件工程中的一种软件架构模式,基于此模式把软件系统分为三个根本局部:模型(Model)、视图(View)和控制器(Controller)。目标是通过这样的设计使程序结构更加简洁、直观,升高问题的复杂度。其中各个组成部分的职责为: 视图(View) - UI设计人员进行图形界面设计,负责实现与用户交互。控制器(Controller)- 负责获取申请,解决申请,响应后果。模型(Model) - 实现业务逻辑,数据逻辑实现。咱们在软件设计时,通常要遵循肯定的设计准则。MVC架构模式的设计中,首先基于繁多职责准则(SRP-Single responsibility principle)让每个对象各司其职,各尽所能。而后再基于“高内聚,低耦合”的设计思维实现相干层对象之间的交互。这样能够更好进步程序的可维护性和可扩展性。 Spring MVC 是Spring 框架中基于MVC设计思维实现的一个用于解决Web申请的模块。其繁难架构剖析,如图所示: 外围组件剖析: DispatcherServlet :前端控制器, 解决申请的入口。HandlerMapping:映射器对象, 用于治理url与对应controller的映射关系。Interceptors:拦截器,实现申请响应的共性解决。Controller:后端控制器-handler, 负责解决申请的管制逻辑。ViewResolver:视图解析器,解析对应的视图关系(前缀+viewname+后缀)。2.SpringMVC的工作原理1、客户端收回一个http申请给web服务器,web服务器对http申请进行解析,如果匹配DispatcherServlet的申请映射门路(在web.xml中指定),web容器将申请转交给DispatcherServlet. 2、DipatcherServlet接管到这个申请之后将依据申请的信息(包含URL、Http办法、申请报文头和申请参数Cookie等)以及HandlerMapping的配置找到解决申请的处理器(Handler)。 3-4、DispatcherServlet依据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的解决进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。 5、Handler对数据处理实现当前将返回一个ModelAndView()对象给DispatcherServlet。 6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。 7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出残缺的view并返回给客户端。

March 9, 2021 · 1 min · jiezi

关于spring-mvc:spring-MVC实践

应用spring mvc提供restful格调的接口,实现前后端拆散,后端只提供数据接口,而不做页面渲染。因而可对接口做对立解决: 申请参数校验响应数据格式全局异样解决通过以上对立解决,开发人员可专一于业务解决,把校验,异样响应的逻辑分离出来。 申请参数校验: 对于url中的参数 如果增加@RequestParam,但没有传递该参数,则抛出MissingServletRequestParameterException异样如果增加@Max等注解,同时不满足该条件,抛出ConstraintViolationException 或BindException异样对于request body申请体中的参数 Bean前增加@RequestBody,如果没有申请体,抛出HttpMessageNotReadableException异样在bean前增加@Validate注解,bean中属性增加@Max,@NotNull等注解,即对响应属性进行校验,如果不满足,抛出MethodArguementNotValidException@Validate内可增加group,表明须要校验的操作,@Max可增加groups,当groups蕴含group时,则进行校验。Bean中也可自定义注解,通过实现ConstraintValidator接口自定义校验逻辑。如果校验失败,会抛出MethodArgumentNotValidException异样,这些异样都被全局异样解决拦挡,返回异样信息。 响应数据格式: 建设对立响应类JsonResp<T>,泛型T为业务响应内容,可为String,List,java bean等。定义属性result表明响应是否胜利,响应码code,响应码信息msg。这里code及msg与全局异样解决的响应枚举类绝对应。定义ResponseBodyhandler实现ResponseBodyAdvice接口,当响应类型为json时,如果响应类型为JsonResp,间接响应给客户端;如果不是,则new JsonResp,将响应体set进去,响应给客户端。在controller的办法返回类型可任意定义String,List,java bean,在ResponseBodyhandler转化为对立JsonResp模式。如果是流文件,则间接返回不会转化为JsonResp模式。这样可将响应包装成对立的JsonResp数据格式,便于前端解决。全局异样解决 建设响应枚举类ResponseEnum,定义业务须要的响应码及响应码信息建设自定义异样类BaseException,继承运行时异样RuntimeException,初始化时设置ResponseEnum。建设异样捕获类GlobalExceptionAspect,类中增加@RestCOntrollerAdvice注解,应用@Exceptional捕获参数校验异样和自定义异样BaseException。最外层捕获Exception,捕获未定义的异样如果遇到业务报错,throw new BaseException(ResponseEnum.xxx),抛出自定义异样,该异样由GlobalExceptionAspect切面捕获,对立响应至客户端对立定义异样响应码,便于查看防止在业务代码里进行异样的响应,简化代码 这些对立解决的实质是应用fliter或者aop拦挡申请和响应参数进行通用逻辑解决,因而,可对申请进行敏感词过滤,参数加解密等解决,解耦业务逻辑。

March 3, 2021 · 1 min · jiezi

关于spring-mvc:SpringMVC

1 Spring与Web环境集成1.1 ApplicationContext利用上下文利用上下文的获取形式 形式一 通过Spring配置文件形式获取 new classpathXmlApplicationContext弊病:配置文件加载屡次 利用上下文对象创立屡次 因为每次从容器中获取Bean都要编写上述代码 创建对象形式二 从域中获取利用上下文ApplicationContext对象 通过 ServletContextListener监听Web利用的启动 在web利用启动时,就加载Spirng的配置容器,创立利用上下文对象ApplicationContext, 在将其存储到最大的域servletContext域中,这样就能够在任意地位从域中取得利用上下文ApplicationContext对象了1.2 Spring提供利用上下文的工具Spring 提供了一个监听器ContextLoaderListener就是对上述性能的封装,该监听器外部加载Spring配置文件,创立利用上下文对象,并存储草ServletContext域中,提供了一个客户端工具 WebApplicationContextUtils供使用者取得利用上下文对象 办法 1 在web.xml中配置ContextLoaderListener监听器(导入Spring-web坐标) `<dependency> < ` 2 应用WebApplicationContextUtils取得利用上下文对象ApplicationContext1.3 导入Spring集成web坐标1.4 配置ContextLoaderListener监听器1.5 通过工具取得利用上下文对象2 SpringMVC的简介2.1 SpringMVC概述2.2 SpringMVC疾速入门2.3 SpringMVC流程试图2.4 常识要点3 ingMVC的组件解析3.1 SpringMVC的执行流程3.2 SpringMVC组件解析3.3 SpringMVC正文解析3.4 SpringMVC的XML配置解析3.5 只是要点4 ringMVC的数据相应4.1 数据相应形式(了解)4.2 返回字符串模式(利用4.3 页面跳转-返回ModelAndView模式1 (利用)4.4 页面跳转-返回ModelAndView模式2 (利用)4.5 页面跳转-返回ModelAndView模式3 (利用)4.6 回写数据-间接滑稽字符串 (利用)4.7 回写数据-间接回写json格局字符串 (利用)4.8 回写数据-返回对象或汇合 (利用)4.9 回写数据对象或汇合2 (利用)4.10 常识要点小结 (了解,记忆)5 SpringMVC申请5.1 取得申请参数-申请参数类型(了解)5.2 取得申请参数-取得根本类型参数(利用)5.3 取得申请参数-取得POJO类型参数(利用)5.4 取得申请参数-取得数组类型参数(利用)5.5 取得申请参数-取得汇合类型参数1(利用)5.6 取得申请参数-取得汇合类型参数2(利用)5.7 取得申请参数-动态资源拜访的开启(利用)5.8 取得申请参数-配置全局乱码过滤器(利用)5.9 取得申请参数-参数绑定注解@RequestParam(利用)5.10 取得申请参数-Restful格调的参数的获取(利用)5.11 取得申请参数-自定义类型转换器(利用)5.12 取得申请参数-取得Servlet相干API(利用)5.13 取得申请参数-取得申请头信息(利用)5.14 文件上传-客户端表单实现(利用)5.15 文件上传-文件上传的原理(了解)5.16 文件上传-单文件上传的代码实现1(利用)5.17 文件上传-单文件上传的代码实现2(利用)5.18 文件上传-多文件上传的代码实现(利用)5.19 常识要点(了解,记忆)

February 9, 2021 · 1 min · jiezi

关于spring-mvc:6-SpringBoot工程中Spring-MVC模块的应用

一.背景剖析当我的项目做的越来越来大时,我的项目中业务就会变得越来越简单,如果咱们只应用一个对象去解决所有的业务,这个对象的复杂度就会更高并且难以保护,生存中和理论我的项目中对相似问题的解决计划往往"分而治之"的思维.来升高业务复杂度,进步其可维护性.那当初的问题的是如何分,依照什么规定去分,这就须要有肯定的设计,于是MVC设计思维诞生. 二.MVC是什么?MVC是一种软件架构设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现,例如能够分为视图层(View),管制层(Controller),模型层(Model),通过这样的分层设计让咱们程序具备更好的灵活性和可可扩展性.因为这样能够将一个简单应用程序进行简化,实现各司其职,各尽所能.比拟适宜一个大型利用的开发。 1)是一种分层架构设计思维,也是一种套路工设计模式。2)是Model,View,Controller单词的缩写。Model(业务逻辑对象,业务层)View(显示逻辑对象,体现层)Controller(管制逻辑对象,管制层) 程序中的MVC? (Web利用)1.传统的web利用?企业中业务零碎->CRM,BOSS,ERP,EBanking,... 2.互联网利用?领取零碎,网约车,... 三.Spring 框架中Web模块中的MVC设计Spring MVC是MVC设计思维在Spring框架中的一种实现,基于这样的思维spring框架设计了一些相干对象,用于更好的基于MVC架构解决申请和响应,其繁难架构如图所示: 其外围组件有:1.DispathcherServlet(外围控制器,前端控制器,Controller)是客户端所有申请解决的入口,负责申请转发。 2.RequestMapping(申请映射)负责存储申请url到后端handler对象之间的映射。 3.Handler(申请处理器)用于解决DispatcherServlet对象转发过去的申请数据。 4.ModelAndView(业务数据和视图信息的对象)用于封装业务数据和视图信息的对象 5.ViewResolver(视图解析器,View)负责解决所有Handler对象响应后果中。 四.SpringBoot 工程中Web MVC 疾速入门实现筹备工作第一步:创立我的项目module,根本信息如图所示: 第二步:增加我的项目依赖(能够在module创立时,也能够创立后),代码如下:Spring Web 依赖(提供了spring mvc反对并且会嵌入一个tomcat) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>Thymeleaf 依赖(提供了以html作为页面模板进行解析和操作的相干对象) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>第三步:启动我的项目检测控制台启动状态,是否运行胜利static目录剖析及利用static 目录为springboot工程创立时增加了web依赖当前主动创立的目录,此目录中能够存储html、css、js、image,这些资源能够在启动服务器当前,间接在浏览器进行拜访。 例如: 第一步:在static目录下创立一个index.html页面,代码如下:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>The static directory index.html page</h1></body></html>第二步:启动服务器并间接进行拜访测试,如图所示 templates 目录剖析及利用templates 目录为springboot工程创立时增加了thymeleaf依赖当前主动创立的目录,此目录中要存储一些html模板,这个模板页面不能间接通过浏览器url进行拜访,须要基于后端控制器,在办法中定义页面响应,例如: 第一步:定义TemplateController及办法,代码如下:package com.cy.pj.health.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class TemplateController { @RequestMapping("doTemplate") public String doTemplateUI(){ return "default"; }}第二步:在templates目录中定义模板页面default.html,代码如下:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>The template directory default page</h1></body></html>其中,如果default.html要在放在templates子目录中,则还须要在配置文件中配置thymeleaf的前缀,例如: ...

December 29, 2020 · 1 min · jiezi

关于spring-mvc:深入解析SpringMVC核心原理从手写简易版MVC框架开始SmartMvc

简介SpringMVC能够说的上是以后最优良的MVC框架,采纳了涣散耦合可插拔组件构造,比其余MVC框架更具扩展性和灵活性;为了进步框架的扩展性和灵活性,设计了松耦合可插拔的组件。了解SpringMVC的原理,在面试或工作中都非常的重要。 SpringMVC的原理在网络上到处都能够找失去,然而写的都很概括、零散;对应浏览源码教训较少的小伙伴来说,本人去看源码被很多细节所烦扰妨碍,不可能很好的抽离出springMVC原理的主线。 本人想和小伙伴一起从手写简易版的SmartMVC框架登程,理出SpringMVC的主线并深刻了解SpringMVC的原理。框架代码开发加上文档编写大略破费工夫一个月 我的项目构造SmartMvc├── docs -- 开发文档├── smart-mvc -- 实现mvc性能的外围代码├── smartmvc-springboot-autoconfigure -- SmartMvc的自动化配置├── smartmvc-springboot-demo -- SmartMvc的demo我的项目├── smartmvc-springboot-starter -- SmartMvc的starter└── spring-mvc-demo -- SpringMVC的demoIDE、源码、依赖版本JDK的版本1.8整个开发过程中我应用的IDE都是IDEA,能够依据读者本人习惯抉择。当然我举荐是用IDEA开发SmartMVC咱们须要应用到Spring,我应用的版本5.2.9整个框架曾经开发实现,SmartMVC的源码地址: Github: https://github.com/silently9527/SmartMvc码云:https://gitee.com/silently9527/SmartMvc大家记得棘手给个star哦约定为了便于前期了解和应用SpringMVC,所以在SmartMVC中所有组件的名称都和SpringMVC的保持一致为了让SpringMVC的外围流程更加的清晰,缩小的烦扰,我拿出了本人18米的砍刀大胆的砍掉了SpringMVC中很多细节流程,达到去枝干立主脑,让咱们可能更加顺畅的了解申请的处理过程文档目录所有开发文档都在我的项目的docs目录下 01 SmartMVC总体架构布局02 RequestMappingHandlerMapping初始化过程03 拦截器HandlerInterceptor04 HandlerMapping获取对应的Handler05 参数解析器HandlerMethodArgumentResolver06 返回解析器HandlerMethodReturnValueHandler07 Handler执行器InvocableHandlerMethod08 实现RequestMappingHandlerAdapter09 视图InternalResourceView、RedirectView10 视图解析器ViewResolver11 DispatcherServlet实现doDispatch来实现申请逻辑12 全局异样处理器HandlerExceptionResolver13 外围配置类WebMvcConfigurationSupport14 SmartMvc与SpringBoot集成(一)15 SmartMvc与SpringBoot集成(二)16 SmartMvc我的项目实战SpringBoot我的项目中引入SmartMVC的步骤1. 新建一个SpringBoot我的项目,在pom.xml中退出SmartMVC的starter<dependency> <groupId>com.silently9527</groupId> <artifactId>smartmvc-springboot-starter</artifactId> <version>1.0.0-SNAPSHOT</version></dependency>2. 批改SpringBoot生成的启动类,指定SmartMVC的ApplicationContextClass@SpringBootApplicationpublic class SmartmvcSpringbootDemoApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(SmartmvcSpringbootDemoApplication.class); application.setApplicationContextClass(ServletWebServerApplicationContext.class); application.run(args); }}写到最初(点关注,不迷路)在开发文档中可能会存在谬误或不足之处,欢送大家指出。 创作不易,心愿敌人们能够点赞评论关注三连 原文地址,转载请注明出处:https://silently9527.cn/archives/88

December 28, 2020 · 1 min · jiezi

关于spring-mvc:上传文件异步处理注意事项

问题上传Excel进行解决 不必用户期待 解决完之后 会邮件告知处理结果所以是异步解决 public void readExcel(@RequestParam("file") MultipartFile file) { CompletableFuture.runAsync(() -> { try { service.readExcel(file); } catch (IOException e) { e.printStackTrace(); } });}理论应用的过程中 发现常常上传失败 报错如下 java.io.FileNotFoundException: /private/tmp/upload_2cc08ec8_c3eb_4633_8c0f_0cc20e34ff55_00000000.tmp (No such file or directory) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getInputStream(DiskFileItem.java:188) at org.apache.catalina.core.ApplicationPart.getInputStream(ApplicationPart.java:100) at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.getInputStream(StandardMultipartHttpServletRequest.java:297)起因申请返回后 会主动删除临时文件 导致理论读取Excel的时候 找不到文件 // org.apache.catalina.core.ApplicationPart#deletepublic void delete() throws IOException { fileItem.delete();}解决复制该临时文件 将复制后的文件传给异步程序处理 解决完之后删除该临时文件 String uuid = UUID.randomUUID().toString().replace('-', '_');String tmpFileName = String.format("/tmp/upload_%s.tmp", uuid);final File tmpFile = new File(tmpFileName);try { Files.copy(file.getInputStream(), tmpFile.toPath());} catch (IOException e) { e.printStackTrace();}CompletableFuture.runAsync(() -> { try { service.readExcel(tmpFile); } catch (IOException e) { e.printStackTrace(); }});参考文档https://stackoverflow.com/que... ...

December 19, 2020 · 1 min · jiezi

关于spring-mvc:你知道目前最流行的SpringMVC框架如何搭建吗

Spring MVC 是 Spring 家族中的一个 web 成员, 它是一种基于 Java 的实现了 Web MVC 设计思维的申请驱动类型的轻量级 Web 框架,即应用了 MVC 架构模式的思维,将 web 层进行职责解耦,基于申请驱动指的就是应用申请-响应模型,框架的目标就是帮忙咱们简化开发,Spring MVC 也是要简化咱们日常 Web 开发的。 Spring MVC 是服务到工作者思维的实现。前端控制器是 DispatcherServlet;利用控制器拆为处理器映射器(Handler Mapping)进行处理器治理和视图解析器(View Resolver)进行视图治理;反对本地化/国际化(Locale)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了弱小的约定大于配置(常规优先准则)的契约式编程反对。 SpringMVC 搭建的形式开发环境搭建新建 Maven webAppSpringmvc 环境 jar 包依赖配置 web.xml (前端控制器配置)servlet-context.xml 配置页面控制器的编写增加视图页面启动 jetty 服务器案例实操开发环境搭建Eclipse + jdk1.7 + maven + Jetty 新建 Maven webApp建设 springmvc01 工程并调整 web 环境。 Springmvc 环境 jar 包依赖<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven...d"> <modelVersion>4.0.0</modelVersion> <groupId>com.xxx</groupId> <artifactId>springmvc01</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springmvc01 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- spring web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!-- spring mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!-- web servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> </dependencies> <!-- jetty 插件 --> <build> <finalName>springmvc01</finalName> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <!-- 编译环境插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.25</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <contextPath>/springmvc01</contextPath> </configuration> </plugin> </plugins> </build></project> ...

December 17, 2020 · 3 min · jiezi

关于spring-mvc:你知道什么是-Restful-风格吗SpringMVC-带我们实现它

Restful 格调的 API 是一种软件架构格调,设计格调而不是规范,只是提供了一组设计准则和约束条件。它次要用于客户端和服务器交互类的软件。基于这个格调设计的软件能够更简洁,更有档次,更易于实现缓存等机制。 在 Restful 格调中,用户申请的 url 应用同一个 url 而用申请形式:get,post,delete,put...等形式对申请的解决办法进行辨别,这样能够在前后台分离式的开发中使得前端开发人员不会对申请的资源地址产生混同和大量的查看办法名的麻烦,造成一个对立的接口。 SpringMVC Restful 格调 url 配置实现的形式SpringMVC 的 resturl 是通过 @RequestMapping 及 @PathVariable annotation 提供的,通过如 @RequestMapping(value="/blog /{id}",method=RequestMethod.DELETE) 即可解决 /blog/1 的 delete 申请。 GET(SELECT):从服务器查问,能够在服务器通过申请的参数辨别查问的 形式。POST(CREATE):在服务器端新建一个资源,调用 insert 操作。PUT(UPDATE):在服务器端更新资源,调用 update 操作。PATCH(UPDATE):在服务器端更新资源(客户端提供扭转的属性)。(目前 jdk7 未实现,tomcat7 不反对)。DELETE(DELETE):从服务器端删除资源,调用 delete 语句。案例实操Get 申请配置/***restful-->get 申请 执行查问操作 @param id@return*/@RequestMapping(value="queryAccountById02/{id}",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_UTF8_VALUE)@ResponseBodypublic MessageModel queryAccountById(@PathVariable Integer id){ MessageModel messageModel=new MessageModel(); if(null==id){ messageModel.setCode(300); messageModel.setMsg("参数非法!"); return messageModel; } messageModel.setResult(accountService.queryById(id)); return messageModel; } Post 申请配置/** ...

December 17, 2020 · 1 min · jiezi

关于spring-mvc:你知道目前最流行的SpringMVC框架吗如何搭建呢

Spring MVC 是 Spring 家族中的一个 web 成员, 它是一种基于 Java 的实现了 Web MVC 设计思维的申请驱动类型的轻量级 Web 框架,即应用了 MVC 架构模式的思维,将 web 层进行职责解耦,基于申请驱动指的就是应用申请-响应模型,框架的目标就是帮忙咱们简化开发,Spring MVC 也是要简化咱们日常 Web 开发的。 Spring MVC 是服务到工作者思维的实现。前端控制器是 DispatcherServlet;利用控制器拆为处理器映射器(Handler Mapping)进行处理器治理和视图解析器(View Resolver)进行视图治理;反对本地化/国际化(Locale)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了弱小的约定大于配置(常规优先准则)的契约式编程反对。 SpringMVC 搭建的形式开发环境搭建新建 Maven webAppSpringmvc 环境 jar 包依赖配置 web.xml (前端控制器配置)servlet-context.xml 配置页面控制器的编写增加视图页面启动 jetty 服务器案例实操开发环境搭建Eclipse + jdk1.7 + maven + Jetty 新建 Maven webApp建设 springmvc01 工程并调整 web 环境。 Springmvc 环境 jar 包依赖<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xxx</groupId> <artifactId>springmvc01</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springmvc01 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- spring web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!-- spring mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <!-- web servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> </dependencies> <!-- jetty 插件 --> <build> <finalName>springmvc01</finalName> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <!-- 编译环境插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.25</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <contextPath>/springmvc01</contextPath> </configuration> </plugin> </plugins> </build></project> 配置 web.xml (前端控制器配置)<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- 示意容器启动时 加载上下文配置 这里指定 spring 相干配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:*.xml</param-value> </context-param> <!-- 启用 spring 容器环境上下文监听 --> <listener> <listener class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 编码过滤 utf-8 --> <filter> <description>char encoding filter</description> <filter-name>encodingFilter</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>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- servlet 申请散发器 --> <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:servlet-context.xml</param-value> </init-param> <!-- 示意启动容器时初始化该 Servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <!-- 这是拦挡申请, /代表拦挡所有申请,拦挡所有.do 申请 --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> 要想启动咱们的 springMvc 环境,目前对于 mvc 框架的配置还未进行。以上在 web.xml 中援用了 servlet-context.xml 文件。 ...

December 10, 2020 · 3 min · jiezi

关于spring-mvc:06SpringBoot工程下Spring-MVC技术的应用

Spring MVC 简介背景剖析在大型软件系统设计时,业务个别会绝对简单,如果所有业务实现的代码都纠缠在一起,会呈现逻辑不清晰、可读性差,保护艰难,改变一处就牵一发而动全身等问题。为了更好解决这个问题就有了咱们当初常说的分层架构设计。 MVC 是什么MVC是一种软件架构设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现,例如能够分为视图层(View),管制层(Controller),模型层(Model),通过这样的分层设计让咱们程序具备更好的灵活性和可可扩展性.因为这样能够将一个简单应用程序进行简化,实现各司其职,各尽所能.比拟适宜一个大型利用的开发. Spring MVC 概述Spring MVC是MVC设计思维在Spring框架中的一种实现,基于这样的思维spring框架设计了一些相干对象,用于更好的基于MVC架构解决申请和响应,其繁难架构如图所示: 其中:1)DispatcherServlet是客户端所有申请解决的入口,负责申请转发。2)RequestMapping负责存储申请url到后端handler对象之间的映射。3)Handler 用于解决DispatcherServlet对象转发过去的申请数据。4)ViewResolver负责解决所有Handler对象响应后果中的view。 Spring MVC 疾速入门筹备工作第一步:创立我的项目module,根本信息如图所示: 第二步:增加我的项目依赖(能够在module创立时,也能够创立后),代码如下: Spring Web 依赖(提供了spring mvc反对并且会嵌入一个tomcat) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>Thymeleaf 依赖(提供了以html作为页面模板进行解析和操作的相干对象) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>第三步:启动我的项目检测控制台启动状态是否OK static 目录剖析及利用static 目录为springboot工程创立时增加了web依赖当前主动创立的目录,此目录中能够存储html、css、js、image,这些资源能够在启动服务器当前,间接在浏览器进行拜访。例如:第一步:在static目录下创立一个index.html页面,代码如下: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>The First Html Page</h1></body></html>第二步:启动服务器并间接进行拜访测试,如图所示 templates 目录剖析及利用templates 目录为springboot工程创立时增加了thymeleaf依赖当前主动创立的目录,此目录中要存储一些html模板,这个模板页面不能间接通过浏览器url进行拜访,须要基于后端控制器,在办法中定义页面响应,例如: 第一步:定义TemplateController及办法,代码如下: package com.cy.pj.health.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class TemplateController { @RequestMapping("doTemplateUI") public String doTemplateUI(){ return "default"; }}第二步:在templates目录中定义模板页面default.html,代码如下: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>The Default Template page</h1></body></html>其中,如果default.html要在放在templates子目录中,则还须要在配置文件中配置thymeleaf的前缀,例如: ...

December 9, 2020 · 2 min · jiezi

关于spring-mvc:SpringMVC是如何处理请求的

SpringMVC到底是如何解决申请的?很多人会用 SpringMVC,但对它的解决申请的形式并不分明,当咱们学习一个常识的时候,理解它会让咱们更好地应用它,上面咱们来看看 SpringMVC 是如何解决申请的。 申请流程的形式先上图: Spring MVC 框架也是一个基于申请驱动的 Web 框架,并且应用了前端控制器模式(是用来提供一个集中的申请解决机制,所有的申请都将由一个繁多的处理程序解决来进行设计,再依据申请映射规定分发给相应的页面控制器(动作/处理器)进行解决。首先让咱们整体看一下 Spring MVC 解决申请的流程: 首先用户发送申请,申请被 SpringMVC前端控制器(DispatherServlet)捕捉;前端控制器(DispatherServlet)对申请 URL 解析获取申请 URI,依据 URI,调用 HandlerMapping;前端控制器(DispatherServlet)取得返回的 HandlerExecutionChain(包含 Handler 对象以及 Handler 对象对应的拦截器);DispatcherServlet 依据取得的 HandlerExecutionChain,抉择一个适合的 HandlerAdapter。(附注:如果胜利取得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(…) 办法);HandlerAdapter 依据申请的 Handler 适配并执行对应的 Handler;HandlerAdapter 提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller)。 在填充 Handler 的入参过程中,依据配置,Spring 将做一些额定的工作:HttpMessageConveter:将申请音讯(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息; 数据转换:对申请音讯进行数据转换。如 String 转换成 Integer、Double 等; 数据格式化:如将字符串转换成格式化数字或格式化日期等; 数据验证: 验证数据的有效性(长度、格局等),验证后果存储到 BindingResult 或 Error 中); Handler 执行结束,返回一个 ModelAndView (即模型和视图)给 HandlerAdaptor;HandlerAdaptor 适配器将执行后果 ModelAndView 返回给前端控制器;前端控制器接收到 ModelAndView 后,申请对应的视图解析器;视图解析器解析 ModelAndView 后返回对应 View;渲染视图并返回渲染后的视图给前端控制器;最终前端控制器将渲染后的页面响应给用户或客户端。案例实操SpringMVC 申请执行源码解读对于 SpringMVC 我的项目所有的申请入口(动态资源除外)这里都是从 web.xml 文件配置的前端控制器 DispatcherServlet 开始: ...

December 8, 2020 · 7 min · jiezi

关于spring-mvc:SpringMVC中转发和重定向的区别

转发和重定向相同点都是web开发中资源跳转的形式。 不同点转发:是服务器外部的跳转,浏览器的地址栏不会发生变化。从一个页面到另一个页面的跳转还是同一个申请,也即是只有一个申请响应。能够通过request域来传递对象。重定向:是浏览器主动发动对跳转指标的申请,浏览器的地址栏会发生变化。从一个页面到另一个页面的跳转是不同的申请,也即是有两个或两个以上的不同的申请的响应。无奈通过request域来传递对象。 在SpringMVC中实现转发和重定向 (1)在SpringMVC中依然以传统形式进行转发和重定向上面的代码中login.jsp就是跳转后的页面转发: requst.getRequestDispatcher("login.jsp").forword(request,response);重定向: response.sendRedirect("login.jsp");(2)SpringMVC提供了便捷的转发和重定向的形式 //转发@RequestMapping("/forward")public String forword(){ return "forward:/index.jsp";}//重定向@RequestMapping("redirect")public String redirect(){ return "redirect:/index.jsp";}

December 5, 2020 · 1 min · jiezi

关于spring-mvc:SpringMvc路径参数和url的两种实现方式

一、申请参数 申请参数采纳key = value模式,并用“&”分隔。例如上面的URL带有名为name和pwd的申请参数。 localhost:9090/showUser?name=spring&pwd=spring 在传统的servlet编程中,能够应用HttpServletRequest的getParameter办法来获取申请参数值。 String name = httpServletRequest.getParameter(“name”); Spring MVC 提供了一个更简略的办法来获取申请参数:通过注解@RequestParam来正文办法参数。依据下面的URL,编写一个映射函数。 @RequestMapping(value="/showUser/") public String testRequestParam(@RequestParam String name, @RequestParam String pwd, Map<String, Object> model){ model.put("name", name); model.put("pwd", pwd); return "showUser"; }运行后果如下: 二、门路参数门路参数相似申请参数,但没有key局部,只是一个值。例如上面的URL: http://localhost:9090/showUser/spring其中的spring是示意用户的明码字符串。在Spring MVC中,spring被作为门路变量用来发送一个值到服务器。Sping 3当前Spring 3当前反对注解@PathVariable用来接管门路参数。为了应用门路变量,首先须要在RequestMapping注解的值属性中增加一个变量,该变量必须放在花括号之间,例如:@RequestMapping(value= “/showUser/{pwd}”)而后在办法签名中加上@PathVariable注解。具体代码如下: @RequestMapping(value= "/showUser/{pwd}") public String testPathVariable(@PathVariable(name="pwd") String password, Map<String, Object> model){ model.put("pwd", password); return "showUser"; }运行后果: 能够在申请映射中应用多个门路变量。例如,上面定义了userId和orderId两个门路变量。@RequestMapping(value= “/showUser/{userId}/{orderId}”)。

December 5, 2020 · 1 min · jiezi

关于spring-mvc:springMVC的工作流程

1.springmvc工作流程图 2.springmvc工作流程1、 用户向服务端发送一次申请,这个申请会先到前端控制器DispatcherServlet(也叫地方控制器)。2、DispatcherServlet接管到申请后会调用HandlerMapping处理器映射器。由此得悉,该申请该由哪个Controller来解决(并未调用Controller,只是得悉)3、DispatcherServlet调用HandlerAdapter处理器适配器,通知处理器适配器应该要去执行哪个Controller4、HandlerAdapter处理器适配器去执行Controller并失去ModelAndView(数据和视图),并层层返回给DispatcherServlet5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,而后返回真正的视图。6、DispatcherServlet将模型数据填充到视图中7、DispatcherServlet将后果响应给用户3.组件阐明 DispatcherServlet:前端控制器,也称为地方控制器,它是整个申请响应的控制中心,组件的调用由它对立调度。HandlerMapping:处理器映射器,它依据用户拜访的 URL 映射到对应的后端处理器 Handler。也就是说它晓得解决用户申请的后端处理器,然而它并不执行后端处理器,而是将处理器通知给中央处理器。HandlerAdapter:处理器适配器,它调用后端处理器中的办法,返回逻辑视图 ModelAndView 对象。ViewResolver:视图解析器,将 ModelAndView 逻辑视图解析为具体的视图(如 JSP)。Handler:后端处理器,对用户具体申请进行解决,也就是咱们编写的 Controller 类。组件具体阐明:1、前端控制器DispatcherServlet(不须要工程师开发),由框架提供作用:接管申请,响应后果,相当于转发器,中央处理器。有了dispatcherServlet缩小了其它组件之间的耦合度。用户申请达到前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程管制的核心,由它调用其它组件解决用户的申请,dispatcherServlet的存在升高了组件之间的耦合性。 2、处理器映射器HandlerMapping(不须要工程师开发),由框架提供作用:依据申请的url查找HandlerHandlerMapping负责依据用户申请找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射形式,例如:配置文件形式,实现接口方式,注解形式等。 3、处理器适配器HandlerAdapter作用:依照特定规定(HandlerAdapter要求的规定)去执行Handler通过HandlerAdapter对处理器进行执行,这是适配器模式的利用,通过扩大适配器能够对更多类型的处理器进行执行。 4、处理器Handler(须要工程师开发)留神:编写Handler时依照HandlerAdapter的要求去做,这样适配器才能够去正确执行HandlerHandler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的管制下Handler对具体的用户申请进行解决。因为Handler波及到具体的用户业务申请,所以个别状况须要工程师依据业务需要开发Handler。 5、视图解析器View resolver(不须要工程师开发),由框架提供作用:进行视图解析,依据逻辑视图名解析成真正的视图(view)View Resolver负责将处理结果生成View视图,View Resolver首先依据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最初对View进行渲染将处理结果通过页面展现给用户。 springmvc框架提供了很多的View视图类型,包含:jstlView、freemarkerView、pdfView等。个别状况下须要通过页面标签或页面模版技术将模型数据通过页面展现给用户,须要由工程师依据业务需要开发具体的页面。 6、视图View(须要工程师开发jsp...)View是一个接口,实现类反对不同的View类型(jsp、freemarker、pdf...) 外围架构的具体流程步骤如下:1、首先用户发送申请——>DispatcherServlet,前端控制器收到申请后本人不进行解决,而是委托给其余的解析器进行解决,作为对立拜访点,进行全局的流程管制;2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把申请映射为HandlerExecutionChain 对象(蕴含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易增加新的映射策略;3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而反对多种类型的处理器,即适配器设计模式的利用,从而很容易反对很多类型的处理器;4、HandlerAdapter——>处理器性能解决办法的调用,HandlerAdapter 将会依据适配的后果调用真正的处理器的性能解决办法,实现性能解决;并返回一个ModelAndView 对象(蕴含模型数据、逻辑视图名);5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其余视图技术;6、View——>渲染,View会依据传进来的Model模型数据进行渲染,此处的Model理论是一个Map数据结构,因而很容易反对其余视图技术;7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程完结。 下边两个组件通常状况下须要开发: Handler:处理器,即后端控制器用controller示意。 View:视图,即展现给用户的界面,视图中通常须要标签语言展现模型数据。 在将SpringMVC之前咱们先来看一下什么是MVC模式 MVC:MVC是一种设计模式 MVC的原理图:剖析: M-Model 模型(实现业务逻辑:有javaBean形成,service+dao+entity) V-View 视图(做界面的展现  jsp,html……) C-Controller 控制器(接管申请—>调用模型—>依据后果派发页面) springMVC是什么:  springMVC是一个MVC的开源框架,springMVC=struts2+spring,springMVC就相当于是Struts2加上sring的整合,然而这里有一个纳闷就是,springMVC和spring是什么样的关系呢?这个在百度百科上有一个很好的解释:意思是说,springMVC是spring的一个后续产品,其实就是spring在原有根底上,又提供了web利用的MVC模块,能够简略的把springMVC了解为是spring的一个模块(相似AOP,IOC这样的模块),网络上常常会说springMVC和spring无缝集成,其实springMVC就是spring的一个子模块,所以基本不须要同spring进行整合。 SpringMVC的原理图: 看到这个图大家可能会有很多的纳闷,当初咱们来看一下这个图的步骤:(能够比照MVC的原理图进行了解) 第一步:用户发动申请到前端控制器(DispatcherServlet) 第二步:前端控制器申请处理器映射器(HandlerMappering)去查找处理器(Handle):通过xml配置或者注解进行查找 第三步:找到当前处理器映射器(HandlerMappering)像前端控制器返回执行链(HandlerExecutionChain) 第四步:前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler) 第五步:处理器适配器去执行Handler 第六步:Handler执行完给处理器适配器返回ModelAndView 第七步:处理器适配器向前端控制器返回ModelAndView 第八步:前端控制器申请视图解析器(ViewResolver)去进行视图解析 第九步:视图解析器像前端控制器返回View 第十步:前端控制器对视图进行渲染 第十一步:前端控制器向用户响应后果 了解springMVC中的几个组件: 前端控制器(DispatcherServlet):接管申请,响应后果,相当于电脑的CPU。 ...

December 1, 2020 · 1 min · jiezi

关于spring-mvc:SSMCookieSession拦截器Interceptor

1 CookieCookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区倒退的一种机制。 Cookie实际上是一小段的文本信息。客户端申请服务器,如果服务器须要记录该用户状态,就应用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再申请该网站时,浏览器把申请的网址连同该Cookie一起提交给服务器。服务器查看该Cookie,以此来识别用户状态。服务器还能够依据须要批改Cookie的内容。 单点登录中可利用cookie设置实现。 可在浏览器中查看cookie,cookie不能跨域。一对一的关系。 1.1 设置CookieCookie常识介绍: 1.cookie.setPath("/") 代表根目录无效 url1:www.jt.com/addUser url2:www.jt.com/user/addUser2.cookie.setDomain("域名地址") cookie在哪些域名中共享 例子1:cookie.setDomain("www.jt.com");//只有在www.jt.com中共享 cookie.setDomain("jt.com");//在jt.com中共享3.cookie.setMaxAge(30*24*60*60);//让cookie30天无效。4.Cookie cookie = new Cookie("JT_TICKET",uuid); 设置cookie的name和值例如: @RestControllerpublic class UserController { @RequestMapping("/login") public String login(String username, HttpServletResponse response) { //创立cookie Cookie cookie = new Cookie("username", username); //把cookie返回给浏览器 response.addCookie(cookie); return "设置cookie"; }}1.2 读取Cookie@RestControllerpublic class OrderController { @RequestMapping("/getOrder") public String getOrder(HttpServletRequest request) { //读取所有cookie Cookie[] cookies = request.getCookies(); String string = ""; if (cookies != null) { //遍历cookie for (Cookie cookie : cookies) { //取cookie名 String cookieName = cookie.getName(); //取cookie值 String cookieValue = cookie.getValue(); string = string + cookieName + cookieValue; } } return string; }1.3 “删除”Cookiecookie不能被动删除,如需删除cookie,可从新设置cookie,将无效工夫改为0即可。 ...

November 28, 2020 · 2 min · jiezi

关于spring-mvc:这份SpringMVC执行原理笔记建议做java开发的好好看看总结的很详细

什么是SpringMVC?Spring MVC属于SpringFrameWork的后续产品,曾经交融在Spring Web Flow外面。Spring 框架提供的web模块,蕴含了开发Web 应用程序的全功能 MVC 模块。从而在应用Spring进行Web开发时,能够抉择应用Spring的SpringMVC框架。集成其余WEB MVC开发框架,如Struts、Struts2等。SpringMVC是Web层的MVC开发框架,属于Spring框架的Web模块中的一个局部。 基于SpringMVC案例创立webapp我的项目、欠缺我的项目构造、导入依赖<!-- 配置开发SpringMVC所以来的jar包 --><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.5.RELEASE</version></dependency><!-- 配置ServletAPI依赖 --><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope></dependency><!--配置JSP依赖包--><!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api --><dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.2.1</version> <scope>provided</scope></dependency>#### 在web.xml文件中配置中央处理器(DispatcherServlet) <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- 留神:/前面没有* --> <url-pattern>/</url-pattern> </servlet-mapping>创立自定义控制器类package qing;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 StudentController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mav = new ModelAndView(); mav.addObject("info", "hello,小李同学"); mav.setViewName("test.jsp"); return mav; }}在resources文件中编写SpringMVC.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置URL解析器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <!-- 配置管制适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean> <!-- 配置自定义控制器 --> <!-- name:自定义控制器拜访门路 class:包名+类名 --> <bean name="/stu" class="qing.StudentController"></bean> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=""></property> </bean></beans>在web.xml配置文件中加载SpringMVC.xml文件<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:SpringMVC.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>创立test.jsp文件<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><html><head> <title>欢送应用SpringMVC</title></head><body> <h1>${info}</h1></body></html>部署本地服务器测试http://localhost:8080/stu ...

November 27, 2020 · 2 min · jiezi

关于spring-mvc:SpringMVC到底是如何处理请求的

很多人会用 SpringMVC,但对它的解决申请的形式并不分明,当咱们学习一个常识的时候,理解它会让咱们更好地应用它,上面咱们来看看 SpringMVC 是如何解决申请的。 申请流程的形式先上图: Spring MVC 框架也是一个基于申请驱动的 Web 框架,并且应用了前端控制器模式(是用来提供一个集中的申请解决机制,所有的申请都将由一个繁多的处理程序解决来进行设计,再依据申请映射规定分发给相应的页面控制器(动作/处理器)进行解决。首先让咱们整体看一下 Spring MVC 解决申请的流程: 首先用户发送申请,申请被 SpringMVC前端控制器(DispatherServlet)捕捉;前端控制器(DispatherServlet)对申请 URL 解析获取申请 URI,依据 URI,调用 HandlerMapping;前端控制器(DispatherServlet)取得返回的 HandlerExecutionChain(包含 Handler 对象以及 Handler 对象对应的拦截器);DispatcherServlet 依据取得的 HandlerExecutionChain,抉择一个适合的 HandlerAdapter。(附注:如果胜利取得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(...) 办法);HandlerAdapter 依据申请的 Handler 适配并执行对应的 Handler;HandlerAdapter 提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller)。 在填充 Handler 的入参过程中,依据配置,Spring 将做一些额定的工作:HttpMessageConveter:将申请音讯(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息; 数据转换:对申请音讯进行数据转换。如 String 转换成 Integer、Double 等; 数据格式化:如将字符串转换成格式化数字或格式化日期等; 数据验证: 验证数据的有效性(长度、格局等),验证后果存储到 BindingResult 或 Error 中); Handler 执行结束,返回一个 ModelAndView (即模型和视图)给 HandlerAdaptor;HandlerAdaptor 适配器将执行后果 ModelAndView 返回给前端控制器;前端控制器接收到 ModelAndView 后,申请对应的视图解析器;视图解析器解析 ModelAndView 后返回对应 View;渲染视图并返回渲染后的视图给前端控制器;最终前端控制器将渲染后的页面响应给用户或客户端。案例实操SpringMVC 申请执行源码解读对于 SpringMVC 我的项目所有的申请入口(动态资源除外)这里都是从 web.xml 文件配置的前端控制器 DispatcherServlet 开始: ...

November 20, 2020 · 7 min · jiezi

关于spring-mvc:SpringMVC源码分析

弱小的DispatcherServlet还记得在web.xml中配置的DispatcherServlet吗?其实那个就是SpringMVC框架的入口,这也是struts2和springmvc不同点之一,struts2是通过filter的,而springmvc是通过servlet的。看下servlet的结构图 从下面这张图很显著能够看出DispatcherServlet和Servlet以及Spring的关系。而咱们明天的重点就从DispatchServlet说起。 在剖析之前我用SpringBoot搭建了一个很简略的后盾我的项目,用于剖析。代码如下 import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;@Data@Builder@AllArgsConstructorpublic class User {private Integer id;private String name;private Integer age;private String address;public User() {}}/*** @author generalthink*/@RestController@RequestMapping("/user")public class UserController {@RequestMapping(value = "/{id}",method = RequestMethod.GET)public User getUser(HttpServletRequest request,@PathVariable Integer id) {//创立一个user,不走数据库只是为了剖析springmvc源码User user = User.builder().id(id).age(ThreadLocalRandom.current().nextInt(30)).name("zzz" + id).address("成都市").build();return user;}@RequestMapping(value = "/condition",method = RequestMethod.GET)public User getByNameOrAge(@RequestParam String name,@RequestParam Integer age) {User user = User.builder().name(name).age(age).address("成都市").id(2).build();return user;}@PostMappingpublic Integer saveUser(@RequestBody User user) {Integer id = user.getName().hashCode() - user.getAge().hashCode();return id > 0 ? id : -id;}}这里为了不便调试把关注点更多集中在SpringMVC源码中,所以这里的数据都是伪造的。而且这里的关注点也集中到应用注解的Controller(org.springframework.stereotype.Controller),而不是Controller接口(org.springframework.web.servlet.mvc.Controller),这两者的区别次要在意一个只用标注注解,一个须要实现接口,然而它们都能实现解决申请的基本功能。咱们都晓得拜访servlet的时候默认是拜访service办法的,所以咱们将断点打在HttpServlet的service办法中,此时查看整个调用栈如下从这里咱们也晓得了申请时如何从servlet到了DispatcherServlet的,咱们先来看一下DispatcherServlet的doDiapatch的办法逻辑,这里把外围逻辑列出来了,把其余的一些非核心逻辑移除了 ...

November 11, 2020 · 2 min · jiezi

关于spring-mvc:SpringBoot强化篇四Spring-MVC框架的整合及原理分析

Spring MVC 简介在大型软件系统设计时,业务个别会绝对简单,如果所有业务实现的代码都纠缠在一起,会呈现逻辑不清晰、可读性差,保护艰难,改变一处就牵一发而动全身等问题。为了更好解决这个问题就有了咱们当初常说的分层架构设计。 MVC 是什么MVC是一种软件架构设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现,例如能够分为视图层(View),管制层(Controller),模型层(Model),通过这样的分层设计让咱们程序具备更好的灵活性和可可扩展性.因为这样能够将一个简单应用程序进行简化,实现各司其职,各尽所能.比拟适宜一个大型利用的开发.▪ 视图(View) - UI设计人员进行图形界面设计,负责实现与用户交互。▪ 控制器(Controller)- 负责获取申请,解决申请,响应后果。▪ 模型(Model) - 实现业务逻辑,数据逻辑实现。 Spring MVC 概述Spring MVC是MVC设计思维在Spring框架中的一种实现,基于这样的思维spring框架设计了一些相干对象,用于更好的基于MVC架构解决申请和响应,其繁难架构如图所示:1.前端控制器 DispatcherServlet是客户端所有申请解决的入口,负责申请转发。2.处理器映射器 RequestMapping负责存储申请url到后端handler对象之间的映射。3.处理器适配器 Handler 用于解决DispatcherServlet对象转发过去的申请数据。4.视图解析器 ViewResolver负责解决所有Handler对象响应后果中的view。 Spring MVC 疾速入门筹备工作第一步:创立我的项目module,根本信息如图所示: 第二步:增加我的项目依赖(能够在module创立时,也能够创立后),代码如下: Spring Web 依赖(提供了spring mvc反对并且会嵌入一个tomcat) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>Thymeleaf 依赖(提供了以html作为页面模板进行解析和操作的相干对象) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>static 目录剖析及利用static 目录为springboot工程创立时增加了web依赖当前主动创立的目录,此目录中能够存储html、css、js、image,这些资源能够在启动服务器当前,间接在浏览器进行拜访。 templates 目录剖析及利用templates 目录为springboot工程创立时增加了thymeleaf依赖当前主动创立的目录,此目录中要存储一些html模板,这个模板页面不能间接通过浏览器url进行拜访,须要基于后端控制器,在办法中定义页面响应其中,如果default.html要在放在templates子目录中,则还须要在配置文件中配置thymeleaf的前缀 #server portserver.port=80#spring webspring.thymeleaf.prefix=classpath:/templates/health/spring.thymeleaf.suffix=.html#spring thymeleafspring.thymeleaf.cache=false定义HealthController类来测试 package com.cy.pj.health.controller;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletResponse;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;@Controllerpublic class HealthController {//Handler对象 来解决DispatcherServlet散发过去的申请 //三种状况 //1.只返回页面 //2.返回json字符串 //3.返回页面加参数 @RequestMapping("/doPrint") @ResponseBody public void doPrint(HttpServletResponse response) throws Exception{ Map<String,Object> map =new HashMap<>(); map.put("username", "tony"); map.put("state", true); //return map ; //将map中的数据转换成json格局的字符串,底层实现如下 ObjectMapper om=new ObjectMapper(); String jsonStr=om.writeValueAsString(map);//jackson中转换json字符串的办法 System.out.println("jsonStr="+jsonStr); //将字符串响应到客户端 response.setCharacterEncoding("utf-8");//批改编码方式 response.setContentType("text/html;charset=utf-8");//通知客户端咱们的编码格局让其以这种形式解析数据 PrintWriter pw = response.getWriter();//写入响应流中 pw.println(jsonStr); } @RequestMapping("/doHealth") public String doHealth(Model model) { model.addAttribute("username","张三"); model.addAttribute("state","亚健康"); return "default"; //返回的字符串交给ViewResolver视图解析器,会主动剖析,传参且出现页面 } @RequestMapping("/health.html") @ResponseBody //应用此注解形容管制办法时,用于通知spring框架,这个办法返回值能够依照特定格局(例json字符串)进行转换,来响应客户端 //将转换当前的后果写到response对象的响应体中 //f昂发的返回值不再封装为ModelAndView对象,不会再交给视图解析器进行解析,而是间接基于response对象响应到客户端 public Map<String, Object> doHealth(){ Map<String,Object> map =new HashMap<>(); map.put("username", "tony"); map.put("state", true); return map ; } //public ModelAndView doHealth(){//此办法由DispatcherServlet对象通过反射调用 //ModelAndView mv =new ModelAndView(); //mv.setViewName("default");//viewname //mv.addObject("username","李四"); //mv.addObject("state","亚健康");//传的是个对象,所以能够传的不止字符串 //return mv; //1.返回值会交给DispatcherServlet对象进行解决 //2.DispatcherServlet对象会调用viewresolver对后果进行解析 //2.1基于viewname找对应的view页面(prefix+viewname+suffix) //2.2将model中的数据填充到view页面上 //2.3返回一个带有module数据的页面给DispatcherServlet //3.DispatcherServlet将带有model数据的页面返回给客户端 //public String doHealth(){ // return "default" ;// 能够间接返回对应名字的页面 // }}JSON数据响应咱们有一业务不须要页面,只须要将响应数据转换为json,而后响应到客户端,如何实现呢?第一步:定义ResponseResult对象用于封装响应数据,例如: ...

November 10, 2020 · 2 min · jiezi

关于spring-mvc:精通Spring-MVC4pdf

关注公众号“Java后端技术全栈”** 回复“面试”获取全套大厂面试材料 Spring MVC 属于 Spring Framework 的衍生产品,曾经交融在 Spring Web Flow 外面。  Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC 4 是以后比拟罕用的版本,在泛滥个性上有了进一步的晋升。 最近很多小伙伴问我要一些Spring MVC 的相干材料,于是我翻箱倒柜,找到了这本能够教咱们从头开始构建一个有用的Web利用的电子书——《精通Spring MVC4》。 材料介绍 本书中从头开始构建了一个残缺的 Web 利用。全书共10 章,别离介绍了疾速搭建 Spring Web 利用、精通 MVC 构造、解决表单和简单的 URL 映射、文件上传与错误处理、创立 RESTful 利用、爱护利用、单元测试与验收测试、优化申请、将 Web 利用部署到云等内容, 循序渐进地解说了 Spring MVC 4 的开发技巧。 本书最适宜曾经相熟 Spring 编程基础知识并迫切希望扩大其 Web 技能的开发人员。通过浏览本书,读者将深度把握 Spring MVC 的各项个性及实用技巧。  最次要的是,这份材料不是扫描版,还能够复制哟。 如何获取? 辨认二维码并关注公众号「Java后端技术全栈」;在公众号后盾回复关键字「505」。

November 5, 2020 · 1 min · jiezi

关于spring-mvc:Spring-MVC-源码之请求的执行流程

Spring MVC 源码之申请的执行流程 DispatcherServletSpringMVC外围就是DispatcherServlet,所有得申请都会转发到DispatcherServlet,而后再通过DispatcherServlet执行具体得管制层(Handler)返回ModelAndView给客户端视图展现。 DispatcherServlet其实就是一个Servlet类,无非就是包装一层,通过url可能映射找到咱们得SpringMvc中定义得申请办法。 类的集成关系DispatcherServlet继承FrameworkServlet继承HttpServlet 面向基本上思维 重写 先走父类 ,在走子类。 得出答案:先看HttpServlet再找到咱们最初的子类 当咱们第一次申请一个地址的时候,如果可能拜访,他会返回一个200代表拜访胜利,此时应答头信息中会有一个 Last-Modified 代表服务器这个文件的最初批改工夫。 当咱们再次申请的时候,如果申请过了,就会在申请头,有一个If-Modified-Since的值,这时候传到服务器,服务器就会拿这个值和上次批改的工夫比照,如果小于上次批改的工夫,阐明服务器上的文件被批改过,就再次从服务器进行下载,返回200 如果没有批改就像上图一样,返回一个304,代表客户端曾经执行了GET,但文件未变动。 既然是Servlet类,那么他有一个最终的办法,就是service()办法,他是Servlet最外围的办法。 HttpServlet#service protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < lastModified) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // // Note that this means NO servlet supports whatever // method was requested, anywhere on this server. // String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } }maybeSetLastModified(resp, lastModified); ...

November 2, 2020 · 7 min · jiezi

关于spring-mvc:Spring-MVC-到-Spring-Boot-的简化之路

背景从Servlet技术到Spring和Spring MVC,开发Web利用变得越来越简捷。然而Spring和Spring MVC的泛滥配置有时却让人望而生畏,置信有过Spring MVC开发教训的敌人能粗浅领会到这一苦楚。因为即便是开发一个Hello-World的Web利用,都须要咱们在pom文件中导入各种依赖,编写web.xml、spring.xml、springmvc.xml配置文件等。特地是须要导入大量的jar包依赖时,咱们须要在网上查找各种jar包资源,各个jar间可能存在着各种依赖关系,这时候又得下载其依赖的jar包,有时候jar包间还存在着严格的版本要求,,所以当咱们只是想开发一个Hello-World的超简略的Web利用时,却把极大局部的工夫在花在了编写配置文件和导入jar包依赖上,极大地影响了咱们的开发效率。所以为了简化Spring繁冗的配置,Spring Boot应运而生。正如Spring Boot的名称一样,一键启动,Spring Boot提供了主动配置性能,为咱们提供了开箱即用的性能,使咱们将重心放在业务逻辑的开发上。那么Spring Boot又是怎么简化Spring MVC的呢?Spring Boot和Spring、Spring MVC间又是怎么的关系呢?Spring Boot又有什么新特点呢?接下来,让咱们走进Spring MVC 到Spring Boot的简化之路,或者你就能找到这些答案。 Spring vs Spring MVC vs Spring BootSpring Boot和Spring、Spring MVC不是竞争关系,Spring Boot使咱们更加容易应用Spring和Spring MVCSpring FrameWorkSpring FrameWork解决的外围问题是什么 Spring框架的最重要个性是依赖注入,所有的Spring模块的外围都是依赖注入(DI)或管制反转(IOC)。为什么很重要呢,因为当咱们应用DI或IOC时,咱们能够使利用失去解耦。咱们来看一个简略的例子:没有依赖注入的例子: @RestControllerpublic class WelcomeController { private WelcomeService service = new WelcomeService(); @RequestMapping("/welcome") public String welcome() { return service.retrieveWelcomeMessage(); }}WelcomeService service = new WelcomeService(); 意味着WelcomeController类与WelcomeService类紧密结合在一起,耦合度高。复制代码应用依赖注入的例子: @Componentpublic class WelcomeService { //Bla Bla Bla}@RestControllerpublic class WelcomeController { @Autowired private WelcomeService service; @RequestMapping("/welcome") public String welcome() { return service.retrieveWelcomeMessage(); }}依赖注入使世界看起来更简略,咱们让Spring 框架做了辛勤的工作:@Component:咱们通知Spring框架-嘿,这是一个你须要治理的bean@Autowired:咱们通知Spring框架-嘿,找到这个特定类型的正确匹配并主动装入它复制代码如果感觉看完文章有所播种的话,能够关注我一下哦知乎:秃顶之路 b站:linux亦有归途 每天都会更新咱们的公开课录播以及编程干货和大厂面经或者间接点击链接c/c++ linux服务器开发高级架构师来课堂上跟咱们讲师面对面交换须要大厂面经跟学习纲要的小伙伴能够加群973961276获取 ...

October 31, 2020 · 2 min · jiezi

关于spring-mvc:浅谈SpringMVC处理流程

1.解决流程图 2.流程阐明* 一个申请匹配前端控制器DispatcherServlet的申请映射门路(在web.xml中指定),WEB容器将该申请转交给DispatcherServlet解决* DispatcherServlet接管到申请后,依据申请信息交给处理器映射器(HandlerMapping)* HandlerMapping依据用户的url申请查找匹配该url的Handler,并返回一个执行链* DispatcherServlet再申请处理器适配器HandlerAdapter调用雷同的Handler进行解决并返回ModelAndView给DispatcherServlet* DispatcherServlet将ModelAndView申请ViewResolver(视图解析器)解析,返回具体的view* DispatcherServlet对View进行渲染视图(行将模型数据填充至视图中)* DispatcherServlet将页面响应给客户3.组件阐明DispatcherServlet:前端控制器 用户申请达到前端控制器,它就相当于mvc模式中的c(管制层),DispatcherServlet是整个流程管制的核心,由它调用其它组件解决用户的申请,DispatcherServlet的存在升高了组件之间的耦合性。HandlerMapping:处理器映射器 HandlerMapping负责依据用户申请url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射形式,例如:配置文件形式,实现接口方式,注解形式等。Handler:处理器 Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的管制下Handler对具体的用户申请进行解决。因为Handler设计到具体的用户业务申请,所以个别状况下须要程序员依据业务需要开发Handler。HandlerAdapter:处理器适配器 通过HandlerAdapter对处理器进行执行,这是适配器模式的利用,通过扩大适配器能够对更多类型的处理器进行执行。ViewResolver:视图解析器 ViewResolver负责将解决的后果生成View视图,ViewResolver首先依据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最初对View进行渲染将处理结果通过页面展现给用户。View:视图 springmvc框架提供了很多的view视图类型的反对,包含:jstlView,freemakerView,pdfView等。咱们最常见的视图就是jsp,个别状况下须要页面标签或者页面模版技术将模型数据通过页面展现给用户,须要程序员依据业务需要开发具体的页面。

October 30, 2020 · 1 min · jiezi

关于spring-mvc:Spring-MVC的配置和原理

SpringMVC的配置和原理:1.Spring MVC的配置:1.在pom.xml中引入springmvc所须要的jar包: <dependencies> <!-- Spring MVC的jar包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.1.3.RELEASE</version> </dependency> <!-- servlet 和 jsp 的jar包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies>2.在web.xml中 配置前端控制器 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"><!-- 配置springmvc前端控制器(DispatcherServlet),将所有申请交给springmvc来解决 --><servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置springmvc外围配置文件的地位,默认springmvc的配置文件在WEB-INF录下,默认的名字为springmvc-servlet.xml,如果要放在其余目录,则须要指定如下配置: --> <init-param> <!-- 这里配置的是固定值 --> <param-name>contextConfigLocation</param-name> <!-- 这里依据文件名和地位决定xml文件的门路 --> <param-value>classpath:springmvc-config.xml</param-value> </init-param></servlet><servlet-mapping> <!-- 此名字要与下面的name一样 --> <servlet-name>springmvc</servlet-name> <!--/*:拦挡动态web资源(html/css/JS/图片),包含JSP /:拦挡动态web资源,不包含JSP --> <url-pattern>/</url-pattern></servlet-mapping></web-app>3.创立并配置springmvc-config.xml ...

October 29, 2020 · 1 min · jiezi

关于spring-mvc:SpringMVC

待欠缺

October 25, 2020 · 1 min · jiezi

关于spring-mvc:SpringMVC

待欠缺

October 25, 2020 · 1 min · jiezi

关于spring-mvc:动吧旅游生态系统日志管理设计说明

1 日志治理设计说明1.1 业务设计说明本模块次要是实现对用户行为日志(例如谁在什么工夫点执行了什么操作,拜访了哪些办法,传递的什么参数,执行时长等)进行记录、查问、删除等操作。其表设计语句如下: CREATE TABLE `sys_logs` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL COMMENT '登陆用户名', `operation` varchar(50) DEFAULT NULL COMMENT '用户操作', `method` varchar(200) DEFAULT NULL COMMENT '申请办法', `params` varchar(5000) DEFAULT NULL COMMENT '申请参数', `time` bigint(20) NOT NULL COMMENT '执行时长(毫秒)', `ip` varchar(64) DEFAULT NULL COMMENT 'IP地址', `createdTime` datetime DEFAULT NULL COMMENT '日志记录时间', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='系统日志';1.2 原型设计说明基于用户需要,实现动态页面(html/css/js),通过动态页面为用户出现根本需要实现,如图-1所示。 图-1 阐明:如果客户对此原型进行了确认,后续则能够基于此原型进行研发。 1.3 API设计说明日志业务后盾API分层架构及调用关系如图-2所示: ...

October 21, 2020 · 8 min · jiezi

关于spring-mvc:动吧旅游生态系统day01

1我的项目简介1.1 概述动吧游览生态系统,应市场高端用户需要,公司决定开发这样的一套游览零碎,此零碎蕴含游览电商零碎(广告子系统,举荐子系统,评估子系统,商品子系统,订单子系统,…),游览分销零碎(分销商的治理),游览业务零碎(产品研发,计调服务,零碎权限管理子系统,..),,。。。 1.2 原型剖析基于用户需要,进行原型设计(基于html+css+js进行动态页面实现)。例如零碎登录页面: 零碎登录胜利页面(例如starter.html) 菜单展现页面 阐明:原型设计好当前,会与客户进行确认,确认好当前进行签字,而后就是设计和实现. 2 技术架构2.1 我的项目分层架构本我的项目应用层基于MVC设计思维,进行分层架构设计,其外围目标是将简单问题简单化,实现各司其职,各尽所能.而后基于“高内聚,低耦合”的设计思维,再实现各对象之间协同,从而进步零碎的可维护性,可扩展性。 其中: 1.凋谢接口层:可间接封装 Service 办法裸露成 RPC (近程过程调用)接口;也可通过 Web 封装成 http 接口;同时也可进行网关安全控制、流量管制等。 2.终端显示层:负责各个端的模板渲染并显示。以后次要是 thymeleaf 渲染,JS 渲染,挪动端展现等。 3.Web申请解决层:次要是对访问控制进行转发,申请参数校验,响应后果解决等 4.Service 层:绝对具体的业务逻辑服务层(外围业务,扩大业务)。 5.Manager 层:通用业务解决层,它有如下特色: 1) 对第三方平台封装的层,预处理返回后果及转化异样信息; 2) 对 Service 层通用能力的下沉,如缓存计划、中间件通用解决; 3) 与 DAO 层交互,对多个 DAO 的组合复用。 6.DAO 层:数据拜访层,与底层 MySQL、Oracle、Hbase 等进行数据交互。 7.内部接口或第三方平台:包含其它部门RPC凋谢接口,根底平台,其它公司的 HTTP 接口 阐明:对如上分层中波及到常识的点,逐渐增强。 总之:分层的目标就是将简单问题进行拆解,而后分而治,进而进步零碎的可扩展性以及可维护性。 2.2 API利用架构整体API利用架构: 3 技术整合3.1 环境筹备3.1.1 数据库初始化启动MySQL客户端并登陆,而后执行 1) set names utf8; 2) source d:/jtsys.sql ...

October 21, 2020 · 1 min · jiezi

关于spring-mvc:spring-mvc框架的理解

spring mvc?要想晓得什么是spring mvc首先要晓得什么是设计模式? 设计模式(Design Pattern)是一套被重复应用、少数人通晓的、通过分类的、代码设计教训的总结。 应用设计模式的目标:为了代码可重用性、让代码更容易被别人了解、保障代码可靠性。 设计模式使代码编写真正工程化; 设计模式是软件工程的基石脉络,如同大厦的构造一样。 设计模式就是一种模子,通过多年实际锻炼造成一套卓有成效的实现某个特定工作的步骤和形式。 例如:西凤酒的酿造过程,酿造工序,前后不能变,温差不能变,这样做就是好喝,略微改变就变滋味了。 再如,北京烤鸭,就是那样做,就是那些调料腌制,变量配比,滋味口感就是不如人家。 MVC设计模式MVC设计模式是一种通用的软件编程思维 在MVC设计模式中认为, 任何软件都能够分为三局部组成: (1)控制程序流转的控制器(Controller) (2)封装数据解决数据的模型(Model) (3)负责展现数据的视图(view) 并且在MVC设计思维中要求一个合乎MVC设计思维的软件应该保障下面这三局部互相独立,互不烦扰,每一个局部只负责本人善于的局部。 如果某一个模块发生变化,应该尽量做到不影响其余两个模块。这样做的益处是,软件的构造会变得更加的清晰,可读性强。有利于前期的扩大和保护,并且代码能够实现复用。 简介spring mvcSpringmvc是spring框架的一个模块,spring和springmvc无需两头整合层整合 Springmvc是一个基于mvc的web框架 spring mvc 执行的原理解析 (1).用户发送申请 至 前端控制器(DispatcherServlet); 提醒:DispatcherServlet的作用:接管申请,调用其它组件解决申请,响应后果,相当于转发器、中央处理器,是整个流程管制的核心 (2).前端控制器(DispatcherServlet)收到申请后调用处理器映射器(HandlerMapping) 处理器映射器(HandlerMapping)找到具体的Controller(能够依据xml配置、注解进行查找),并将Controller返回给DispatcherServlet; (3).前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器通过适配调用具体的Controller;(Controller--> service --> Dao --> 数据库) Controller执行实现后返回ModelAndView, 提醒:Model(模型数据,即Controller解决的后果,Map) View(逻辑视图名,即负责展现后果的JSP页面的名字) 处理器适配器(HandlerAdapter)将controller执行的后果(ModelAndView)返回给前端控制器(DispatcherServlet); (4).前端控制器(DispatcherServlet)将执行的后果(ModelAndView)传给视图解析器(ViewReslover) 视图解析器(ViewReslover)依据View(逻辑视图名)解析后返回具体JSP页面 (5).前端控制器(DispatcherServlet)依据Model对View进行渲染(行将模型数据填充至视图中); 前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。 其中整个过程中须要开发人员编写的局部有Controller、Service、Dao、View;

October 15, 2020 · 1 min · jiezi

关于spring-mvc:第六阶段-第三模块

/*是包含jsp为尾缀的 只有是负数启动的时候就会加载 视图渲染就是填充数据 tomcat8.5以上会解决get申请中文乱码的问题可是解决不了post申请的中文乱码 参数名要与name统一

October 6, 2020 · 1 min · jiezi

关于spring-mvc:SpringMVC

Spring MVC 简介 MVC是什么 mvc是一种软件架构设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现, @ResponseBody 过后应用此注解形容管制层办法时,用于通知spring框架,这个办法返回字符串尽量转换为json字符串到客户端 理论我的项目中既有页面 还有数据 当应用此注解形容管制层办法时,用于spring框架,这个办法返回值能够依照特定格局(例如json)进行转换 而后将转换当前的后果写到response对象的响应体中 办法的返回值不在封装为ModelAndView对象,不会再交给解析器进行解析,而是间接基于response对象响应到客户端 背景剖析 在大型软件系统设计时,业务个别会绝对简单,例如所有的业务实现的代码都纠缠在一起,会突出 逻辑不清晰,可读性差,保护艰难,改变一处就牵一动员全身等问题。为了更好解决这个问题就有 了咱们当初常说的分层架构 MVC是什么 mvc是一种软件架构的设计思维,基于MVC架构将咱们的应用软件进行分层设计和实现,例如能够 分为视图层(view)管制层(controller),模型层(model),通过这样的分层设计让咱们的程序有更 好的灵活性,和可扩展性,因为这样能够讲一个简单的应用程序进行简化实现各司其职,各尽所能比拟适宜一些大型利用的开发。 Spring MVC概述 springmvc 是mvc 设计思维在spring框架中的一种实现,基于这样的思维spring框架设计一些相干 对象,用于更好的基于mvc架构解决和响应,其简略架构如下图所示 其中: 1)DispatcherServlet是负责客户端所有申请的一个解决的入口,负责申请和转发, 2)RequestMapping负责贮存申请url到后端服务器handler对象对象之间的映射。 3)Handler用于解决DispatcherServlet对象转发过去的申请数据。 4)ViewResolver负责解决所有的Handler对象响应后果中的view。 SpringMVC疾速入门 第一步 创立medule 第二步 创立依赖(能够在module创立时,也能够在创立后)代码如下 第三步 启动我的项目检测控制台启动状态是否为ok Statics目录剖析及利用 Statics目录为Springboot工程创立时增加web依赖当前主动创立的目录,此目录中能够贮存 html,css,js 等相干资源,这些资源能够在启动服务器当前,间接在浏览器上进行拜访。 例如: 第一步: 在statics目录下创立一个index.html(首页)页面,代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>The First Html Page</h1> </body> </html> 第二部:启动服务器并间接进行拜访测试 如图所示: templates目录剖析及利用 templates目录为springboot工程创立时天年假了thymelea当前主动创立的目录,此目录中要贮存 一些html模板,这个模板页面不能间接通过浏览器进行拜访,须要基于后端控制器,在办法中定义 ...

October 5, 2020 · 2 min · jiezi

关于spring-mvc:EasyUISpringMVC上传文件

成果 因为传入的url是一个假的,所以回显的图片和保留的图片不统一 1.jskingEditorParams : { filePostName : "uploadFile", uploadJson : '/pic/upload', dir : "image"},// 初始化图片上传组件initPicUpload : function(data){ $(".picFileUpload").each(function(i,e){ var _ele = $(e); _ele.siblings("div.pics").remove(); _ele.after(' <div class="pics"> <ul></ul> </div>'); // 回显图片 if(data && data.pics){ var imgs = data.pics.split(","); for(var i in imgs){ if($.trim(imgs[i]).length > 0){ _ele.siblings(".pics").find("ul").append("<li><a href='"+imgs[i]+"' target='_blank'><img src='"+imgs[i]+"' width='80' height='50' /></a></li>"); } } } $(e).click(function(){ var form = $(this).parentsUntil("form").parent("form"); KindEditor.editor(TT.kingEditorParams).loadPlugin('multiimage',function(){ var editor = this; editor.plugin.multiImageDialog({ clickFn : function(urlList) { var imgArray = []; KindEditor.each(urlList, function(i, data) { imgArray.push(data.url); form.find(".pics ul").append("<li><a href='"+data.url+"' target='_blank'><img src='"+data.url+"' width='80' height='50' /></a></li>"); }); form.find("[name=image]").val(imgArray.join(",")); editor.hideDialog(); } }); }); }); });}, /** * 初始化单图片上传组件 <br/> * 选择器为:.onePicUpload <br/> * 上传实现后会设置input内容以及在input前面追加<img> */ initOnePicUpload : function(){ $(".onePicUpload").click(function(){ var _self = $(this); KindEditor.editor(TT.kingEditorParams).loadPlugin('image', function() { this.plugin.imageDialog({ showRemote : false, clickFn : function(url, title, width, height, border, align) { var input = _self.siblings("input"); input.parent().find("img").remove(); input.val(url); input.after("<a href='"+url+"' target='_blank'><img src='"+url+"' width='80' height='50'/></a>"); this.hideDialog(); } }); });}); }2.jsp<tr> <td>商品图片:</td> <td> <a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a> <input type="hidden" name="image"/> </td></tr>3.后端实现3.1封装ImageVO特定的格局信息{“error”:0,“url”:“图片的保留门路”,“width”:图片的宽度,“height”:图片的高度}依据easyUI的格局信息封装ImageVO类 ...

September 29, 2020 · 2 min · jiezi

关于spring-mvc:SpringMVC-用于接收参数的注解

如上图中所示:次要分为三个注解: @RequestParam:用于接管 get/post 申请提交的 键值对/表单 参数,个别在申请中传参中能够省略.@PathVariable:用于接管restful格调的申请门路参数,如:http://localhost:8080/123/aa/bb@RequestBody:用于残缺承受post申请协定体中的json数据@RequestBody能够了解为和@ResponseBody是一对的,@RequestBody用于接管json数据,@ResponseBody用于返回json数据

September 22, 2020 · 1 min · jiezi

关于spring-mvc:SpringMVC-参数格式

SpringMVC中参数格局阐明简略参数传值问题阐明:页面传参中 name属性必须与mvc中的数据保持一致.1.页面信息 <input type="text" name="name" value="二郎神"/><input type="text" name="age" value="3500"/>2.服务端接管 public String saveUser(String name,Integer age){....}利用对象的形式接管参数1.页面信息 <input type="text" name="name" value="二郎神"/><input type="text" name="age" value="3500"/>2.服务端接管 public String saveUser(User user){....}mvc为对象的援用赋值问题:如何解决重名提交的问题计划: 能够将对象进行封装,之后采纳对象援用赋值的形式实现该性能.注意事项: 属性的名称必须统一,否则赋值失败. 1.页面信息 <input type="text" name="name" value="二郎神"/><input type="text" name="age" value="3500"/><input type="text" name="dog.name" value="啸天犬"/><input type="text" name="dog.age" value="5000"/> 2.服务端接管 public class User { private String name; private Integer age; private Dog dog;}public class Dog{ private String name; private Integer age;}public String saveUser(User user){....}pojo对象定义理论我的项目中采纳为对象援用赋值的操作. 然而该属性不属于数据库,所以须要额定的配置.长久层若是采纳MP实现,须要在援用赋值的字段增加@TableField(exist=false) //入库操作疏忽该字段配置; 如果间接应用的mybatis,在sql语句中不写援用字段即可.

September 21, 2020 · 1 min · jiezi

关于spring-mvc:Spring-mvc处理web请求简易图解

外围组件剖析: DispatcherServlet :前端控制器, 解决申请的入口。HandlerMapping:映射器对象, 用于治理url与对应controller的映射关系。Controller:后端控制器-handler, 负责解决申请的管制逻辑。ViewResolver:视图解析器,解析对应的视图关系(前缀+viewname+后缀)。

August 4, 2020 · 1 min · jiezi

关于spring-mvc:Spring-mvc处理web请求简易图解

外围组件剖析: DispatcherServlet :前端控制器, 解决申请的入口。HandlerMapping:映射器对象, 用于治理url与对应controller的映射关系。Controller:后端控制器-handler, 负责解决申请的管制逻辑。ViewResolver:视图解析器,解析对应的视图关系(前缀+viewname+后缀)。

August 4, 2020 · 1 min · jiezi

关于spring-mvc:Spring-MVC-理解核心原理-实现轻量级Spring-MVC框架

波及知识点:slf4jjava annotation如何定义通过classloader获取java文件的门路等信息 - https://www.cnblogs.com/seven...map遍历 https://blog.csdn.net/tjcyjd/... 办法二class.forname实例化 https://www.cnblogs.com/shosk...java 反射中的调用办法 - https://www.cnblogs.com/qingc...java 获取我的项目门路的形式第一局部, 工程根底配置创立Dynamic web工程为工程增加runtime librariy. 目标: 为了实现servlet性能 (次要须要其中的servlet-api等jar文件) 此为servlet基础知识. 创立DispatcherServlet并继承HttpServletweb.xml中申明此dispatcherServlet, 目标: ①示意这是个会被tomcat容器辨认的servlet, ②拦挡所有申请 <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringSim2</display-name> <servlet> <servlet-name>springsim2</servlet-name> <servlet-class>com.spring.sim.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>springsim2</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping></web-app>src下创立application.properties, 指定须要被扫描的包 path=com.spring.simweb.xml中将properties文件设置为启动时被load ⚠ 此步骤为可选, 在DispatcherServlet中申明也能够 此步实现后, web.xml不须要再改变 <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SpringSimv1</display-name> <servlet> <servlet-name>springsim</servlet-name> <servlet-class>pro.yizheng.DispatcherServlet</servlet-class> <!-- 指定配置文件 --> <init-param> <param-name>webXmlInitParam-properties</param-name> <param-value>application.properties</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springsim</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping></web-app>申明要用到的Annotation 波及到的annotation有: Autowired, Controller, RequestMapping, RequestParam, Service波及Annotation知识点这一步骤Annotation source code: ...

July 20, 2020 · 2 min · jiezi