springmvc
时间:2020-01-19 18:51:47
收藏:0
阅读:99
SpringMVC
第一章
1.1 三层架构
- 表现层:web层,用来和客户端进行数据交互的,一般采用MVC的设计模式
- 业务层:处理公司具体的业务逻辑的
- 持久层:操作数据库的
1.2 MVC模型
- Model:用来进行数据封装
- View:用来展示数据给用户
- Controller:用来接收用户请求,整个流程的控制器,进行数据校验等
1.3 SpringMVC的优势
- 清晰的角色划分
- 前端控制器(DispatcherServlet)
- 控制流程的中心,有它调用其他组件处理用户的请求,解耦
- 请求到处理器映射(HandlerMapping)
- 负责根据用户请求找到Handler即处理器,SpringMVC 提供了不同的映射器实现不同的 映射方式,例如:配置文件方式,实现接口方式,注解方式等
- 处理器(Handler)
- 由DispatcherServlet把用户请求转发到Handler,由Handler对具体的用户请求进行处理
- 处理器适配器(HandlerAdapter)
- 充当接口作用
- 视图解析器(ViewResolver)
- 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名 即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户
- 视图(view)
- SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView 等。我们最常用的视图就是 jsp
- 处理器或页面控制器(Controller)
- 验证器( Validator)
- 命令对象(Command 请求参数绑定到的对象就叫命令对象)
- 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)
- 前端控制器(DispatcherServlet)
- 分工明确,容易扩展
- 可使用命令对象直接作为业务对象
- 和Spring无缝集成
- 可适配
- 可定制性
1.4 SpringMVC入门案例
通过Maven创建web工程,引入依赖
配置核心的控制器(在web.xml中配置DispatcherServlet)
<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启动时加载对象 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
编写springmvc.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="cn.itcast"/> <!-- 视图解析器对象 --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <!--配置自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itcast.utils.StringToDateConverter"/> </set> </property> </bean> <!-- 开启SpringMVC框架注解的支持 --> <mvc:annotation-driven conversion-service="conversionService"/> <!-- SpringMVC的各个组件中,处理器映射器,处理器适配器,视图解析器成为SpringMVC三大组件,配置了上面这个标签,自动加载RequestMappingHandlerMapping (处理映射器)和 RequestMappingHandlerAdapter ( 处 理 适 配 器 ) --> </beans>
编写index.jsp和HelloController控制器类
index.jsp
<body> <h3>入门案例</h3> <a href="${ pageContext.request.contextPath }/hello">入门案例</a> </body>
HelloController
@Controller public class HelloController { /** * 接收请求 * @return */ @RequestMapping(path="/hello") public String sayHello() { System.out.println("Hello SpringMVC!!"); return "success"; } }
在web-INF目录下创建pages文件夹,编写success.jsp的成功页面
<body> <h3>入门成功</h3> </body>
测试
1.5 RequestMapping注解
@Controller("accountController")
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/findAccount")
public String findAccount() {
System.out.println("查询了账户。。。。");
return "success";
}
//method属性:限定提交方式
@RequestMapping(value="/saveAccount",method=RequestMethod.POST)
public String saveAccount() {
System.out.println("保存了账户");
return "success";
}
//限定了参数,<a href="account/removeAccount?accountName=aaa&money>100">可访问
@RequestMapping(value="/removeAccount",params= {"accountName","money>100"})
public String removeAccount() {
System.out.println("删除了账户");
return "success";
}
}
<!-- jsp中的使用 -->
<body>
<!-- 第一种访问方式 -->
<a href="${pageContext.request.contextPath}/account/findAccount">
查询账户
</a>
<br/>
<!-- 第二种访问方式 -->
<a href="account/findAccount">
查询账户
</a>
</body>
1.6 请求参数的绑定
<a href="account/findAccount?accountId=10">查询账户</a>
//会自动将请求参数accountId=10作为方法的参数传入
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
System.out.println("查询了账户。。。。"+accountId);
return "success";
}
- 控制器方法中的形参支持的数据类型
- 基本类型(加String类型)
- 要求请求参数名称和控制器中方法的形参名称严格一致
- POJO类型参数(实体类,相关联的实体类)
- 要求表单中的参数名称和POJO类的属性名称保持一致,并且控制器方法的参数类型是POJO类型
- 数组和集合类型参数
- 基本类型(加String类型)
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
private Address address; //getters and setters
}
public class Address implements Serializable {
private String provinceName;
private String cityName; //getters and setters
}
public class User implements Serializable {
private String username;
private String password;
private Integer age;
private List<Account> accounts;
private Map<String,Account> accountMap; //getters and setters
}
//在controller中
@RequestMapping("/saveAccount")
public String saveAccount(Account account) {
System.out.println("保存了账户。。。。"+account);
return "success";
}
@RequestMapping("/updateAccount")
public String updateAccount(User user) {
System.out.println("更新了账户。。。。"+user);
return "success";
}
<form action="account/saveAccount" method="post">
账户名称:<input type="text" name="name" ><br/>
账户金额:<input type="text" name="money" ><br/>
账户省份:<input type="text" name="address.provinceName" ><br/>
账户城市:<input type="text" name="address.cityName" ><br/>
<input type="submit" value=" 保存 ">
</form>
<form action="account/updateAccount" method="post">
用户名称:<input type="text" name="username" ><br/>
用户密码:<input type="password" name="password" ><br/>
用户年龄:<input type="text" name="age" ><br/>
账户 1 名称:<input type="text" name="accounts[0].name" ><br/>
账户 1 金额:<input type="text" name="accounts[0].money" ><br/>
账户 2 名称:<input type="text" name="accounts[1].name" ><br/>
账户 2 金额:<input type="text" name="accounts[1].money" ><br/>
账户 3 名称:<input type="text" name="accountMap['one'].name" ><br/>
账户 3 金额:<input type="text" name="accountMap['one'].money" ><br/>
账户 4 名称:<input type="text" name="accountMap['two'].name" ><br/>
账户 4 金额:<input type="text" name="accountMap['two'].money" ><br/>
<input type="submit" value=" 保存 ">
</form>
1.7 请求参数乱码问题
post 请求方式: 在 web.xml 中配置一个过滤器
<!-- 配置 springMVC 编码过滤器 -->
<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>
<!-- 启动过滤器 -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 过滤所有请求 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在 springmvc 的配置文件中可以配置,静态资源不过滤:
<!-- location 表示路径,mapping 表示文件,**表示该目录下的文件以及子目录的文件 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>
get 请求方式:
tomacat 对 GET和 POST 请求处理方式是不同的,GET请求的编码问题,要改 tomcat 的 server.xml 配置文件,如下:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
改为:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
如果遇到 ajax 请求仍然乱码,请把: useBodyEncodingForURI="true"改为 URIEncoding="UTF-8" 即可。
1.8 自定义类型转换器
- 使用情况
<a href="account/deleteAccount?date=2018-01-01">根据日期删除账户</a>
@RequestMapping("/deleteAccount")
public String deleteAccount(String date) {
System.out.println("删除了账户。。。。"+date);
return "success";
}//此时可能会报错,因为格式不匹配,自动转换要求不匹配
- 使用步骤
第一步:定义一个类,实现 Converter 接口,该接口有两个泛型。
public interface Converter<S, T> {//S:表示接受的类型,T:表示目标类型
/**
* 实现类型转换的方法
*/
@Nullable T convert(S source);
}
public class StringToDateConverter implements Converter<String, Date> {
/**
* 用于把 String 类型转成日期类型 */
@Override public Date convert(String source) {
DateFormat format = null;
try {
if(StringUtils.isEmpty(source)) {
throw new NullPointerException("请输入要转换的日期");
}
format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(source);
return date;
} catch (Exception e) {
throw new RuntimeException("输入日期有误");
}
}
}
第二步:在 spring配置文件中配置类型转换器
<!-- 配置类型转换器工厂 -->
<bean id="converterService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 给工厂注入一个新的类型转换器 -->
<property name="converters">
<array>
<!-- 配置自定义类型转换器,将自定义的转换器也加入其中 -->
<bean class="com.itheima.web.converter.StringToDateConverter"></bean>
</array>
</property>
</bean>
第三步:在 annotation-driven标签中引用配置的类型转换服务
<!-- 引用自定义类型转换器 -->
<mvc:annotation-driven
conversion-service="converterService"></mvc:annotation-driven>
1.9 使用ServletAPI对象作为方法参数
<a href="account/testServletAPI">测试访问 ServletAPI</a>
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,
HttpServletResponse response,
HttpSession session) {
System.out.println(request); System.out.println(response);
System.out.println(session);
return "success";
}
1.10 常用注解
- RequestParam:把求情中指定名称的参数给控制器中的形参赋值
- 属性
- value:请求参数的名称
- required:请求参数中是否必须提供此参数。默认值:true,表示必须提供,不提供则报错
- RequestBody:用于获取请求体内容。直接使用得到是 key=value&key=value...结构的数据。 get 请求方式不适用。
- 属性
- required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值 为 false,get 请求得到是 null。
- PathVaribale :用于绑定 url 中的占位符。
- value:用于指定 url 中占位符名称
- required:是否必须提供占位符。
- RequestHeader :用于获取请求消息头
- 属性
- value:提供消息头名称
- required:是否必须有此消息头
- CookieValue :用于把指定 cookie 名称的值传入控制器方法参数。
- value:指定 cookie 的名称。
- required:是否必须有此 cookie
<a href="springmvc/useRequestParam?name=test">requestParam 注解</a>
post 请求 jsp代码:
<!-- request body 注解 -->
<form action="springmvc/useRequestBody" method="post">
用户名称:<input type="text" name="username" ><br/>
用户密码:<input type="password" name="password" ><br/>
用户年龄:<input type="text" name="age" ><br/>
<input type="submit" value=" 保存 ">
</form>
get 请求 jsp代码:
<a href="springmvc/useRequestBody?body=test">requestBody 注解 get 请求</a>
<a href="springmvc/usePathVariable/100">pathVariable 注解</a>
<a href="springmvc/useRequestHeader">获取请求消息头</a>
<a href="springmvc/useCookieValue">绑定 cookie 的值</a>
@RequestMapping("/useRequestParam")
public String useRequestParam(@RequestParam("name")String username,
@RequestParam(value="age",required=false)
Integer age){
System.out.println(username+","+age);
return "success";
}
@RequestMapping("/useRequestBody")
public String useRequestBody(@RequestBody(required=false) String body){
System.out.println(body);
return "success";
}
@RequestMapping("/usePathVariable/{id}")
public String usePathVariable(@PathVariable("id") Integer id){
System.out.println(id); return "success";
}
@RequestMapping("/useRequestHeader")
public String useRequestHeader(
@RequestHeader(value="Accept-Language", required=false)String requestHeader){
System.out.println(requestHeader);
return "success";
}
@RequestMapping("/useCookieValue")
public String useCookieValue(
@CookieValue(value="JSESSIONID",required=false) String cookieValue){
System.out.println(cookieValue);
return "success";
}
- ModelAttribute :若一个方法被ModelAttribute修饰后,进行处理器请求方法之前它会被执行
<form action="springmvc/updateUser" method="post">
用户名称:<input type="text" name="username" ><br/> //输入cgx
用户年龄:<input type="text" name="age" ><br/> //输入23
<input type="submit" value=" 保存 ">
</form>
@ModelAttribute
public User showModel(User user) {
User abc = findUserByName(username);
System.out.println("执行了 showModel 方法"+abc);
return abc;
}//username=cgx,password=123456,age=19,会将对象传递给下面的方法参数中
方式一:带返回值
@RequestMapping("/updateUser")
public String testModelAttribute(User user) { //会根据表单的值修改user对象内容。
System.out.println("控制器中处理请求的方法:修改用户:"+user);
return "success";
}//username=cgx,password=123456,age=23
private User findUserByName(String username) {
User user = new User();
user.setUsername(username);
user.setAge(19);
user.setPassword("123456");
return user;
}
方式二:不带返回值
@ModelAttribute
public void showModel(String username,Map<String,User> map) {
//模拟去数据库查询
User user = findUserByName(username);
System.out.println("执行了 showModel 方法"+user);
map.put("abc",user);
}
@RequestMapping("/updateUser")
public String testModelAttribute(@ModelAttribute("abc")User user) {
System.out.println("控制器中处理请求的方法:修改用户:"+user);
return "success";
}
- SessionAttribute:用于多次执行控制器方法间的参数共享
<!-- SessionAttribute 注解的使用 -->
<a href="springmvc/testPut">存入 SessionAttribute</a> <hr/>
<a href="springmvc/testGet">取出 SessionAttribute</a> <hr/>
<a href="springmvc/testClean">清除 SessionAttribute</a>
@Controller("sessionAttributeController")
@RequestMapping("/springmvc")
@SessionAttributes(value ={"username","password"},types={Integer.class})
public class SessionAttributeController {
/**
* 把数据存入 SessionAttribute
* @param model
* @return
* Model 是 spring 提供的一个接口,该接口有一个实现类 ExtendedModelMap
* 该类继承了 ModelMap,而 ModelMap 就是 LinkedHashMap 子类
*/
@RequestMapping("/testPut") //存入数据
public String testPut(Model model){
model.addAttribute("username", "泰斯特");
model.addAttribute("password","123456");
model.addAttribute("age", 31);
//跳转之前将数据保存到 username、password 和 age 中,因为注解@SessionAttribute 中有 这几个参数
return "success";
}
@RequestMapping("/testGet") //获取数据
public String testGet(ModelMap model){
System.out.println(model.get("username")+";"
+model.get("password")+";"+model.get("a ge"));
return "success";
}
@RequestMapping("/testClean") //清空数据
public String complete(SessionStatus sessionStatus){
sessionStatus.setComplete();
return "success";
}
}
第二章
2.1 返回值
//方式一:空返回值,通过resquest和response设置
@RequestMapping("/testReturnVoid")
public void testReturnVoid(HttpServletRequest request,HttpServletResponse response) throws Exception {
//1、使用 request 转向页面,如下:
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,
response);
//2、也可以通过 response 页面重定向:
response.sendRedirect("testRetrunString")
//3、也可以通过 response 指定响应结果,例如响应 json 数据:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json 串");
}
//方式二:ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值
@RequestMapping("/testReturnModelAndView")
public ModelAndView testReturnModelAndView() {
ModelAndView mv = new ModelAndView();
mv.addObject("username", "张三"); //将属性添加到request域中
mv.setViewName("success"); //设置转发视图页面
}
//获取
<body>
执行成功!
${requestScope.username}
</body>
2.2 转发和重定向
//转发
@RequestMapping("/testForward")
public String testForward() {
System.out.println("AccountController 的 testForward 方法执行了。。。。");
return "forward:/WEB-INF/pages/success.jsp";
}
//如果用了 formward:则路径必须写成实际视图 url,不能写逻辑视图
//它相当于“request.getRequestDispatcher("url").forward(request,response)”。
//重定向
@RequestMapping("/testRedirect") public String testRedirect() {
System.out.println("AccountController 的 testRedirect 方法执行了。。。。");
return "redirect:testReturnModelAndView";
}
//它相当于“response.sendRedirect(url)”。需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不 能写在 WEB-INF 目录中,否则无法找到
2.3 ResponseBody响应json数据
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#testJson").click(function(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/testResponseJson",
contentType:"application/json;charset=utf-8",
data:'{"id":1,"name":"test","money":999.0}',
dataType:"json",
success:function(data){
alert(data);
}
});
});
})
</script>
<!-- 测试异步请求 -->
<input type="button" value=" 测试 ajax请求 json和响应 json" id="testJson"/>
@Controller("jsonController")
public class JsonController {
/**
* 测试响应 json 数据
*/
@RequestMapping("/testResponseJson")
public @ResponseBody Account testResponseJson(@RequestBody Account account) {
System.out.println("异步请求:"+account);
return account;
}
}
2.4 SpringMVC实现文件上传
- 前提
A form 表单的 enctype 取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
B method 属性取值必须是 Post
C 提供一个文件选择域<input type=”file” />
因为
当 form 表单的 enctype 取值不是默认值后,request.getParameter()将失效。
enctype=”application/x-www-form-urlencoded”时,form 表单的正文内容是:
key=value&key=value&key=value
当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:
每一部分都是 MIME 类型描述的正文
- 导入相关依赖jar包(io,fileupload相关的jar包)
- 编写jsp页面
- 编写控制器
- 配置文件解析器
<form action="/fileUpload" method="post" enctype="multipart/form-data">
名称:<input type="text" name="picname"/><br/>
图片:<input type="file" name="uploadFile"/><br/>
<input type="submit" value=" 上传 "/>
</form>
@Controller("fileUploadController")
public class FileUploadController {
/**
* 文件上传
*/
@RequestMapping("/fileUpload")
public String testResponseJson(String picname,MultipartFile uploadFile,HttpServletRequest request) throws Exception{
//定义文件名
String fileName = "";
//1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
//2.截取文件扩展名
String extendName =
uploadFileName.substring(uploadFileName.lastIndexOf(".")+1, uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.判断是否输入了文件名
if(!StringUtils.isEmpty(picname)) {
fileName = uuid+"_"+picname+"."+extendName;
}else {
fileName = uuid+"_"+uploadFileName;
}
System.out.println(fileName);
//2.获取文件路径
ServletContext context = request.getServletContext();
String basePath = context.getRealPath("/uploads");
//3.解决同一文件夹中文件过多问题
String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//4.判断路径是否存在
File file = new File(basePath+"/"+datePath);
if(!file.exists()) {
file.mkdirs();
}
//5.使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
uploadFile.transferTo(new File(file,fileName));
return "success";
}
}
<!-- 配置文件上传解析器 -->
<!-- id 的值是固定的-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为 5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
注意: 文件上传的解析器 id是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他 字段也将无法绑定)
2.5 springmvc跨服务器的文件上传
- 不同的服务器
- 应用服务器:负责部署我们的应用
- 数据库服务器:运行我们的数据库
- 缓存和消息服务器:负责处理大并发访问的缓存和消息
- 文件服务器:负责存储用户上传文件的服务器
- 步骤
- 准备两个 tomcat 服务器,并创建一个用于存放图片的 web 工程
- 拷贝jar包(添加依赖)
- 编写控制器实现上传图片
- 编写jsp页面
- 配置解析器
@Controller("fileUploadController2")
public class FileUploadController2 {
public static final String FILESERVERURL =
"http://localhost:9090/day06_spring_image/uploads/";
/**
* 文件上传,保存文件到不同服务器
*/
@RequestMapping("/fileUpload2")
public String testResponseJson(String picname,MultipartFile uploadFile) throws Exception{
//定义文件名
String fileName = "";
//1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
//2.截取文件扩展名
String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1,
uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.判断是否输入了文件名
if(!StringUtils.isEmpty(picname)) {
fileName = uuid+"_"+picname+"."+extendName;
}else {
fileName = uuid+"_"+uploadFileName;
}
System.out.println(fileName);
//5.创建 sun 公司提供的 jersey 包中的 Client 对象
Client client = Client.create();
//6.指定上传文件的地址,该地址是 web 路径
WebResource resource = client.resource(FILESERVERURL+fileName);
//7.实现上传
String result = resource.put(String.class,uploadFile.getBytes());
System.out.println(result);
return "success";
}
}
<form action="fileUpload2" method="post" enctype="multipart/form-data">
名称:<input type="text" name="picname"/><br/>
图片:<input type="file" name="uploadFile"/><br/>
<input type="submit" value="上传"/>
</form>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为 5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
3.6 SpringMVC中的异常处理
- 编写异常类和错误页面
- 自定义异常处理器
- 配置异常处理器
public class CustomException extends Exception {
private String message;
public CustomException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>
执行失败
</title>
</head>
<body>
执行失败!
${message }
</body>
</html>
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ex.printStackTrace();
CustomException customException = null;
//如果抛出的是系统自定义异常则直接转换
if(ex instanceof CustomException){
customException = (CustomException)ex;
}else{
//如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
customException = new CustomException("系统错误,请与系统管理 员联系!");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", customException.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
<bean id="handlerExceptionResolver"
class="com.itheima.exception.CustomExceptionResolver"/>
3.7 SpringMVC中的拦截器
- 编写一个普通类实现HandlerInterceptor接口
- 配置拦截器
public class HandlerInterceptorDemo1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
System.out.println("preHandle 拦截器拦截了");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 方法执行了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
System.out.println("afterCompletion 方法执行了");
}
}
<!-- 配置拦截器的作用范围 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" /><!-- 用于指定对拦截的 url -->
<mvc:exclude-mapping path=""/><!-- 用于指定排除的 url-->
<bean id="handlerInterceptorDemo1"
class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>
</mvc:interceptor>
</mvc:interceptors>
第三章
3.1 SSM整合
- 创建数据库和表结构
- 创建Maven工程
- 导入坐标引入依赖
- 编写实体类
- 编写业务层接口
- 编写持久层接口
- 保证Spring框架在web工程上独立运行
- 编写spring配置文件并导入约束
- 使用注解配置业务层和持久层
- 测试spring能否独立运行
- 保证SpringMVC在web工程独立运行
- 在web.xml中配置核心控制器(DispatcherServlet)
- 编写SpringMVC的配置文件
- 编写Controller和jsp页面
- 整合Spring和SpringMVC
- 配置监听器实现启动服务创建容器
- 保证MyBatis框架在web工程中独立运行
- 编写AccountDao映射配置文件
- 编写SqlMapConfig配置文件
- 测试运行结果
- 整合Spring和Mybatis
- Spring接管MyBatis的Session工厂
- 配置自动扫描所有Mapper接口和文件
- 配置Spring的事物
- 测试整合结果
- 测试SSM整合结果
- 编写测试jsp
- 修改控制器的方法
- 测试运行结果
create database ssm;
create table account(
id int primary key auto_increment,
name varchar(100),
money double(7,2),
);
@Service("accountService")
public class AccountServiceImpl implements AccountService{
@Autowired
private AccountDao accountDao;
public List<Account> findAll() {
System.out.println("业务层:查询所有账户...");
return accountDao.findAll();
}
public void saveAccount(Account account) {
System.out.println("业务层:保存帐户...");
accountDao.saveAccount(account);
}
}
@Repository
public interface AccountDao {
// 查询所有账户
@Select("select * from account")
public List<Account> findAll();
// 保存帐户信息
@Insert("insert into account (name,money) values (#{name},#{money})")
public void saveAccount(Account account);
}
//测试spring
public class Test01Spring {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);
as.findAllAccount();
}
}
//配置web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置Spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--设置配置文件的路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name/>
<param-value/>
</context-param>
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载springmvc.xml配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--启动服务器,创建该servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--解决中文乱码的过滤器-->
<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>
</web-app>
//配置SpringMVC的配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描,只扫描Controller注解-->
<context:component-scan base-package="cn.itcast">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!--配置的视图解析器对象-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--过滤静态资源-->
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<!--开启SpringMVC注解的支持-->
<mvc:annotation-driven/>
</beans>
//编写jsp页面
<body>
<a href="account/findAll">测试查询</a>
<h3>测试包</h3>
<form action="account/save" method="post">
姓名:<input type="text" name="name" /><br/>
金额:<input type="text" name="money" /><br/>
<input type="submit" value="保存"/><br/>
</form>
</body>
//控制器
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/findAll")
public String findAll(Model model){
System.out.println("表现层:查询所有账户...");
// 调用service的方法
List<Account> list = accountService.findAll();
model.addAttribute("list",list);
return "list";
}
/**
* 保存
* @return
*/
@RequestMapping("/save")
public void save(Account account, HttpServletRequest request, HttpServletResponse response) throws IOException {
accountService.saveAccount(account);
response.sendRedirect(request.getContextPath()+"/account/findAll");
return;
}
}
原文:https://www.cnblogs.com/liujiashun/p/12215154.html
评论(0)