赞
踩
MVC : 是一种用于设计创建web应用表现层的模式,主要作用是将视图展示和业务控制代码分离开来
MVC 使用了三种角色来分别处理不同的功能:
Model(模型):数据模型(封装对象)
View(视图):负责数据的展示(html,jsp)
Controller(控制器):负责调度,用于程序业务逻辑处理
MVC架构跟三层架构的关系:
MVC架构在三层架构中的位置图示:
SpringMVC介绍
SpringMVC是Spring产品对MVC模式的一种具体实现,属于轻量级的WEB框架。它通过一套简单的注解,让一个普通的 Java 类成为控制器,而无须实现任何接口。同时他还支持RestFul风格的编程风格。
SpringMVC的功能就是封装了原来Servlet中的共有功能,例如请求参数解析处理、请求结果封装返回等。
SpringMVC中和Spring一样,也存在容器的概念(支持spring的注解)。
SpringMVC依赖
<dependencies> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.6.RELEASE</version> </dependency> <!--前端控制器 servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 包扫描 --> <context:component-scan base-package="cn.test"></context:component-scan> <!-- 配置springmvc的注解驱动。内置了处理器映射器和处理器适配器 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 视图解析器 --> <!-- 配置返回页面的前缀和后缀。当需要返回一个视图的时候,只需写视图的名称,视图解析器会自动在该名称上拼接前后缀。 前缀 + 控制器返回值 + 后缀 /WEB-INF/jsps/ + 控制器返回值 + .jsp --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsps/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
web.xml 中配置前端控制器
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 配置SpringMVC的前端控制器 DispatcherServlet --> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--自动加载Springmvc的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <!-- 处理所有请求,不处理.jsp为后缀的请求 --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Controller:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 控制器:需要交给容器管理 * 方法:接受请求,调用service,完成响应和页面跳转 */ @Controller public class HelloController { /** * 控制器方法: * 接受请求,调用service,完成响应和页面跳转 * 1、返回值String (跳转的页面路径) * 2、需要在方法上通过注解@RequestMapping配置进入此方法的url * */ @RequestMapping(value="/hello") public String hello() { System.out.println("hello heima23"); return "success"; // /WEB-INF/jsps/ + 控制器返回值 + .jsp } }
http://localhost/hello
前端控制器(DispatcherServlet):
SpringMVC的核心组件(DispathcherServlet),协调所有组件的运行
处理器映射器(HandlerMapping):
负责根据URL请求找到对应的的处理器(Controller中的方法)
处理器适配器(HandlerAdapter):
统一适配器接口,对处理器进行了一个封装,可以统一调用。真正的去调用处理方法(执行Controller中的方法)
视图解析器 (ViewReslover):
根据逻辑视图匹配到真正的物理视图
物理视图:jsp页面的完整路径
@RequestMapping 注解用于建立请求URL和处理方法之间的对应关系,也可以通过它的属性对请求做出各种限制
此注解可以标注在方法上,也可以标注在类上,标注在类上代表类中的所有方法都可以共用一段URL
在SpringMVC中可以使用多种类型来接收前端传入的地址栏参数
简单类型(8种基本类型 \ 8种基本类型的包装类型 \ 字符串)
使用方式:只需要保证前端传递的参数名称跟方法的形参名称一致即可
//处理器中属性名必须和请求参数名一致
@RequestMapping("/simpleParam")
public String simpleParam(Integer id, String name){
System.out.println(id);
System.out.println(name);
return "success";
}
对象(pojo)类型
使用方式:只需要保证前端传递的参数名称跟pojo的属性名称(set方法)一致即可,所有的请求参数自动地封装到java对象种
@RequestMapping("/dtoParam")
public String voParam(UserDTO dto){
System.out.println(dto);
return "success";
}
数组类型
使用方式:只需要保证前端传递的参数名称跟方法中的数组形参名称一致就好
同名参数传递,自动的将请求参数封装到数组种
集合类型
将集合包装到一个对象中即可,自动的将前端传入的数据封装到对象中的集合属性
日期类型
在springmvc中内置了一系列的类型转化器,可以自动的将请求参数的String类型转化为某种格式(Integer)
对于一些常见的类型, SpringMVC是内置了类型转换器的,但是对于一些格式比较灵活的参数(日期 时间),SpringMVC无法完成类型转换,就需要自定义类型转换器
@RequestParam注解 标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:
在控制器中获取当前请求的请求头的方式:
@RequestHeader Map map : 获取所有的请求头
@RequestHeader("cookie") String cookie : 根据key从所有头信息中获取指定头信息
/**
* 在控制器中获取,当前请求的请求头
*/
@RequestMapping(value="/demo12")
public String demo12(@RequestHeader Map map,
@RequestHeader("cookie") String cookie,
@CookieValue("JSESSIONID") String sessionId) {
System.out.println(map);
System.out.println(cookie);
System.out.println(sessionId);
return "success";
}
客户端文件上传的三要素
springmvc中服务端
文件上传依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
需要在SpringMVC的配置文件中,配置文件上传解析器(自动的将上传的内容,转化为MultipartFile对象)
<!--
文件解析器
id:固定值(multipartResolver)
property:其中指定上传文件的大小规则
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--文件的大小规则 5M = 1024 * 1024 * 5 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
在控制器方法上,直接使用MultipartFile对象参数封装上传的文件
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @Controller public class FileUploadController { /** * 上传文件到服务端。服务端将文件转存到E:\file * MultipartFile :封装上传的文件 * 参数名 :和上传文件的input的name属性一致 */ @RequestMapping("/upload") public String upload(MultipartFile myFile, String name) throws IOException { System.out.println("name=" + name); System.out.println(myFile.getOriginalFilename()); //获取上传文件名 System.out.println(myFile.getSize()); //获取上传文件大小 File file = new File(new File("E:\\file"), myFile.getOriginalFilename()); myFile.transferTo(file); //写入文件内容 return "success"; } }
Ajax + json 实现异步交互
在SpringMVC中进行 ajax 的数据交互,需要通过两个注解简化开发
@RequestBody : 自动的将请求的 json 字符串,转化为指定 java 对象(处理请求)
@ResponseBody :自动的将 java 对象,通过转换器转换为指定的格式(通常为 json 字符串))并响应(处理响应)
@RequestMapping("/testAjax")
@ResponseBody
public User testAjax(@RequestBody User user) {
System.out.println("ajax请求的数据对象=" + user);
//调用业务逻辑
User user2 = new User();
user2.setUsername("张三");
return user2;
}
注意: Springmvc默认用 MappingJackson2HttpMessageConverter 对 json 数据进行转换,需要加入 jackson 的包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
Servlet原生API对象:HttpServletRequest,HttpSevletResponse,HttpSession
语法规则:
方式1(推荐):将对象以方法参数的形式配置到controller方法中
/**
* 获取Servlet原生API对象(request,response,session)
*/
@RequestMapping("/demo2")
public String demo2(HttpServletRequest request, HttpServletResponse response,
HttpSession session) {
request.setAttribute("user", "1");
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}
方式2:将需要的API对象通过 @Autowired 的方式注入进来
请求转发:只发送一起请求,不会丢失数据(SpringMVC的默认页面跳转形式)
方式1:直接返回逻辑视图
方式2:使用 forward 转发
@RequestMapping("/demo3")
public String demo3() {
System.out.println("forward转发");
return "forward:/WEB-INF/jsps/success.jsp";
}
方式3:使用servlet原生api
@RequestMapping("/demo3")
public void demo3(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("servlet原生API对象");
request.getRequestDispatcher("/WEB-INF/jsps/success.jsp").forward(request, response);
}
转发时携带数据:返回响应数据。
方式1(推荐):将数据绑定到request域
@RequestMapping("/demo4")
public String demo4(HttpServletRequest request){
// 将数据绑定到request域
request.setAttribute("username", "张三")
return "result"
}
页面通过 el 表达式获取响应数据并展示
方式2:绑定到Model对象
Model:SpringMVC中的Model配置到参数上,底层通过Request实现。可以用于替换request完成数据响应
@RequestMapping("/demo4")
public String demo4(Model model){
// 将数据绑定到Model对象
model。addAttribute("username", "张三")
return "result"
}
方式3(官方):通过ModelAndView返回
ModelAndView : 模型视图对象,通过此对象可以指定返回的视图地址和数据绑定
语法规则:
@RequestMapping("/demo4")
public ModelAndView demo4() {
ModelAndView mv = new ModelAndView();
// 指定响应数据
mv.addObject("username", "传智播客");
// 配置返回页面视图地址
mv.setViewName("result"); // 支持逻辑视图,支持forward:物理视图
return mv;
}
重定向:通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)。
实现原理:
客户端浏览器发送http请求,web服务器接收请求后发送302状态码响应及对应新的location给客户端,客户端发现是302请求,则自动再发送一个新的http请求,请求url是新的location,服务器再根据新的http请求响应客户端。
在这里的location可以定义到任意的url,既然是浏览器重新发送了请求,则就没有什么request传递的概念了,在客户端浏览器的路径栏显示的是其重定向的路径,客户端可以观察到路径的变化。
特点:
重定向的方式:
方式1(推荐):使用 redirect 重定向
@RequestMapping("/demo5")
public void demo5(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("第一次请求");
return "redirect:/demo6";
}
@RequestMapping("/demo6")
public String demo6() {
System.out.println("重定向到demo6");
return "success";
}
方式2:使用servlet原生API
@RequestMapping("/demo5")
public void demo5(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("第一次请求");
response.sendRedirect("/demo6");
}
@RequestMapping("/demo6")
public String demo6() {
System.out.println("重定向到demo6");
return "success";
}
使用传统方式操作session域
@RequestMapping("/hello13.action")
public String hello13(HttpSession session){
session.setAttribute("prod", "电视机");
return "hello";
}
@RequestMapping("/hello14.action")
public String hello14(HttpSession session){
String prod = (String) session.getAttribute("prod");
System.out.println(prod);
return "hello";
}
使用 @SessionAttribute(“name”) ,从session里面根据name来获取对应的参数的值
@GetMapping("/test-mvc-get-session")
public String testMvcGetSession(@SessionAttribute("girl") String girl) {
System.out.println("testMvcGetSession -----> girl in session is " + girl);
return "success";
}
使用ModelMap对象从session域中获取值
@RequestMapping("/getValue")
public String getValue(ModelMap modelMap){
System.out.println(modelMap.get("value"));
return "success";
}
清空session域
@RequestMapping("/delValue")
public String delValue(SessionStatus sessionStatus){
//清空session
sessionStatus.setComplete();
return "success";
}
当有静态资源需要加载时,比如 jquery.js,通过谷歌开发者工具抓包发现,没有加载到 jquery.js 的原因:
释放静态资源方式
方式1(推荐):在Springmvc的配置文件中配置统一释放所有的静态资源文件
<mvc:default-servlet-handler/>
方式2:在SpringMVC的配置文件中配置释放静态资源
当静态资源请求到SpringMVC的前端控制器时,根据释放资源的配置
<mvc:resources mapping="/js/*" location="/js/"></mvc:resources>
<mvc:resources mapping="/image/*" location="/image/"></mvc:resources>
<mvc:resources mapping="/css/*" location="/css/"></mvc:resources>
方式3:修改web.xml
中前端控制器的URL映射规则,以特殊字符串结尾的请求交给前端控制器处理
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
对于异常的处理一般有两种方式:
一种是当前方法处理(try-catch),这种处理方式会造成业务代码和异常处理代码的耦合。
一种是当前方法不处理,出现异常后直接抛给调用者处理。
使用Spring框架,代码最终是由框架来调用的,也就是说,异常最终会抛到框架,然后由框架指定异常处理器来统一处理异常。
方式1:自定义异常处理器
自定义一个类实现HandlerExceptionResolver接口,重写resolveException方法,将异常处理器交给spring容器管理即可
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 自定义异常处理器 * 跳转到一个美化的页面,携带错误信息 */ @Component public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView mv = new ModelAndView(); mv.addObject("errorMsg","运行报错!"); mv.setViewName("forward:error.jsp"); return mv; } }
方式2:通过@ControllerAdvice 和 @ExceptionHandler 注解定义全局异常处理
使用方式:
import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; /** * 定义全局异常处理 */ @ControllerAdvice public class MyHandlerException2 { @ExceptionHandler(value=Exception.class) public String handlerException(Model model) { model.addAttribute("errorMsg", "运行报错!"); return "forward:error.jsp"; } }
方式3:使用web提供的异常机制
在web.xml中提供异常处理配置
<!--处理403异常-->
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
<!--处理404异常-->
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
拦截器是SpringMVC提供的一种技术, 它的功能似于过滤器Filter,它会在进入controller之前,离开controller之后以及页面渲染完毕之后进行拦截
拦截器和过滤器的区别
过滤器是Servlet 规范中的一部分,任何java web工程都可以使用;
拦截器是SpringMVC框架的,只有使用了SpringMVC框架的工程才能用。
过滤器在url-pattern中配置了 /* 之后,可以对所有要访问的资源拦截;
拦截器只会拦截访问的控制器方法,如果访问的是jsp,js,html,css,image等,它是不拦截的。
实现HnadlerInterceptor接口
实现其中的三个方法(三个拦截点)
// 进入controller方法之前执行的内容(对请求拦截处理)
// 返回值 boolean。true :放行(继续向后执行,进入到controller),false :拦截过滤
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
// 执行了controller方法之后,执行的内容(对象响应进行拦截处理)
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
// 页面渲染完成之后,执行(一般不用)
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 自定义拦截器 * 实现HnadlerInterceptor接口。实现其中的三个方法(三个拦截点) */ public class MyInterceptor01 implements HandlerInterceptor { /** * 进入controller方法之前执行的内容(对请求拦截处理) */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String path = request.getServletPath(); if (path.matches(Const.NO_INTERCEPTOR_PATH)) { //不需要的拦截直接过 return true; } else { // 这写你拦截需要干的事儿,比如取缓存,SESSION,权限判断等 System.out.println("===================================="); return true; } } /** * 执行了controller方法之后,执行的内容(对象响应进行拦截处理) */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("执行MyInterceptor01的postHandle方法"); } /** * 页面渲染完成之后,执行(不用) */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("执行MyInterceptor01的afterCompletion方法"); } }
关键代码:path.matches(Const.NO_INTERCEPTOR_PATH 就是基于正则匹配的url
/** * 常量类 */ public class Const { public static final String SUCCESS = "SUCCESS"; public static final String ERROR = "ERROR"; public static final String FIALL = "FIALL"; /**********************对象和个体****************************/ public static final String SESSION_USER = "loginedAgent"; // 用户对象 public static final String SESSION_LOGINID = "sessionLoginID"; // 登录ID public static final String SESSION_USERID = "sessionUserID"; // 当前用户对象ID编号 public static final String SESSION_USERNAME = "sessionUserName"; // 当前用户对象ID编号 public static final Integer PAGE = 10; // 默认分页数 public static final String SESSION_URL = "sessionUrl"; // 被记录的url public static final String SESSION_SECURITY_CODE = "sessionVerifyCode"; // 登录页验证码 // 时间 缓存时间 public static final int TIMEOUT = 1800;// 秒 public static final String ON_LOGIN = "/logout.htm"; public static final String LOGIN_OUT = "/toLogout"; // 不验证URL anon:不验证/authc:受控制的 public static final String NO_INTERCEPTOR_PATH =".*/((.css)|(.js)|(images)|(login)|(anon)).*"; }
1.创建注解:
/**
* 在需要登录验证的Controller的方法上使用此注解
*/
@Target({ElementType.METHOD}) // 可用在方法名上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface LoginRequired {
}
2.创建拦截器:
public class MyInterceptor02 extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 如果不是映射到方法直接通过 if (!(handler instanceof HandlerMethod)) { return true; } // 方法注解级拦截器 HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); // 判断接口是否需要登录 LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class); // 有 @LoginRequired 注解,需要认证 if (methodAnnotation != null) { // 拦截需要干的事儿,比如取缓存,SESSION,权限判断等 System.out.println("===================================="); return true; } return true; } }
config类方式
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.*.*.interceptor.AdminInterceptor; /** * 拦截器配置 */ @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //注册MyInterceptor01拦截器 InterceptorRegistration registration = registry.addInterceptor(getMyInterceptor01()); registration.addPathPatterns("/**"); //所有路径都被拦截 registration.excludePathPatterns( //添加不拦截路径 "登陆路径", //登录 "/**/*.html", //html静态资源 "/**/*.js", //js静态资源 "/**/*.css", //css静态资源 "/**/*.woff", "/**/*.ttf" ); // 注册MyInterceptor02拦截器。拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要拦截 registry.addInterceptor(getMyInterceptor02()).addPathPatterns("/**"); } @Bean public MyInterceptor01 getMyInterceptor01() { return new MyInterceptor01(); } @Bean public MyInterceptor02 getMyInterceptor02() { return new MyInterceptor02(); } }
xml方式
在SpringMVC的配置文件中,添加拦截器配置(配置拦截器对应需要拦截的URL和方法规则)
<!--配置SpringMVC的拦截器-->
<mvc:interceptors>
<!--配置具体的拦截器和拦截器的拦截规则-->
<mvc:interceptor>
<!-- mapping : 配置拦截规则。 /** 表示拦截所有 -->
<mvc:mapping path="/**"/>
<!-- exclude-mapping: 配置不拦截的规则 -->
<mvc:exclude-mapping path="/hello/demo2"/>
<!--创建对象:在当前拦截器中有效-->
<bean class="cn.test.interceptors.MyInterceptor01"></bean>
</mvc:interceptor>
</mvc:interceptors>
开发中拦截器可以单独使用,也可以同时使用多个拦截器形成一条拦截器链。
开发步骤和单个拦截器是一样的,只不过注册的时候注册多个,注意这里注册的顺序就代表拦截器执行的顺序。
配置拦截器:多个拦截器链的执行顺序和配置顺序有关
<!--配置SpringMVC的拦截器--> <mvc:interceptors> <!--配置具体的拦截器和拦截器的拦截规则--> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/hello/demo2"/> <bean class="cn.test.interceptors.MyInterceptor01"></bean> </mvc:interceptor> <!--配置具体的拦截器和拦截器的拦截规则--> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/hello/demo2"/> <bean class="cn.test.interceptors.MyInterceptor02"></bean> </mvc:interceptor> </mvc:interceptors>
1.自定义一个类型转换器,实现类型转换的方法
import org.springframework.core.convert.converter.Converter; import java.text.SimpleDateFormat; import java.util.Date; /** * 自定义的类型转换器 * 实现Converter接口,<原始类型,目标类型> */ public class StringToDateConverter implements Converter<String, Date> { /** * 日期转化 * 参数:请求参数中的原始数据 * 返回值:转换好的数据(目标类型) */ public Date convert(String source) { Date date = null; try { date = new SimpleDateFormat("yyyy-MM-dd").parse(source); }catch (Exception e) { e.printStackTrace(); } return date; } }
2.将自定义的类型转换注册到SpringMvc的转换服务中,然后再将服务注册到SpringMVC的注解驱动
<!--将自定义的类型转化器加入Springmvc的转化器ConversionService的集合中-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!--使用集合传入自定义的converter-->
<property name="converters">
<set>
<!--一个bean对应一个类型转换器-->
<bean class="cn.test.converter.StringToDateConverter"></bean>
</set>
</property>
</bean>
<!--将Springmvc的转化器注册到springmvc驱动中-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.GenericConversionService;
@Configuration
public class ConvertConfig {
@Bean
public ConversionService genericConversionService(GenericConversionService genericConversionService){
genericConversionService.addConverter(new StringToDateConverter());
return genericConversionService;
}
}
restful简称REST,全称是Representational State Transfer。
REST是一种软件架构风格, 其强调HTTP应当以资源为中心 ( URL中尽量不要出现动词 )。
它制定了HTTP请求四个动作,分别表示对资源的CRUD操作: GET(获取)、POST(新建)、PUT(更新)、DELETE(删除)
restful 使用方式:
原来 | Restful | |
---|---|---|
保存 | /saveUser | POST /user |
修改 | /udpateUser?uid=1 | PUT /user/1 |
删除 | /deleteUser?uid=1 | DELETE /user/1 |
查询一个 | /findUserByUid?uid=1 | GET /user/1 |
查询所有 | /findUser | GET /user |
@Controller @RequestMapping("/user") public class UserController { /** * 根据id查询 * 请求地址:/user/5 * 请求方式:GET */ @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String findById(@PathVariable(value="id") String id) { System.out.println("根据id查询,id=" + id); return "success"; } /** * 根据id删除 * 请求地址:/user/5 * 请求方式:DELETE */ @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public String delete(@PathVariable(value="id") String id) { System.out.println("根据id删除,id=" + id); return "success"; } /** * 根据id更新 * 请求地址:/user/5 * 请求方式:PUT */ @RequestMapping(value="/{id}", method = RequestMethod.PUT) public String update(@PathVariable(value="id") String id) { System.out.println("根据id更新,id=" + id); return "success"; } /** * 保存 * 请求地址:/user * 请求方式:POST */ @RequestMapping(value="/", method = RequestMethod.POST) public String save() { System.out.println("保存"); return "success"; } }
@RestController注解说明
restful风格多用于前后端绝对分离的项目开发中,这时同步请求将无法使用,所有的处理器都将成为返回数据的异步请求。
这种情况,可以将所有处理器方法上的 @ResponseBody 注解提取到类上去。
然后,进一步可以使用 @RestController 注解来替代 @Controller 和 @ResponseBody 两个注解。
写法如下:
//@Controller
//@ResponseBody
@RestController
@RequestMapping("/day02")
public class Day02Controller {
...
}
SpringMVC在使用post提交请求时,对于中文参数是有乱码问题的, 针对这种情况它提供了一个中文乱码过滤器,只需要进行配置一下即可。
在web.xml
配置SpringMVC中文乱码过滤器
<!--在web.xml中配置过滤器,设置编码即可 CharacterEncodingFilter--> <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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。