SpringMVC的简单入门
-
概念 : Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
-
快速入门
-
创建项目导入坐标
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <spring-version>5.0.10.RELEASE</spring-version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> </dependencies>
-
创建springMVC的配置类
<?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="com.junyang.springmvc.controller"></context:component-scan> <!--开启SpringMVC框架注解的支持--> <mvc:annotation-driven/> <!--配置视图解析器--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
-
配置web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--配置前端控制器--> <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> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
编写测试类
@Controller public class HelloSpringMvc { @RequestMapping("/hello") public String hello(){ System.out.println("来到啦hello这里..."); return "success"; } }
-
编写页面
>> index.jsp页面内容 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>springMVC入门</title> </head> <body> <h2>入门案例</h2> <a href="/springmvc/hello">入门案例才能点的连接</a> </body> </html>
>>success.jsp内容 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>入门成功</title> </head> <body> <h2>springMVC入门成功!</h2> </body> </html>
-
成功的画面
-
-
请求参数的绑定
-
普通类型
请求路径 : http://localhost/springmvc/user/login?username=haha @Controller @RequestMapping("/user") public class User { @RequestMapping("/login") public String login(String username){ System.out.println(username); return "success"; } } 打印结果如下:
-
JavaBean : 参数列表 – User user
-
QueryVo : 参数列表 – Account account 提交表单name的值需要使用user.username user.age
-
复杂类型的绑定 :
- list : list[0].username, list[0].age
- map : map[‘one’].username , map[‘one’].age
-
-
解决中文乱码问题: 在web.xml中添加如下配置
<filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf8</param-value> </init-param> </filter>
-
自定义类型转换
-
编写转换类
public class ConverStringToDate implements Converter<String,Date> { @Override public Date convert(String s) { if(s==null||!(s.length()>0)){ throw new RuntimeException("传入的数据有问题"); } DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { return df.parse(s); } catch (ParseException e) { throw new RuntimeException("类型转换出现错误"); } } }
-
注册转换组件
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean id="converStringToDate" class="com.junyang.springmvc.controller.ConverStringToDate"></bean> </set> </property> </bean> <!--开启SpringMVC框架注解的支持--> <mvc:annotation-driven conversion-service="conversionService"/>
-
-
获取request和response 直接在参数列表中添加即可
方法名(HttpServletRequest request, HttpServletResponse response)
SpringMVC的常用注解
- RequestParam注解
- 作用:把请求中的指定名称的参数传递给控制器中的形参赋值
- 属性
- value:请求参数中的名称
- required:请求参数中是否必须提供此参数,默认值是true,必须提供
- RequestBody注解
- 作用:用于获取请求体的内容(注意:get方法不可以)
- 属性
- required:是否必须有请求体,默认值是true
- PathVariable注解
- 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
- 属性
- value:指定url中的占位符名称
- Restful风格的URL
- 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
- restful风格的URL优点
- 结构清晰
- 符合标准
- 易于理解
- 扩展方便
- RequestHeader注解
- 作用:获取指定请求头的值
- 属性
- value:请求头的名称
- CookieValue注解
- 作用:用于获取指定cookie的名称的值
- 属性
- value:cookie的名称
- ModelAttribute注解
- 作用
- 出现在方法上:表示当前方法会在控制器方法执行前线执行。
- 出现在参数上:获取指定的数据给参数赋值。
- 应用场景
- 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
- 作用
- SessionAttributes注解
- 作用:用于多次执行控制器方法间的参数共享
- 属性
- value:指定存入属性的名称
SpringMVC的返回值类型
- 返回字符串
-
Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
@Controller @RequestMapping("/user") public class UserController { /** * 请求参数的绑定 */ @RequestMapping(value="/initUpdate") public String initUpdate(Model model) { // 模拟从数据库中查询的数据 User user = new User(); user.setUsername("张三"); user.setPassword("123"); user.setMoney(100d); user.setBirthday(new Date()); model.addAttribute("user", user); return "update"; } } <h3>修改用户</h3> ${ requestScope } <form action="user/update" method="post"> 姓名:<input type="text" name="username" value="${ user.username }"><br> 密码:<input type="text" name="password" value="${ user.password }"><br> 金额:<input type="text" name="money" value="${ user.money }"><br> <input type="submit" value="提交"> </form>
-
- void:
- 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
- 默认会跳转到@RequestMapping(value="/initUpdate") initUpdate的页面。
- 可以使用请求转发或者重定向跳转到指定的页面
@RequestMapping(value="/initAdd") public void initAdd(HttpServletRequest request,HttpServletResponse response) throws Exception { System.out.println("请求转发或者重定向"); // 请求转发 // request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request, response); // 重定向 // response.sendRedirect(request.getContextPath()+"/add2.jsp"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 直接响应数据 response.getWriter().print("你好"); return; }
- 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
- 返回值是ModelAndView对象
-
ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
/** * 返回ModelAndView对象 * 可以传入视图的名称(即跳转的页面),还可以传入对象。 * @return * @throws Exception */ @RequestMapping(value="/findAll") public ModelAndView findAll() throws Exception { ModelAndView mv = new ModelAndView(); // 跳转到list.jsp的页面 mv.setViewName("list"); // 模拟从数据库中查询所有的用户信息 List<User> users = new ArrayList<>(); User user1 = new User(); user1.setUsername("张三"); user1.setPassword("123"); User user2 = new User(); user2.setUsername("赵四"); user2.setPassword("456"); 2. SpringMVC框架提供的转发和重定向 1. forward请求转发 1. controller方法返回String类型,想进行请求转发也可以编写成 2. redirect重定向 users.add(user1); users.add(user2); // 添加对象 mv.addObject("users", users); return mv; } <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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>Insert title here</title> </head> <body> <h3>查询所有的数据</h3> <c:forEach items="${ users }" var="user"> ${ user.username } </c:forEach> </body> </html>
-
SpringMVC框架的请求转发和重定向
- forward请求转发
-
- controller方法返回String类型,想进行请求转发也可以编写成
/** * 使用forward关键字进行请求转发 * "forward:转发的JSP路径",不走视图解析器了,所以需要编写完整的路径 * @return * @throws Exception */ @RequestMapping("/delete") public String delete() throws Exception { System.out.println("delete方法执行了..."); // return "forward:/WEB-INF/pages/success.jsp"; return "forward:/user/findAll"; }
-
- redirect重定向
-
controller方法返回String类型,想进行重定向也可以编写成
/** * 重定向 * @return * @throws Exception */ @RequestMapping("/count") public String count() throws Exception { System.out.println("count方法执行了..."); return "redirect:/add.jsp"; // return "redirect:/user/findAll"; }
-
ResponseBody响应json数据
-
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而
不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置.-
mvc:resources标签配置不过滤
- location元素表示webapp目录下的包下的所有文件
- mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
<!-- 设置静态资源不过滤 --> <mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 --> <mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 --> <mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
-
-
使用@RequestBody获取请求体数据
-
使用@RequestBody注解把json的字符串转换成JavaBean的对象
-
使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应
-
json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
SpringMVC实现文件上传
-
创建工程,导入jar包
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
-
编写文件上传的JSP页面
<h3>文件上传</h3> <form action="user/fileupload" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="upload"/><br/> <input type="submit" value="上传文件"/> </form>
-
编写测试代码
/** * SpringMVC方式的文件上传 * * @param request * @return * @throws Exception */ @RequestMapping(value="/fileupload2") public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception { System.out.println("SpringMVC方式的文件上传..."); // 先获取到要上传的文件目录 String path = request.getSession().getServletContext().getRealPath("/uploads"); // 创建File对象,一会向该路径下上传文件 File file = new File(path); // 判断路径是否存在,如果不存在,创建该路径 if(!file.exists()) { file.mkdirs(); } // 获取到上传文件的名称 String filename = upload.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); // 把文件的名称唯一化 filename = uuid+"_"+filename; // 上传文件 upload.transferTo(new File(file,filename)); return "success"; }
-
配置文件解析对象
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> </bean>
-
SpringMVC跨服务器方式文件上传
-
搭建图片服务器
-
根据文档配置tomcat_upload服务器,现在是2个服务器
-
导入开发需要的jar包
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.18.1</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.18.1</version> </dependency>
-
编写文件上传的JSP页面
<h3>跨服务器的文件上传</h3> <form action="user/fileupload3" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="upload"/><br/> <input type="submit" value="上传文件"/> </form>
-
编写控制器
/** * SpringMVC跨服务器方式的文件上传 * * @param request * @return * @throws Exception */ @RequestMapping(value="/fileupload3") public String fileupload3(MultipartFile upload) throws Exception { System.out.println("SpringMVC跨服务器方式的文件上传..."); // 定义图片服务器的请求路径 String path = "http://localhost:9090/day02_springmvc5_02image/uploads/"; // 获取到上传文件的名称 String filename = upload.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); // 把文件的名称唯一化 filename = uuid+"_"+filename; // 向图片服务器上传文件 // 创建客户端对象 Client client = Client.create(); // 连接图片服务器 WebResource webResource = client.resource(path+filename); // 上传文件 webResource.put(upload.getBytes()); return "success"; }
-
SpringMVC的异常处理
- 异常处理思路
- Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进
行异常的处理。
- Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进
- SpringMVC的异常处理
-
自定义异常类
public class SysException extends Exception{ private static final long serialVersionUID = 4055945147128016300L; // 异常提示信息 private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public SysException(String message) { this.message = message; } }
-
自定义异常处理器
/** * 异常处理器 * @author rt */ public class SysExceptionResolver implements HandlerExceptionResolver{ /** * 跳转到具体的错误页面的方法 */ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ex.printStackTrace(); SysException e = null; // 获取到异常对象 if(ex instanceof SysException) { e = (SysException) ex; }else { e = new SysException("请联系管理员"); } ModelAndView mv = new ModelAndView(); // 存入错误的提示信息 mv.addObject("message", e.getMessage()); // 跳转的Jsp页面 mv.setViewName("error"); return mv; } }
-
配置异常处理器
<!-- 配置异常处理器 --> <bean id="sysExceptionResolver" class="cn.junyang.exception.SysExceptionResolver"/
-