宁波怎么建网站模板站,重庆网络科技有限公司,优化网站用什么软件好,wordpress static page1.SpringMVC介绍
SpringMVC是Spring框架中的一个组件#xff0c;是一个轻量级的web的MVC框架#xff0c;充当controller,其本质就是一个Servlet。
1.1 传统Servlet的不足
每个请求#xff0c;都需要定义一个Servlet。虽然可以在service方法中#xff0c;根据业务标识进行…1.SpringMVC介绍
SpringMVC是Spring框架中的一个组件是一个轻量级的web的MVC框架充当controller,其本质就是一个Servlet。
1.1 传统Servlet的不足
每个请求都需要定义一个Servlet。虽然可以在service方法中根据业务标识进行业务分发但是每个Servlet中的service方法的实现是重复。如果想要对service进行更高层次的封装就可以解决service的重复代码问题。
每个请求的参数都需要根据request对象从Map逐一的获取单调且含量低。将所有的参数自动封装映射简化开发。
request.getParameter(“”)
每个Servlet向客户端返回数据时需要单独的处理。
request.getRequestDispatcher(“/路径”).forward(request,response)
Response.sendRedirect(“/路径”)
针对于Servlet在实际使用中的不便Spring中提供了组件SpringMVC,更进一步的简化了Servlet的开发。
1.2 SpringMVC的架构 1.2.1 DispatcherServlet 核心控制器本质上就是一个Servlet处理所有的客户端的请求。根据请求的资源路径在处理器映射器中查找对应的处理器。
1.2.2 HandlerMapping 处理器映射器存储所有当前程序中的处理器如果在处理器映射器中查找不到资源路径直接返回404。
1.2.3 HandlerAdapter 处理器适配器用于适配各种处理器调用具体的处理器程序。
1.2.4 Handler 具体处理器开发者实现相应接口或者使用注解声明的程序。用于处理具体的请求。
1.2.5 ViewResolver 视图解析器根据处理器返回的数据进行数据处理将数据处理成相应的格式。
JSP/JSON等等。
2.SpringMVC使用
2.1 SpringMVC入门使用
2.1.1 导入SpringMVC相关jar包
?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactId01-mvc01/artifactIdversion1.0-SNAPSHOT/versionpackagingwar/packagingpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.target/propertiesdependencies!-- 引入springmvc 相关jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.2.0.RELEASE/version/dependency/dependencies
/project2.1.2 编写SpringMVC配置文件
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 配置了一个自定义的处理器 --bean idcontroller01 name/controller01.do classcom.bjpowernode.controller.Controller01/beanbean idcontroller02 name/controller02.do classcom.bjpowernode.controller.Controller02/bean!-- 开启springmvc 注解 --!-- 开启组件扫描 --context:component-scan base-packagecom.* /!-- 开启springmvc 相关注解 --mvc:annotation-driven /
/beans2.1.3 编写相关类
package com.bjpowernode.controller;import org.springframework.web.HttpRequestHandler;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class Controller01 implements HttpRequestHandler {Overridepublic void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {System.out.println(你好啊 springmvc);}
}package com.bjpowernode.controller;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 Controller02 implements Controller {Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {System.out.println(Hello SpringMVC 02);//模型视图//模型就是数据//视图 界面ModelAndView modelAndView new ModelAndView();modelAndView.addObject(name,Hello SpringMVC);modelAndView.setViewName(/index.html);//springmvc中 /表示当前项目return modelAndView;}
}package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller
RequestMapping
public class Controller03 {RequestMapping(hello1.do)public String hello(String name){System.out.println(name:name);System.out.println(你好springmvc);return /index.html;}RequestMapping(hello2.do)public String hello1(String name){System.out.println(name:name);System.out.println(你好springmvc);return /index.html;}
}2.1.4 在web.xml中配置SpringMVC
!DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-nameservletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!-- 配置自定义的处理器清单 --init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc.xml/param-value/init-param!-- 配置服务器启动时 就初始化DispatcherServlet --load-on-startup1/load-on-startup/servletservlet-mappingservlet-namespringmvc/servlet-nameurl-pattern*.do/url-pattern/servlet-mapping
/web-app2.1.5 进行测试
使用bean标签的name属性进行访问。注意每个名字必须有个/,如果多个名字之间使用逗号。
2.2 SpringMVC的数据绑定
在SpringMVC中为了简化开发SpringMVC对请求的参数进行预处理SpringMVC支持按照参数名称直接将请求参数封装传递给处理器中的方法处理无需单独的获取。
2.2.1 请求参数 请求参数是指基本数据类型和字符串、对象、数组、Map等。
2.2.2 获取请求参数
package com.bjpowernode.controller;import com.bjpowernode.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.Arrays;
import java.util.List;
import java.util.Map;
Controller
RequestMapping(/param)
public class ParamController {/*** 处理简单的参数* return*/RequestMapping(/simple.do)public String doSimpleParam(Integer id,boolean flag,String name,RequestParam(City) String city){System.out.println(id: id);System.out.println(flag: flag);System.out.println(name: name);System.out.println(city: city);return /success.html;//默认当做内部转发处理 默认当做视图路径}/*** 使用对象接收请求参数* 请求参数的名称 必须 和 对象中属性名一致 类型要支持转换* param user* return*/RequestMapping(/obj.do)public String objParam(User user){System.out.println(id: user.getId());System.out.println(flag: user.getFlag());System.out.println(name: user.getName());return /success.html;//默认当做内部转发处理 默认当做视图路径}/*** 使用map接收请求参数* 默认是不支持使用map集合接收数据 需要使用注解RequestParam* RequestParam :* name/value : 绑定请求参数 ,默认根据名称注入值,当名称不一致,可以使用RequestParam设置对应的参数的名称进行绑定* required 是否需要这个参数 默认true 如果有使用了RequestParam这个注解默认必须传这个参数 如果不是必传 设置为 false* defaultValue : 如果没有这个请求参数时或者请求参数值为null 设置默认值* param param* return*/RequestMapping(/map.do)public String mapParam(RequestParam MapString,Object param){System.out.println(id: param.get(id));System.out.println(flag: param.get(flag));System.out.println(name: param.get(name));return /success.html;//默认当做内部转发处理 默认当做视图路径}RequestMapping(/arr.do)public String arr(Integer id,boolean flag,String name,String[] likes){System.out.println(id: id);System.out.println(flag: flag);System.out.println(name: name);ListString strings Arrays.asList(likes);System.out.println(strings);return /success.html;//默认当做内部转发处理 默认当做视图路径}RequestMapping(/list.do)public String arr(Integer id,boolean flag,String name,RequestParam(likes) ListString likes){System.out.println(id: id);System.out.println(flag: flag);System.out.println(name: name);System.out.println(likes);return /success.html;//默认当做内部转发处理 默认当做视图路径}
}2.2.3 页面代码
html
headtitleTitle/title
/head
body
h1简单的数据/h1
form actionparam/simple.do methodgetpID:input nameid //ppboolean:input nameflag typeradio valuetrue /男input nameflag typeradio valuefalse /女/ppString:input namename //ppcity:input nameCity //pinput typesubmit value提交 /
/form
h1对象的数据/h1
form actionparam/obj.do methodgetpID:input nameid //ppboolean:input nameflag typeradio valuetrue /男input nameflag typeradio valuefalse /女/ppString:input namename //pinput typesubmit value提交 /
/form
h1map的数据/h1
form actionparam/map.do methodgetpID:input nameid //ppboolean:input nameflag typeradio valuetrue /男input nameflag typeradio valuefalse /女/ppString:input namename //pinput typesubmit value提交 /
/form
h1数组的数据/h1
form actionparam/arr.do methodgetpID:input nameid //ppboolean:input nameflag typeradio valuetrue /男input nameflag typeradio valuefalse /女/ppString:input namename //pplikes:input namelikes typecheckbox value篮球 /篮球input namelikes typecheckbox value足球 /足球/pinput typesubmit value提交 /
/form
h1list的数据/h1
form actionparam/list.do methodgetpID:input nameid //ppboolean:input nameflag typeradio valuetrue /男input nameflag typeradio valuefalse /女/ppString:input namename //pplikes:input namelikes typecheckbox value篮球 /篮球input namelikes typecheckbox value足球 /足球/pinput typesubmit value提交 /
/form
/body
/html2.3 SpringMVC的跳转
在SpringMVC中默认的跳转方式内部转发,每个URL前面默认有forward:
默认会将方法的返回值当做视图的路径处理。并且在SpringMVC中/表示当前项目根目录。如果想要使用重定向则使用关键字redirect:/路径。
2.3.1 代码示例
package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller
RequestMapping(jump)
public class JumpController {RequestMapping(forward.do)public String forward(){System.out.println(内部转发跳转!);return forward:/success.html;}RequestMapping(forward1.do)public String forward1(){System.out.println(内部转发跳转!);return /success.html;}RequestMapping(redirect.do)public String redirect(){System.out.println(重定向跳转!);return redirect:/success.html;}
}2.4 SpringMVC支持内置的对象
在SpringMVC中支持为处理器中的方法注入内置的对象如HttpServletRequest、HttpServletResponse、HttpSession、Model等。
/**** param request* param resp* param session* param model 是springmvc中 推荐使用参数传递的容器 当参数发生覆盖 优先使用model中的参数* throws IOException*/
RequestMapping(servletParam.do)
public void servletParam(HttpServletRequest request, HttpServletResponse resp, HttpSession session, Model model) throws IOException {String name request.getParameter(name);System.out.println(name);System.out.println(request);System.out.println(resp);System.out.println(session);System.out.println(model);resp.sendRedirect(success.html);//return /success.html;
}2.5 SpringSpringMVCMybatis整合
2.5.1 创建项目导入jar包
?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactId02-mvc01/artifactIdversion1.0-SNAPSHOT/versionpackagingwar/packagingpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetspring.version5.2.0.RELEASE/spring.version
/properties
dependencies!--servlet-api--dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion4.0.1/version/dependency!-- jsp-api --dependencygroupIdjavax.servlet.html/groupIdartifactIdjsp-api/artifactIdversion2.2/version/dependency!-- jstl jar --dependencygroupIdorg.glassfish.web/groupIdartifactIdjstl-impl/artifactIdversion1.2/version/dependency!-- spring相关jar --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependency!-- spring相关jar 结束 --!-- mysql 数据库 jar --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.49/version/dependency!-- mysql 数据库 end --!-- mybatis 开始 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version/dependency!-- mybatis 结束 --!-- mybatis 和 spring的整合包 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.4/version/dependency!-- mybatis 和 spring的整合包 end --!-- 日志 开始 --dependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependencydependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-core/artifactIdversion2.13.3/version/dependency!-- 日志 结束 --!--pagehelper分页--dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.2.0/version/dependency!-- 分页插件 结束 --!-- lombok 开始 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.12/version/dependency!-- lombok 结束 --
/dependenciesbuildresourcesresourcedirectorysrc/main/java/directoryincludesinclude**/*.xml/include/includes/resource/resources
/build/project2.5.2 定义相关类
2.5.2.1 domain
package com.bjpowernode.domain;import lombok.Data;
/*** Description: 用户类*/
Data
public class User {private Integer id;private String username;private String password;private String realname;
}2.5.2.2 mapper
package com.bjpowernode.mapper;import com.bjpowernode.domain.User;import java.util.List;/*** Description: 用户数据操作类*/
public interface UserMapper {/*** 查询所有 用户信息* return*/ListUser selectAll();
}2.5.2.3 service
package com.bjpowernode.service;import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;public interface IUserService {/*** 分页查询数据* param page* param limit* return*/PageInfoUser queryPage(Integer page,Integer limit);
}package com.bjpowernode.service.impl;import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;
import com.bjpowernode.mapper.UserMapper;
import com.bjpowernode.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** Description: 用户业务实现类*/
Service
public class UserServiceImpl implements IUserService {Autowiredprivate UserMapper userMapper;/*** 分页查询数据* param page* param limit* return*/Overridepublic PageInfoUser queryPage(Integer page, Integer limit) {PageUser pageObj PageHelper.startPage(page, limit);userMapper.selectAll();return pageObj.toPageInfo();}
}2.5.2.4 controller
package com.bjpowernode.controller;import com.github.pagehelper.PageInfo;
import com.bjpowernode.domain.User;
import com.bjpowernode.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;/*** Description: 用户控制类*/
Controller
RequestMapping(user)
public class UserController {Autowiredprivate IUserService userService;RequestMapping(page.do)public ModelAndView page(RequestParam(name page,required false,defaultValue 1) Integer page, RequestParam(name limit,required false,defaultValue 10) Integer limit){PageInfoUser pageInfo userService.queryPage(page, limit);ModelAndView modelAndView new ModelAndView();//设置视图路径modelAndView.setViewName(/list.html);//设置数据modelAndView.addObject(pageInfo,pageInfo);return modelAndView;}
}2.5.2.5 页面
html
headtitleTitle/title
/head
bodytable theadthID/ththusername/ththpassword/ththrealname/th/thead/table
/body
/html2.5.3 配置文件 2.5.3.1 数据库配置文件 #数据库连接信息 jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/stmng?useUnicodetruecharacterEncodingutf8useSSLfalse jdbc.usernameroot jdbc.passwordroot 2.5.3.2 日志配置文件
# 全局日志配置
log4j.rootLoggerDEBUG, stdout
# MyBatis 日志配置
log4j.logger.org.mybatis.example.BlogMapperTRACE
# 控制台输出
log4j.appender.stdoutorg.apache.log4j.ConsoleAppender
log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern%5p [%t] - %m%n2.5.3.3 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/context xmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd!-- 整合mybatis --!--1. 引入数据库配置文件 因为创建数据源 --context:property-placeholder locationclasspath:jdbc.properties system-properties-modeFALLBACK /!--2. 创建数据源--bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!--3. 创建SqlSessionFactoryBean --!-- configuration 指 mybatis的核心配制信息 --bean idconfiguration classorg.apache.ibatis.session.Configurationproperty namelogImpl valueorg.apache.ibatis.logging.log4j.Log4jImpl/property namecacheEnabled valuetrue //beanbean idsqlSessionFactoryBean classorg.mybatis.spring.SqlSessionFactoryBean!-- 数据源 --property namedataSource refdataSource/!-- 使用 configuration 取代了 mybatis的核心配置文件--property nameconfiguration refconfiguration/!-- 配置mapper 映射 文件--property namemapperLocations valueclasspath:mapper/**Mapper.xml /!-- 配置类别名 --property nametypeAliasesPackage valuecom.bjpowernode.domain /!-- 配制插件 --property namepluginsarray!-- 分页插件 --bean classcom.github.pagehelper.PageInterceptor //array/property/bean!--4. Mapper接口的扫描 自动创建代理类 --bean classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 被扫描的mapper接口 产生接口的实现类 对象 使用SqlSession.getMapper(接口.class) --property namebasePackage valuecom.bjpowernode.mapper /!-- 注入一个SqlSessionFactoryBean 为了产生 SqlSession --property namesqlSessionFactoryBeanName valuesqlSessionFactoryBean //bean!-- 5. 配置事务 --bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager!-- 指定被管理事务的数据源 --property namedataSource refdataSource //bean!-- 配置声明式事务 XML 注解 --!-- 开启事务注解 --tx:annotation-driven transaction-managertransactionManager /!-- 开启组件扫描 创建 对象 --context:component-scan base-packagecom.bjpowernode /
/beans2.5.3.4 springmvc配置文件
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 开启组件扫描 --!-- 扫描的目的是为了将 处理器放入到HandlerMapping中 --context:component-scan base-packagecom.bjpowernode.controller /!-- 开启springmvc注解 --mvc:annotation-driven /
/beans2.5.3.5 Mapper配置文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.bjpowernode.mapper.UserMapperselect idselectAll resultTypeUserselect * from user/select
/mapper2.5.3.6 web.xml
!DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd
web-appdisplay-nameArchetype Created Web Application/display-name!-- 配置监听器需要加载的配置文件 --context-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:spring-context.xml/param-value/context-param!-- 加载初始化spring核心配置文件配置监听器 启动时就加载 spring核心配置文件 IOC容器相关初始化--listenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!-- 配置 springmvc --servletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-classinit-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc.xml/param-value/init-paramload-on-startup1/load-on-startup/servletservlet-mappingservlet-namespringmvc/servlet-nameurl-pattern*.do/url-pattern/servlet-mapping
/web-app2.6 SpringMVC获取Servlet作用域
package com.bjpowernode.util;import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** Description: 获取Servlet 作用域对象工具类* HttpServletRequest* HttpSession* ServletContext*/
public class WebScopeUtil {/*** 获取当前 HttpServletRequest 对象* return*/public static HttpServletRequest getRequest(){ServletRequestAttributes requestAttributes (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();return requestAttributes.getRequest();}/*** 获取当前请求绑定的session* return*/public static HttpSession getSession(){return getRequest().getSession();}/*** 获取全局容器对象* return*/public static ServletContext getContext(){//getRequest().getServletContext(); // ServletContext 的生命周期 是早于 HttpServletRequest//所以不能通过 HttpServletRequest 获取ServletContext 可能发生 NullpointExceptionreturn ContextLoader.getCurrentWebApplicationContext().getServletContext();}
}2.7 SpringMVC内置的编码过滤器
在springmvc中为了解决乱码问题springmvc提供了内置的编码过滤器。在使用时只需要在web.xml中进行配置即可。
!-- 编码过滤器 --
filterfilter-namecharsetFilter/filter-name!-- 配置内置的编码过滤器 --filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class!-- 为编码过滤器指定编码 --init-paramparam-nameencoding/param-nameparam-valueUTF-8/param-value/init-param
/filter
filter-mappingfilter-namecharsetFilter/filter-name!-- 只对springmvc处理的请求进行编码过滤 --servlet-namespringmvc/servlet-name
/filter-mapping2.8 SpringMVC返回JSON
{key1:value1,key2:value2}:key为Stringvalue为Object [{},{},{}…]
实体类对象、MapString,Object、List实体类、ListMapString,Object
fastjson.jar: JSON.toJSONString(Object)
在springmvc中默认返回的数据不论是什么格式都当做视图进行解析。会根据返回值的toString的结果,当做路径去查找视图的模板,如果想要返回JSON,则需要使用注解,标识该方法返回的是JSON数据,不要当做视图路径进行路径的查找.该注解为:ResponseBody.因为springmvc有内置的消息转换器,如果想要特殊设置,需要进行XML配置.
2.8.1 XML配置的形式 XML配置形式是修改了默认结果处理全局生效的。使用注解ResponseBody标识该方法返回的内容不是URL地址而是一个消息使用输出对象输出给客户端。
RequestMapping
name : 方法映射名称
value/path : 方法访问路径
method : 支持的请求的方法类型
GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE
params 请求必须有的参数
headers 请求必须有的头信息
consumes 指定请求的数据格式类型 普通文本、表单格式、JSON
produces 指定返回数据的格式类型 JSON 、HTML
!-- 配置JSON转换器 --
!--bean idconfig classcom.alibaba.fastjson.support.config.FastJsonConfig--
!--/bean--
mvc:annotation-driven mvc:message-converters register-defaultstrue!--将内容转化为字符串消息 使用 IO发送给客户端此时只支持字符串--!--bean classorg.springframework.http.converter.StringHttpMessageConverter /--!-- 将内容转化为JSON字符串 发送客户端 能够处理对象--!-- date 年-月-日 时分秒 --bean classcom.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter //mvc:message-converters
/mvc:annotation-driven2.8.2 注解 SpringMVC中有内置的转换器但是SpringMVC内置的转换器需要相关jar包需要jackson的jar包。只需要导入jar包后使用ResponseBody标识返回的数据是消息即可。SpringMVC自动将返回数据当做JSON字符串处理并且消息按照UTF-8进行编码。如果ResponseBody放在类上类中所有的方法都返回的是消息不是视图资源。
注意
RestController
是 ResponseBody Controller 结合标识该类是一个处理器并且处理器中所有的方法都返回的是消息。
!-- 导入jackson的jar包 --
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.11.2/version
/dependency
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.11.2/version
/dependency
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.11.2/version
/dependency2.9 文件上传下载
在springmvc中也对文件上传进行了封装。更进一步的简化的文件上传只需导入文件上传相关的jar包和处理文件上传的解析器即可。
2.9.1 文件上传 2.9.1.1 导入jar包
!-- 文件上传相关依赖jar --
dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.4/version
/dependency2.9.1.2 配置文件上传的解析器
在SpringMVC的核心配置文件中新增文件上传解析器配置: bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver!--文件格式编码--property namedefaultEncoding valueUTF-8/property!--配置单个文件上传大小:1M--property namemaxUploadSizePerFile value1048576/property!--配置所有文件上传总大小:10M--property namemaxUploadSize value10485760/property/bean2.9.1.3 处理文件上传请求
页面
html
headtitle文件上传/title
/head
body
form actionfile/upload2.do methodpost enctypemultipart/form-datap普通的文本数据:input namename typetext //pp文件数据:input nameuserImg typefile //pp文件数据:input nameuserImg typefile //pinput typesubmit value提交
/form
/body
/html处理器
package com.bjpowernode.controller;
import cn.hutool.core.img.Img;
import cn.hutool.core.img.ImgUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;Controller
RequestMapping(file)
public class FileUploadController {/*** 如果是单个文件则直接使用MultipartFile 对象进行接收* 普通的文本数据 则直接使用相应的类型进行接收* 如果名字不一致 RequestParam 注解 处理名称* param name* param file* return*/RequestMapping(upload1.do)public String upload1(String name,RequestParam(userImg) MultipartFile file){System.out.println(文本数据为:name);System.out.println(文件数据为:file.getName());//input name 属性值System.out.println(文件数据为:file.getSize()); // 文件的字节大小System.out.println(文件数据为:file.getOriginalFilename()); //文件的真实名称return /success.html;}/*** 如果是多个文件 则使用MultipartFile[] 数组进行接收* param name* param files* return*/RequestMapping(upload2.do)public String upload2(String name,RequestParam(userImg) MultipartFile[] files){System.out.println(文本数据为:name);for (MultipartFile file : files) {System.out.println(文件数据为:file.getName());//input name 属性值System.out.println(文件数据为:file.getSize()); // 文件的字节大小System.out.println(文件数据为:file.getOriginalFilename()); //文件的真实名称//将文件进行保存File newFile new File(d://file.getOriginalFilename());try {Font font new Font(微软雅黑,Font.BOLD,15);ImgUtil.pressText(file.getInputStream(),new FileOutputStream(newFile),我是水印, Color.RED,font,1,1,0.5f);//将文件保存在磁盘上//file.transferTo(newFile);} catch (IOException e) {e.printStackTrace();}}return /success.html;}
}/*** 一个file控件同时上传多个* MultipartFile代表一个文件 MultipartRequest封装了多个MultipartFile对象*/
RequestMapping(/uploadMany2.do)
public void uploadMany2(MultipartRequest mr) throws IOException {ListMultipartFile fileList mr.getFiles(f);for (int i 0;fileList!null i fileList.size(); i) {MultipartFile tempFile fileList.get(i);//将上传的文件保存到D:\\uploads\\String name tempFile.getOriginalFilename();//获取上传文件的名字 1.2.3.jpg 1.jpg 1.avi C:\\users\\desktop\\1.jpg//获取上传文件的拓展名int index name.lastIndexOf(.);String ext name.substring(index);//.jpg .avi .pptx//将上传的文件保存到指定目录String fileName UUID.randomUUID().toString();File file new File(D:\\uploads\\fileNameext);tempFile.transferTo(file);}
}2.9.2 文件下载
2.9.2.1 方案一推荐 文件下载的本质就是获取服务器的文件数据信息使用字节流将数据传递给客户端。 使用输入流将磁盘文件读到内存中。 使用网络输出流将数据输出给客户端。
package com.bjpowernode.controller;import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;/*** Description: 文件下载示例*/
Controller
RequestMapping(download)
public class DownLoadController {/*** 文件下载的方法*/RequestMapping(download.do)public void download(HttpServletResponse response) throws Exception {File file new File(E:\\猪图片.jpg);//本地磁盘文件//使用输入流 将文件读入内存中FileInputStream fis new FileInputStream(file); // 找参照物 将程序运行的内存当做参照物byte[] b new byte[1024];int len -1;ServletOutputStream out response.getOutputStream();//输出流 输出客户端//浏览器 默认打开了这个文件//设置响应类型 通知浏览器 不要打开response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);//文件的名称 不对//设置响应的文件的名称//如果响应的数据的名称是中文在设置文件的名称时 要先将文件的名称进行编码 再进行传输String name URLEncoder.encode(猪图片.jpg, UTF-8);System.out.println(编码后的名字:name);response.setHeader(Content-Disposition, attachment; filenamename);//循环读 循环写while((len fis.read(b)) ! -1) {out.write(b,0,len);out.flush();}out.close();fis.close();}
}2.9.2.2 方案二
springMVC中为了简化文件的下载封装了实体类ResponseEntity可以将文件数据封装在ResponseEntity中。
package com.bjpowernode.controller;import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;/*** Description: 文件下载示例*/
Controller
RequestMapping(/download)
public class DownLoadController {RequestMapping(/download2.do)public ResponseEntityByte[] download() throws Exception {File file new File(E:\\猪图片.jpg);//本地磁盘文件//使用输入流 将文件读入内存中FileInputStream fis new FileInputStream(file); // 找参照物 将程序运行的内存当做参照物//文件的大小long length file.length();//创建一个和文件一样大小的字节数组 一次性将数据读入到内存中 如果文件量过大请求比较频繁 存在 崩溃的风险byte[] fileByte new byte[(int) length];//一个G 的 byte 数组 64 G 65个人下载 1分钟//一次性将文件数据读入到数组中fis.read(fileByte);// springmvc 中封装的 响应实体 //设置响应码//设置响应的数据头信息//设置响应数据HttpHeaders headers new HttpHeaders(); //响应头信息//设置响应的数据为流数据 告诉浏览器 不要解析headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置下载的文件的名称 中文字符串要进行编码headers.setContentDispositionFormData(filename,猪图片.jpg);ResponseEntity responseEntity new ResponseEntity(fileByte,headers, HttpStatus.OK);return responseEntity;}
}2.10 SpringMVC中的拦截器
SpringMVC提供HandlerInteceptor接口这个接口用于拦截处理具体的Handler中的方法在具体的Handler中的方法执行前后及返回视图之间都可以进行相关扩展操作。
2.10.1 如何使用拦截器 2.10.1.1 创建类实现HandlerInteceptor接口
package com.bjpowernode.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Description: 自定义拦截器*/
public class MyInterceptor implements HandlerInterceptor {/*** 在执行具体的Handler中的方法前执行* param request 当前的请求对象* param response 当前的响应对象* param handler 具体的处理器中将要执行的方法* return boolean 如果 返回 true 则执行Handler中的方法 false 则 不执行handler中的方法* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(我是拦截器中preHandle 方法);return true;}/*** 在具体的Handler中的方法执行完成 但是没有做具体的视图解析操作* param request 当前 请求对象* param response 当前响应对象* param handler 具体的处理器中将要执行的方法* param modelAndView 具体的处理器中将要执行的方法 返回的结果* throws Exception*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(我是拦截器中postHandle 方法);//在具体的解析之前 修改视图模型中数据modelAndView.addObject(name,韩梅梅);}/*** 完成了视图解析后 整个方法执行完成调用的方法 在finally中调用 或者出现异常也会调用* param request 当前请求对象* param response 当前响应对象* param handler 具体的处理器中将要执行的方法* param ex 具体的处理器中抛出的异常* throws Exception*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(我是拦截器中afterCompletion 方法);System.out.println(ex.getMessage());request.setAttribute(msg,网管去火星了!);request.getRequestDispatcher(/500.html).forward(request,response);}
}
2.10.1.2 配置拦截器
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 开启组件扫描 --!-- 扫描所有处理器 放入到处理器映射器中 --context:component-scan base-packagecom.bjpowernode.controller /!-- 开启 mvc注解 --mvc:annotation-driven/mvc:annotation-driven!-- 文件上传的解析器 --bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver !--property namemaxUploadSize value1/property--/bean!-- 配置springmvc的拦截器 --mvc:interceptorsmvc:interceptor!-- 拦截器的资源路径 /** 拦截所有 ** 表示多层目录 --mvc:mapping path/**/!-- 不拦截的资源路径 --mvc:exclude-mapping path/user/page.do/!-- 自定义的拦截器 --bean idmyInterceptor classcom.bjpowernode.interceptor.MyInterceptor //mvc:interceptor/mvc:interceptors
/beans注意 在拦截器中最先执行preHandle然后执行Handler中具体的方法再然后执行postHandle和afterCompletion。preHandle就是前置的拦截的方法返回如果为true则执行处理器中的方法如果为false则不执行处理器中的方法。postHandle是在Handler中具体的方法执行完成但是没有交给视图解析器之前执行afterCompletion在视图解析器完成了视图解析之后执行的。 拦截器是拦截器的方法被DispatcherServlet代理调用的方法如果请求的不是Handler拦截器是不会拦截的。index.html由于是由tomcat默认的servlet进行返回的不会执行DispatcherServlet中的doDispatch那么拦截器无法进行拦截。
2.10.2 Interceptor和Filter的区别 Filter是Java Web的规范拦截的是请求任何JavaWeb项目都可以有Filter,但是Interceptor是SpringMVC提供的一套规范HandlerInterceptor只适用SpringMVC自身并且只能对DispatherServlet处理器的请求生效拦截的方法。从范围上说任何JavaWeb项目都有Filter,但是未必有Interceptor。
1、filter可以应用于任何的javaweb项目;inteceptor应用于springmvc框架
2、Filter可以过滤所有请求资源(不限于html、css、js、images等);Interceptor只能拦截所有的controller方法
3、Filter过滤路径时没有排除选项;Interceptor可以排除拦截路径
2.11 异常处理器
在spring中相对完善的异常处理器机制spring可以自己定义处理异常的规则这种处理异常规则的程序就被称之为异常处理器。其实异常处理器就是对controller的增强因为异常是向上抛controller调用serviceservice调用mappercontroller属于最上层所以最终异常都会汇集到controller。因此spring提供了ControllerAdvice注解,表示对controller增强类。并且还提供了ExceptionHandler这个注解当发生异常时该注解修饰的方法就会执行。
在实际开发中异常主要分为两类 系统异常JDK中定义的异常 业务异常开发者自己定义的异常
一般是将系统异常转化为业务异常开发者只处理业务异常。使用try…catch…将代码包裹起来在catch中抛出自定义的异常,这种方案就是将系统异常转化为业务异常。因为很多数据操作事务需要异常进行数据回滚。
package com.bjpowernode.handler;import com.bjpowernode.exception.BussiException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;/*** Description: 全局异常处理器*/
ControllerAdvice
public class GlobalExceptionHandler {/*** 具体的异常处理方法* param exception*/ExceptionHandlerpublic void doException(Exception exception){//exception FileNotFound indexOutof xxxx//判断 异常类型是不是自定义异常if (exception instanceof BussiException){BussiException ex (BussiException) exception;Integer code ex.getCode();//获取异常码String msg ex.getMsg();//获取异常消息System.out.println(code :msg);//Result 转化为JSON字符串 将JSON字符串返回给客户端}}
}package com.bjpowernode.exception;/*** Description: 自定义异常*/
public class BussiException extends RuntimeException {private Integer code;//异常码private String msg;//异常消息public BussiException(){}public BussiException(Integer code,String msg){super(msg);this.code code;this.msg msg;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg msg;}
}package com.bjpowernode.controller;import com.bjpowernode.exception.BussiException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller
RequestMapping(/test)
public class TestController {RequestMapping(/test.do)public String test(){//数据校验 可能发生的情况 很多种int m 0;try {System.out.println(100/m);}catch (Exception e){e.printStackTrace();//打印异常//自己抛出了异常throw new BussiException(1001,被除数不能为0);}return /success.html;}
}
2.12 springmvc中数据校验
springmvc中的数据校验时通过hibernate-validator实现对实体类中的字符串有效。
1、引入hibernate-validator依赖
2、在实体类中的字符串(正则表达式)属性上添加相关注解
3、可以用hibernate-validor提供的特有注解对Long、Integer、Float做校验
4、在被校验的实体类前添加Valid注解
5、当实体类中的数据格式发生错误时错误信息被封装到了BindResult对象中去,BindResult必须和实体类紧紧挨在一起
2.13 Restful风格
Restful风格适合参数少、参数不敏感的请求地址。使用了restful风格的请求地址就不能使用.do的方式请求
Resustful风格 请求地址问题 请求方式问题
http://localhost:8080/getBooksByFenye.do?pageNum1pageSize5
http://localhost:8080/getBooksByFenye/1/5
2.13.1 Http协议设计的初衷 HTTP协议在设计时期望使用一个URL表示一个资源。然后根据不同的动作GET、POST、PUT、DELETE等等表示对一个资源的各种操作。
如
获取这个资源就使用GET, GetMapping(“/”)
修改这个资源PUT, PutMapping()
删除这个资源用DELETEDeleteMapping()
创建这个资源使用POST。 PostMapping()
但是在实际使用中多个URL表示一个资源例如新增用户 addUser.do,修改用户:updateUser.do,删除用户deleteUser.do,查询一个用户getUser.do。这时候出现一个资源存在多个URL。在一定程度声违背了HTTP协议的设计初衷并且命名也是个问题。
2.13.2 Restful设计思想 使用一个URL表示一种资源 客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作GET用来获取资源POST用来新建资源也可以用于更新资源PUT用来更新资源DELETE用来删除资源 通过操作资源的表现形式来操作资源
2.13.3 在SpringMVC中使用Restful SpringMVC也支持Restful风格但是目前存在一些问题。主要不是很好支持PUT请求没有办法获取到PUT请求的数据。
2.13.3.1 将DispatherServlet的映射地址改为 由于将DispatherServlet的映射路径改为了/则所有的请求都由DispatherServlet处理静态的资源文件不在处理器映射器中会出现404。并拦截器拦截DispatherServlet中调用Handler中的方法改为/则所有的请求都会被拦截。
则需要在SpringMVC的核心配置文件中新增启用默认的Servlet的处理器。
!-- 启用默认Servlet --
mvc:default-servlet-handler/并且注意配置拦截器时将静态资源不进行拦截要排除
mvc:exclude-mapping path/resouces/**/2.13.3.2 配置处理PUT请求的拦截器
!-- 处理put请求的拦截器 --
filterfilter-namerestful/filter-namefilter-classorg.springframework.web.filter.HttpPutFormContentFilter/filter-class
/filter
filter-mappingfilter-namerestful/filter-nameservlet-namespringmvc/servlet-name
/filter-mapping2.13.3.3 处理器代码
package com.bjpowernode.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;RestController
RequestMapping(user)
public class UserController {// RequestMapping(method RequestMethod.GET)
// //GetMapping
// public Object get(Integer id){
// System.out.println(get请求);
// MapString,Object data new HashMap();
// data.put(code,200);
// data.put(msg,get请求);
// return data;
// }GetMapping({id}/{name}) //后台的获取方式 使用 {} 进行包裹 并且 在方法参数中 使用PathVariable// 这种将参数拼接在URL上的方式 只支持 GET 请求和 DELETE请求public Object get1(PathVariable(id) Integer id,PathVariable(name) String name){System.out.println(get请求);System.out.println(id);System.out.println(name);MapString,Object data new HashMap();data.put(code,200);data.put(msg,get请求);return data;}//RequestMapping(method RequestMethod.PUT)PutMappingpublic Object put(Integer id){System.out.println(PUT请求);MapString,Object data new HashMap();data.put(code,200);data.put(msg,PUT请求);return data;}RequestMapping(method RequestMethod.POST)PostMappingpublic Object post(Integer id){System.out.println(post请求);MapString,Object data new HashMap();data.put(code,200);data.put(msg,post请求);return data;}//RequestMapping(method RequestMethod.DELETE)DeleteMappingpublic Object delete(Integer id){System.out.println(delete请求);MapString,Object data new HashMap();data.put(code,200);data.put(msg,delete请求);return data;}
}2.13.3.4 页面代码
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
bodybutton idbtn1get/buttonbutton idbtn2put/buttonbutton idbtn3delete/buttonbutton idbtn4post/buttonbutton idbtn5get-1111/buttonscript srcresources/jquery.js/scriptscript$(#btn1).click(function () {$.get(user,{id:1001},function (rs) {console.log(rs);})});$(#btn2).click(function () {$.ajax({url:user,type:PUT,data:{id:1001},success:function (rs) {console.log(rs);}})});$(#btn3).click(function () {$.ajax({url:user,type:DELETE,data:{id:1001},success:function (rs) {console.log(rs);}})});$(#btn4).click(function () {$.post(user,{id:1001},function (rs) {console.log(rs);})});$(#btn5).click(function () {//将参数 拼接在URL上面$.get(user/11111/lucy,function (rs) {console.log(rs);})});/script
/body
/html