淘宝建设网站的目的是什么意思,产品推广平台有哪些,网络app推广公司,企业网站制作与维护10、文件上传和下载
10.1、文件下载
ResponseEntity用于控制器方法的返回值类型#xff0c;该控制器方法的返回值就是响应到浏览器的响应报文
使用ResponseEntity实现下载文件的功能
RequestMapping(/testDown)
public ResponseEntitybyte[] testResp…10、文件上传和下载
10.1、文件下载
ResponseEntity用于控制器方法的返回值类型该控制器方法的返回值就是响应到浏览器的响应报文
使用ResponseEntity实现下载文件的功能
RequestMapping(/testDown)
public ResponseEntitybyte[] testResponseEntity(HttpSession session) throwsIOException {//获取ServletContext对象ServletContext servletContext session.getServletContext();//获取服务器中文件的真实路径String realPath servletContext.getRealPath(/static/img/1.jpg);//创建输入流InputStream is new FileInputStream(realPath);//创建字节数组byte[] bytes new byte[is.available()];//将流读到字节数组中is.read(bytes);//创建HttpHeaders对象设置响应头信息MultiValueMapString, String headers new HttpHeaders();//设置要下载方式以及下载文件的名字headers.add(Content-Disposition, attachment;filename1.jpg);//设置响应状态码HttpStatus statusCode HttpStatus.OK;//创建ResponseEntity对象ResponseEntitybyte[] responseEntity new ResponseEntity(bytes, headers,statusCode);//关闭输入流is.close();return responseEntity;
}10.2、文件上传
文件上传要求form表单的请求方式必须为post并且添加属性enctype“multipart/form-data”
SpringMVC中将上传的文件封装到MultipartFile对象中通过此对象可以获取文件相关信息
上传步骤
①添加依赖
!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --
dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.1/version
/dependency②在SpringMVC的配置文件中添加配置
!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象--
bean idmultipartResolver
classorg.springframework.web.multipart.commons.CommonsMultipartResolver
/bean③控制器方法
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;
}11、拦截器
11.1、拦截器的配置
SpringMVC中的拦截器用于拦截控制器方法的执行
SpringMVC中的拦截器需要实现HandlerInterceptor
SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置
bean classcom.atguigu.interceptor.FirstInterceptor/bean
ref beanfirstInterceptor/ref
!-- 以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截 --
mvc:interceptormvc:mapping path/**/mvc:exclude-mapping path/testRequestEntity/ref beanfirstInterceptor/ref
/mvc:interceptor
!--以上配置方式可以通过ref或bean标签设置拦截器通过mvc:mapping设置需要拦截的请求通过mvc:exclude-mapping设置需要排除的请求即不需要拦截的请求
--11.2、拦截器的三个抽象方法
SpringMVC中的拦截器有三个抽象方法
preHandle控制器方法执行之前执行preHandle()其boolean类型的返回值表示是否拦截或放行返回true为放行即调用控制器方法返回false表示拦截即不调用控制器方法
postHandle控制器方法执行之后执行postHandle()
afterCompletion处理完视图和模型数据渲染视图完毕之后执行afterCompletion()
11.3、多个拦截器的执行顺序
①若每个拦截器的preHandle()都返回true
此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关
preHandle()会按照配置的顺序执行而postHandle()和afterCompletion()会按照配置的反序执行
②若某个拦截器的preHandle()返回了false
preHandle()返回false和它之前的拦截器的preHandle()都会执行postHandle()都不执行返回false的拦截器之前的拦截器的afterCompletion()会执行
12、异常处理器
12.1、基于配置的异常处理
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口HandlerExceptionResolver
HandlerExceptionResolver接口的实现类有DefaultHandlerExceptionResolver和
SimpleMappingExceptionResolver
SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver使用方式
beanclassorg.springframework.web.servlet.handler.SimpleMappingExceptionResolverproperty nameexceptionMappingsprops!--properties的键表示处理器方法执行过程中出现的异常properties的值表示若出现指定异常时设置一个新的视图名称跳转到指定页面--prop keyjava.lang.ArithmeticExceptionerror/prop/props/property!--exceptionAttribute属性设置一个属性名将出现的异常信息在请求域中进行共享--property nameexceptionAttribute valueex/property
/bean12.2、基于注解的异常处理
//ControllerAdvice将当前类标识为异常处理的组件
ControllerAdvice
public class ExceptionController {//ExceptionHandler用于设置所标识方法处理的异常ExceptionHandler(ArithmeticException.class)//ex表示当前请求处理中出现的异常对象public String handleArithmeticException(Exception ex, Model model){model.addAttribute(ex, ex);return error;}
}13、注解配置SpringMVC
使用配置类和注解代替web.xml和SpringMVC配置文件的功能
13.1、创建初始化类代替web.xml
在Servlet3.0环境中容器会在类路径中查找实javax.servlet.ServletContainerInitializer接口的类
如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现名为 SpringServletContainerInitializer这个类反过来又会查找实WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring3.2引入了一个便利的 WebApplicationInitializer基础实现名为AbstractAnnotationConfigDispatcherServletInitializer当我们的类扩展了
AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候容器会自动发现它并用它来配置Servlet上下文。
public class WebInit extendsAbstractAnnotationConfigDispatcherServletInitializer {/*** 指定spring的配置类* return*/Overrideprotected Class?[] getRootConfigClasses() {return new Class[]{SpringConfig.class};}/*** 指定SpringMVC的配置类* return*/Overrideprotected Class?[] getServletConfigClasses() {return new Class[]{WebConfig.class};}/*** 指定DispatcherServlet的映射规则即url-pattern* return*/Overrideprotected String[] getServletMappings() {return new String[]{/};}/*** 添加过滤器* return*/Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter encodingFilter new CharacterEncodingFilter();encodingFilter.setEncoding(UTF-8);encodingFilter.setForceRequestEncoding(true);HiddenHttpMethodFilter hiddenHttpMethodFilter newHiddenHttpMethodFilter();return new Filter[]{encodingFilter, hiddenHttpMethodFilter};}
}13.2、创建SpringConfig配置类代替spring的配置文件
Configuration
public class SpringConfig {//ssm整合之后spring的配置信息写在此类中
}13.3、创建WebConfig配置类代替SpringMVC的配置文件
Configuration
//扫描组件
ComponentScan(com.atguigu.mvc.controller)
//开启MVC注解驱动
EnableWebMvc
public class WebConfig implements WebMvcConfigurer {//使用默认的servlet处理静态资源Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}//配置文件上传解析器Beanpublic CommonsMultipartResolver multipartResolver(){return new CommonsMultipartResolver();}//配置拦截器Overridepublic void addInterceptors(InterceptorRegistry registry) {FirstInterceptor firstInterceptor new FirstInterceptor();registry.addInterceptor(firstInterceptor).addPathPatterns(/**);}//配置视图控制/*Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController(/).setViewName(index);}*///配置异常映射/*Overridepublic void configureHandlerExceptionResolvers(ListHandlerExceptionResolver resolvers) {SimpleMappingExceptionResolver exceptionResolver new SimpleMappingExceptionResolver();Properties prop new Properties();prop.setProperty(java.lang.ArithmeticException, error);//设置异常映射exceptionResolver.setExceptionMappings(prop);//设置共享异常信息的键exceptionResolver.setExceptionAttribute(ex);resolvers.add(exceptionResolver);}*///配置生成模板解析器Beanpublic ITemplateResolver templateResolver() {WebApplicationContext webApplicationContext ContextLoader.getCurrentWebApplicationContext();// ServletContextTemplateResolver需要一个ServletContext作为构造参数可通过WebApplicationContext 的方法获得ServletContextTemplateResolver templateResolver newServletContextTemplateResolver(webApplicationContext.getServletContext());templateResolver.setPrefix(/WEB-INF/templates/);templateResolver.setSuffix(.html);templateResolver.setCharacterEncoding(UTF-8);templateResolver.setTemplateMode(TemplateMode.HTML);return templateResolver;}//生成模板引擎并为模板引擎注入模板解析器Beanpublic SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {SpringTemplateEngine templateEngine new SpringTemplateEngine();templateEngine.setTemplateResolver(templateResolver);return templateEngine;}//生成视图解析器并未解析器注入模板引擎Beanpublic ViewResolver viewResolver(SpringTemplateEngine templateEngine) {ThymeleafViewResolver viewResolver new ThymeleafViewResolver();viewResolver.setCharacterEncoding(UTF-8);viewResolver.setTemplateEngine(templateEngine);return viewResolver;}
}13.4、测试功能
RequestMapping(/)
public String index(){return index;
}14、SpringMVC执行流程
14.1、SpringMVC常用组件
DispatcherServlet前端控制器不需要工程师开发由框架提供
作用统一处理请求和响应整个流程控制的中心由它调用其它组件处理用户的请求
HandlerMapping处理器映射器不需要工程师开发由框架提供
作用根据请求的url、method等信息查找Handler即控制器方法
Handler处理器需要工程师开发
作用在DispatcherServlet的控制下Handler对具体的用户请求进行处理
HandlerAdapter处理器适配器不需要工程师开发由框架提供
作用通过HandlerAdapter对处理器控制器方法进行执行
ViewResolver视图解析器不需要工程师开发由框架提供
作用进行视图解析得到相应的视图例如ThymeleafView、InternalResourceView、
RedirectView
View视图
作用将模型数据通过页面展示给用户
14.2、DispatcherServlet初始化过程
DispatcherServlet 本质上是一个 Servlet所以天然的遵循 Servlet 的生命周期。所以宏观上是 Servlet生命周期来进行调度。 ①初始化WebApplicationContext
所在类org.springframework.web.servlet.FrameworkServlet
protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac null;if (this.webApplicationContext ! null) {// A context instance was injected at construction time - use itwac this.webApplicationContext;if (wac instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac (ConfigurableWebApplicationContext) wac;if (!cwac.isActive()) {// The context has not yet been refreshed - provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() null) {// The context instance was injected without an explicit parent - set// the root application context (if any; may be null) as the parentcwac.setParent(rootContext);}configureAndRefreshWebApplicationContext(cwac);}}}if (wac null) {// No context instance was injected at construction time - see if one// has been registered in the servlet context. If one exists, it is assumed// that the parent context (if any) has already been set and that the// user has performed any initialization such as setting the context idwac findWebApplicationContext();}if (wac null) {// No context instance is defined for this servlet - create a local one// 创建WebApplicationContextwac createWebApplicationContext(rootContext);}if (!this.refreshEventReceived) {// Either the context is not a ConfigurableApplicationContext with refresh// support or the context injected at construction time had already been// refreshed - trigger initial onRefresh manually here.synchronized (this.onRefreshMonitor) {// 刷新WebApplicationContextonRefresh(wac);}}if (this.publishContext) {// Publish the context as a servlet context attribute.// 将IOC容器在应用域共享String attrName getServletContextAttributeName();getServletContext().setAttribute(attrName, wac);}return wac;
}②创建WebApplicationContext
所在类org.springframework.web.servlet.FrameworkServlet
protected WebApplicationContext createWebApplicationContext(Nullable ApplicationContext parent) {Class? contextClass getContextClass();if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)){throw new ApplicationContextException(Fatal initialization error in servlet with name getServletName() : custom WebApplicationContext class [ contextClass.getName() ] is not of type ConfigurableWebApplicationContext);}// 通过反射创建 IOC 容器对象ConfigurableWebApplicationContext wac (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());// 设置父容器wac.setParent(parent);String configLocation getContextConfigLocation();if (configLocation ! null) {wac.setConfigLocation(configLocation);}configureAndRefreshWebApplicationContext(wac);return wac;
}③DispatcherServlet初始化策略
FrameworkServlet创建WebApplicationContext后刷新容器调用onRefresh(wac)此方法在
DispatcherServlet中进行了重写调用了initStrategies(context)方法初始化策略即初始化
DispatcherServlet的各个组件
所在类org.springframework.web.servlet.DispatcherServlet
protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);
}14.3、DispatcherServlet调用组件处理请求
①processRequest()
FrameworkServlet重写HttpServlet中的service()和doXxx()这些方法中调用了
processRequest(request, response)
所在类org.springframework.web.servlet.FrameworkServlet
protected final void processRequest(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException
{long startTime System.currentTimeMillis();Throwable failureCause null;LocaleContext previousLocaleContext LocaleContextHolder.getLocaleContext();LocaleContext localeContext buildLocaleContext(request);RequestAttributes previousAttributes RequestContextHolder.getRequestAttributes();ServletRequestAttributes requestAttributes buildRequestAttributes(request,response, previousAttributes);WebAsyncManager asyncManager WebAsyncUtils.getAsyncManager(request);asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(),new RequestBindingInterceptor());initContextHolders(request, localeContext, requestAttributes);try {// 执行服务doService()是一个抽象方法在DispatcherServlet中进行了重写doService(request, response);}catch (ServletException | IOException ex) {failureCause ex;throw ex;}catch (Throwable ex) {failureCause ex;throw new NestedServletException(Request processing failed, ex);}finally {resetContextHolders(request, previousLocaleContext, previousAttributes);if (requestAttributes ! null) {requestAttributes.requestCompleted();}logResult(request, response, failureCause, asyncManager);publishRequestHandledEvent(request, response, startTime, failureCause);}
}②doService()
所在类org.springframework.web.servlet.DispatcherServlet
Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {logRequest(request);// Keep a snapshot of the request attributes in case of an include,// to be able to restore the original attributes after the include.MapString, Object attributesSnapshot null;if (WebUtils.isIncludeRequest(request)) {attributesSnapshot new HashMap();Enumeration? attrNames request.getAttributeNames();while (attrNames.hasMoreElements()) {String attrName (String) attrNames.nextElement();if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {attributesSnapshot.put(attrName,request.getAttribute(attrName));}}}// Make framework objects available to handlers and view objects.request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,getWebApplicationContext());request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());if (this.flashMapManager ! null) {FlashMap inputFlashMap this.flashMapManager.retrieveAndUpdate(request,response);if (inputFlashMap ! null) {request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE,Collections.unmodifiableMap(inputFlashMap));}request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);}RequestPath requestPath null;if (this.parseRequestPath !ServletRequestPathUtils.hasParsedRequestPath(request)) {requestPath ServletRequestPathUtils.parseAndCache(request);}try {// 处理请求和响应doDispatch(request, response);}finally {if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Restore the original attribute snapshot, in case of an include.if (attributesSnapshot ! null) {restoreAttributesAfterInclude(request, attributesSnapshot);}}if (requestPath ! null) {ServletRequestPathUtils.clearParsedRequestPath(request);}}
}③doDispatch()
所在类org.springframework.web.servlet.DispatcherServlet
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);// Determine handler for the current request./*mappedHandler调用链包含handler、interceptorList、interceptorIndexhandler浏览器发送的请求所匹配的控制器方法interceptorList处理控制器方法的所有拦截器集合interceptorIndex拦截器索引控制拦截器afterCompletion()的执行*/mappedHandler getHandler(processedRequest);if (mappedHandler null) {noHandlerFound(processedRequest, response);return;}// Determine handler adapter for the current request.// 通过控制器方法创建相应的处理器适配器调用所对应的控制器方法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;}}// 调用拦截器的preHandle()if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.// 由处理器适配器调用具体的控制器方法最终获得ModelAndView对象mv ha.handle(processedRequest, response,mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);// 调用拦截器的postHandle()mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException ex;}catch (Throwable err) {// As of 4.3, were processing Errors thrown from handler methods as well,// making them available for ExceptionHandler methods and otherscenarios.dispatchException new NestedServletException(Handler dispatchfailed, err);}// 后续处理处理模型数据和渲染视图 processDispatchResult(processedRequest, response, mappedHandler, mv,dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException(Handler processingfailed,err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler ! null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}
} ④processDispatchResult()
private void processDispatchResult(HttpServletRequest request,HttpServletResponse response,Nullable HandlerExecutionChainmappedHandler, Nullable ModelAndView mv,Nullable Exception exception) throws Exception {boolean errorView false;if (exception ! null) {if (exception instanceof ModelAndViewDefiningException) {logger.debug(ModelAndViewDefiningException encountered,exception);mv ((ModelAndViewDefiningException) exception).getModelAndView();}else {Object handler (mappedHandler ! null ? mappedHandler.getHandler(): null);mv processHandlerException(request, response, handler, exception);errorView (mv ! null);}}// Did the handler return a view to render?if (mv ! null !mv.wasCleared()) {// 处理模型数据和渲染视图render(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}else {if (logger.isTraceEnabled()) {logger.trace(No view rendering, null ModelAndView returned.);}}if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Concurrent handling started during a forwardreturn;}if (mappedHandler ! null) {// Exception (if any) is already handled..// 调用拦截器的afterCompletion()mappedHandler.triggerAfterCompletion(request, response, null);}
} 14.4、SpringMVC的执行流程
1.) 用户向服务器发送请求请求被SpringMVC 前端控制器 DispatcherServlet捕获。
DispatcherServlet对请求URL进行解析得到请求资源标识符URI判断请求URI对应的映射
a) 不存在
i. 再判断是否配置了mvc:default-servlet-handler
ii. 如果没配置则控制台报映射查找不到客户端展示404错误 iii. 如果有配置则访问目标资源一般为静态资源如JS,CSS,HTML找不到客户端也会展示404
错误 b) 存在则执行下面的流程
3.) 根据该URI调用HandlerMapping获得该Handler配置的所有相关的对象包括Handler对象以及Handler对象对应的拦截器最后以HandlerExecutionChain执行链对象的形式返回。
4.) DispatcherServlet 根据获得的Handler选择一个合适的HandlerAdapter。
5.) 如果成功获得HandlerAdapter此时将开始执行拦截器的preHandler(…)方法【正向】
6.) 提取Request中的模型数据填充Handler入参开始执行HandlerController)方法处理请求。
在填充Handler的入参过程中根据你的配置Spring将帮你做一些额外的工作
a) HttpMessageConveter 将请求消息如Json、xml等数据转换成一个对象将对象转换为指定的响应信息
b) 数据转换对请求消息进行数据转换。如String转换成Integer、Double等
c) 数据格式化对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
d) 数据验证 验证数据的有效性长度、格式等验证结果存储到BindingResult或Error中
7.) Handler执行完成后向DispatcherServlet 返回一个ModelAndView对象。
8.) 此时将开始执行拦截器的postHandle(…)方法【逆向】。
9.) 根据返回的ModelAndView此时会判断是否存在异常如果存在异常则执行
HandlerExceptionResolver进行异常处理选择一个适合的ViewResolver进行视图解析根据Model和View来渲染视图。
10.) 渲染视图完毕执行拦截器的afterCompletion(…)方法【逆向】。
11.) 将渲染结果返回给客户端。
四、SSM整合
4.1、ContextLoaderListener
Spring提供了监听器ContextLoaderListener实现ServletContextListener接口可监听
ServletContext的状态在web服务器的启动读取Spring的配置文件创建Spring的IOC容器。web应用中必须在web.xml中配置
listener!--配置Spring的监听器在服务器启动时加载Spring的配置文件Spring配置文件默认位置和名称/WEB-INF/applicationContext.xml可通过上下文参数自定义Spring配置文件的位置和名称--listener-classorg.springframework.web.context.ContextLoaderListener/listener-class
/listener
!--自定义Spring配置文件的位置和名称--
context-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:spring.xml/param-value
/context-param4.2、准备工作
①创建Maven Module
②导入依赖
packagingwar/packaging
propertiesspring.version5.3.1/spring.version
/properties
dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion${spring.version}/version/dependency!--springmvc--dependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion${spring.version}/version/dependency!-- Mybatis核心 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version/dependency!--mybatis和spring的整合包--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.6/version/dependency!-- 连接池 --dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.0.9/version/dependency!-- junit测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency!-- MySQL驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.16/version/dependency!-- log4j日志 --dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -- dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.2.0/version/dependency!-- 日志 --dependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.2.3/version/dependency!-- ServletAPI --dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.1.0/versionscopeprovided/scope/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.12.1/version/dependencydependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.1/version/dependency!-- Spring5和Thymeleaf整合包 --dependencygroupIdorg.thymeleaf/groupIdartifactIdthymeleaf-spring5/artifactIdversion3.0.12.RELEASE/version/dependency
/dependencies ③创建表
CREATE TABLE t_emp (emp_id int(11) NOT NULL AUTO_INCREMENT,emp_name varchar(20) DEFAULT NULL,age int(11) DEFAULT NULL,sex char(1) DEFAULT NULL,email varchar(50) DEFAULT NULL,PRIMARY KEY (emp_id)
) ENGINEInnoDB DEFAULT CHARSETutf84.3、配置web.xml
!-- 配置Spring的编码过滤器 --
filterfilter-nameCharacterEncodingFilter/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueUTF-8/param-value/init-paraminit-paramparam-nameforceEncoding/param-nameparam-valuetrue/param-value/init-param
/filter
filter-mappingfilter-nameCharacterEncodingFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
!-- 配置处理请求方式PUT和DELETE的过滤器 --
filterfilter-nameHiddenHttpMethodFilter/filter-namefilter-classorg.springframework.web.filter.HiddenHttpMethodFilter/filterclass
/filter
filter-mappingfilter-nameHiddenHttpMethodFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
!-- 配置SpringMVC的前端控制器 --
servletservlet-nameDispatcherServlet/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servletclass!-- 设置SpringMVC的配置文件的位置和名称 --init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:SpringMVC.xml/param-value/init-paramload-on-startup1/load-on-startup
/servlet
servlet-mappingservlet-nameDispatcherServlet/servlet-nameurl-pattern//url-pattern
/servlet-mapping
!-- 设置Spring的配置文件的位置和名称 --
context-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:Spring.xml/param-value
/context-param
!-- 配置Spring的监听器 --
listenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class
/listener4.4、创建SpringMVC的配置文件并配置
!--扫描组件--
context:component-scan base-packagecom.atguigu.ssm.controller
/context:component-scan
!--配置视图解析器--
bean idviewResolverclassorg.thymeleaf.spring5.view.ThymeleafViewResolverproperty nameorder value1/property namecharacterEncoding valueUTF-8/property nametemplateEnginebean classorg.thymeleaf.spring5.SpringTemplateEngineproperty nametemplateResolverbeanclassorg.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver!-- 视图前缀 --property nameprefix value/WEB-INF/templates//!-- 视图后缀 --property namesuffix value.html/property nametemplateMode valueHTML5/property namecharacterEncoding valueUTF-8 //bean/property/bean/property
/bean
!-- 配置访问首页的视图控制 --
mvc:view-controller path/ view-nameindex/mvc:view-controller
!-- 配置默认的servlet处理静态资源 --
mvc:default-servlet-handler /
!-- 开启MVC的注解驱动 --
mvc:annotation-driven /4.5、搭建MyBatis环境
①创建属性文件jdbc.properties
jdbc.userroot
jdbc.passwordatguigu
jdbc.urljdbc:mysql://localhost:3306/ssm?serverTimezoneUTC
jdbc.drivercom.mysql.cj.jdbc.Driver②创建MyBatis的核心配置文件mybatis-config.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configuration
PUBLIC -//mybatis.org//DTD Config 3.0//EN
http://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!--将下划线映射为驼峰--setting namemapUnderscoreToCamelCase valuetrue//settingsplugins!--配置分页插件--plugin interceptorcom.github.pagehelper.PageInterceptor/plugin/plugins
/configuration③创建Mapper接口和映射文件
public interface EmployeeMapper {
ListEmployee getEmployeeList();
}?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper
PUBLIC -//mybatis.org//DTD Mapper 3.0//EN
http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.atguigu.ssm.mapper.EmployeeMapperselect idgetEmployeeList resultTypeEmployeeselect * from t_emp/select
/mapper④创建日志文件log4j.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE log4j:configuration SYSTEM log4j.dtd
log4j:configuration xmlns:log4jhttp://jakarta.apache.org/log4j/appender nameSTDOUT classorg.apache.log4j.ConsoleAppenderparam nameEncoding valueUTF-8 /layout classorg.apache.log4j.PatternLayoutparam nameConversionPattern value%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n //layout/appenderlogger namejava.sqllevel valuedebug //loggerlogger nameorg.apache.ibatislevel valueinfo //loggerrootlevel valuedebug /appender-ref refSTDOUT //root
/log4j:configuration4.6、创建Spring的配置文件并配置
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd!--扫描组件--context:component-scan base-packagecom.atguigu.ssmcontext:exclude-filter typeannotationexpressionorg.springframework.stereotype.Controller//context:component-scan!-- 引入jdbc.properties --context:property-placeholder locationclasspath:jdbc.properties/context:property-placeholder!-- 配置Druid数据源 --bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- 配置用于创建SqlSessionFactory的工厂bean --bean classorg.mybatis.spring.SqlSessionFactoryBean!-- 设置MyBatis配置文件的路径可以不设置 --property nameconfigLocation valueclasspath:mybatis-config.xml/property!-- 设置数据源 --property namedataSource refdataSource/property!-- 设置类型别名所对应的包 --property nametypeAliasesPackage valuecom.atguigu.ssm.pojo/property!--设置映射文件的路径若映射文件所在路径和mapper接口所在路径一致则不需要设置--!--property namemapperLocations valueclasspath:mapper/*.xml/property--/bean!--配置mapper接口的扫描配置由mybatis-spring提供可以将指定包下所有的mapper接口创建动态代理并将这些动态代理作为IOC容器的bean管理--bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.atguigu.ssm.mapper/property/bean
/beans4.7、测试功能
①创建组件
实体类Employee
public class Employee {private Integer empId;private String empName;private Integer age;private String sex;private String email;public Employee() {}public Employee(Integer empId, String empName, Integer age, String sex,String email) {this.empId empId;this.empName empName;this.age age;this.sex sex;this.email email;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId empId;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex sex;}public String getEmail() {return email;}public void setEmail(String email) {this.email email;}
}创建控制层组件EmployeeController
Controller
public class EmployeeController {Autowiredprivate EmployeeService employeeService;RequestMapping(value /employee/page/{pageNum}, method RequestMethod.GET)public String getEmployeeList(Model model, PathVariable(pageNum) Integer pageNum){PageInfoEmployee page employeeService.getEmployeeList(pageNum);model.addAttribute(page, page);return employee_list;}
}创建接口EmployeeService
public interface EmployeeService {PageInfoEmployee getEmployeeList(Integer pageNum);
}创建实现类EmployeeServiceImpl
Service
public class EmployeeServiceImpl implements EmployeeService {Autowiredprivate EmployeeMapper employeeMapper;Overridepublic PageInfoEmployee getEmployeeList(Integer pageNum) {PageHelper.startPage(pageNum, 4);ListEmployee list employeeMapper.getEmployeeList();PageInfoEmployee page new PageInfo(list, 5);return page;}
}②创建页面
!DOCTYPE html
html langen xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8titleEmployee Info/titlelink relstylesheet th:href{/static/css/index_work.css}/headbodytabletrth colspan6Employee Info/th/trtrthemp_id/ththemp_name/ththage/ththsex/ththemail/ththoptions/th/trtr th:eachemployee : ${page.list}td th:text${employee.empId}/tdtd th:text${employee.empName}/tdtd th:text${employee.age}/tdtd th:text${employee.sex}/tdtd th:text${employee.email}/tdtda hrefdelete/aa hrefupdate/a/td/trtrtd colspan6span th:if${page.hasPreviousPage}a th:href{/employee/page/1}首页/aa th:href{/employee/page/${page.prePage}}上一页/a/spanspan th:eachnum : ${page.navigatepageNums}a th:if${page.pageNumnum}th:href{/employee/page/${num}} th:text[${num}] stylecolor:red;/aa th:if${page.pageNum!num}th:href{/employee/page/${num}} th:text${num} /a/spanspan th:if${page.hasNextPage}a th:href{/employee/page/${page.nextPage}}下一页/aa th:href{/employee/page/${page.pages}}末页/a/span/td/tr/table/body
/html③访问测试分页功能 创建接口EmployeeServicejava
public interface EmployeeService {PageInfoEmployee getEmployeeList(Integer pageNum);
}创建实现类EmployeeServiceImpl
Service
public class EmployeeServiceImpl implements EmployeeService {Autowiredprivate EmployeeMapper employeeMapper;Overridepublic PageInfoEmployee getEmployeeList(Integer pageNum) {PageHelper.startPage(pageNum, 4);ListEmployee list employeeMapper.getEmployeeList();PageInfoEmployee page new PageInfo(list, 5);return page;}
}②创建页面
!DOCTYPE html
html langen xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8titleEmployee Info/titlelink relstylesheet th:href{/static/css/index_work.css}/headbodytabletrth colspan6Employee Info/th/trtrthemp_id/ththemp_name/ththage/ththsex/ththemail/ththoptions/th/trtr th:eachemployee : ${page.list}td th:text${employee.empId}/tdtd th:text${employee.empName}/tdtd th:text${employee.age}/tdtd th:text${employee.sex}/tdtd th:text${employee.email}/tdtda hrefdelete/aa hrefupdate/a/td/trtrtd colspan6span th:if${page.hasPreviousPage}a th:href{/employee/page/1}首页/aa th:href{/employee/page/${page.prePage}}上一页/a/spanspan th:eachnum : ${page.navigatepageNums}a th:if${page.pageNumnum}th:href{/employee/page/${num}} th:text[${num}] stylecolor:red;/aa th:if${page.pageNum!num}th:href{/employee/page/${num}} th:text${num} /a/spanspan th:if${page.hasNextPage}a th:href{/employee/page/${page.nextPage}}下一页/aa th:href{/employee/page/${page.pages}}末页/a/span/td/tr/table/body
/html③访问测试分页功能
localhost:8080/employee/page/1