Spring MVC
Spring MVC
1 springMVC简介
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1,Struts2等。
Web层框架:springMVC、Struts(struts1、webwork、struts2、JSF(sun公司的实现--JSF,Apache的实现 MyFaces,...))
2 springMVC的主要作用
1 处理数据
2 控制跳转
3 调用后台代码
4 异常处理
5 国际化
...
3 使用springMVC
3.1 添加jar包
3.2 配置核心控制器
在web.xml 添加核心控制器的配置
|
<servlet> <servlet-name>first</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>first</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
配置说明:
DispatcherServlet 核心控制器类
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
指定springMVC的配置文件
注意:可以不指定springMVC的配置文件,当不指定时,配置文件默认为
<servlet-name>first</servlet-name>的配置名字
加上-servlet。即为 first-servlet.xml
3.3 springMVC配置文件
存放位置: WEB-INF下。
由于springMVC属于spring的一部分,因此springMVC的配置文件,就是一个spring的配置文件。
主要配置内容:
启动spring的注解
<context:annotation-config />
启动bean扫描
<context:component-scan base-package="web.controller" />
启动spring MVC 注解方式
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
或<mvc:annotation-driven />
4 控制器(Controller)
springMVC的控制器类可以是一个POJO(不需要继承和实现接口)
4.1 控制器添加注解说明
4.1.1 @Controller
添加在类名上,说明这个类为springMVC的Controller
|
@Controller public class UserController { |
4.1.2 @RequestMapping
配置Controller的访问路径
1 在类上和方法名上配置
|
@Controller @RequestMapping("UserController.do") public class UserController { @RequestMapping public String register(){ return "index.jsp"; }
} |
这个Controller的访问路径为 UserController.do
如何访问register方法?
如果UserController只有这个一个方法,那么访问这个Controller时,直接调用的就是这个方法。
其他配置:
|
@RequestMapping(method=RequestMethod.GET,params="method=reg") |
配置说明:
method=RequestMethod.GET: 表示这个方法只有get请求时可以访问
params="method=reg": 当Controller中有多个方法时,指定方法的访问方式。
Register方法的访问方式为:
UserController.do?method=reg
2 只在方法名上配置(类上不添加@RequestMapping注解)
|
@RequestMapping("/reg") public String register(){ return "index.jsp"; } |
这个方法的访问路径为: reg.do
这样做的问题是: 当多个Controller中的方法上有相同的@RequestMapping配置时,无法区分。
因此:只在方法上配置时,建议添加一个前缀
|
@RequestMapping("/UserController/reg") public String register(){ return "index.jsp"; } |
方法的访问路径为: UserController/reg.do
4.2 获取客户端提交的数据
4.2.1使用方法参数HttpServletRequest
|
public String register(HttpServletRequest request){ String name = request.getParameter(“name”); return "index.jsp"; } |
4.2.2 使用@RequestParam("")注解
|
public String register(@RequestParam("name") String name,@RequestParam("age") int age){} |
@RequestParam("name") 注解中的参数要求和请求参数的key值相同
注意:当方法的参数名和请求中的key值相同时,@RequestParam注解可以省略
4.2.3 @PathVariable 注解
|
@RequestMapping(value="/hello/{name}/{age}") public String hello(@PathVariable("name") String name,@PathVariable("age") int age){ //省略了 class 上的@RequestMapping // 访问这个方法??? hello/zhangsan/100.do System.out.println(name+"\t"+age); return "/helloworld.jsp"; } |
4.2.4 @ModelAttribute 注解
public String register(@ModelAttribute User user,@RequestParam("birthday111") String birthday)
客户端提交的数据会直接封装 user中,要保证请求参数的key和user的属性相同
还会将user存入request作用域
对于Date的birthday无法完成直接的赋值,因此单独进行配置
4.2.5 解决日期类型赋值问题
方式一:在Controller中添加如下代码
|
@InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); // true:允许输入空值,false:不能为空值
} |
方式二:编写、配置转换器
|
转换器: public class DateConverter implements Converter<String, Date> {
@Override public Date convert(String source) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); try { return dateFormat.parse(source); } catch (Exception e) { e.printStackTrace(); } return null; } } |
|
配置、引用 <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!-- 设置多个转换器 --> <property name="converters"> <list> <bean class="com.zrgk.converter.DateConverter"></bean> </list> </property> </bean>
<mvc:annotation-driven conversion-service="conversionService" />
使用这种方式开启springMVC的注解方式,可以引入上面的转换器 |
4.3 使用作用域保存值
4.3.1 使用request.setAttribute()
4.3.2 通过方法的参数 ModelMap model
|
public String register(ModelMap modelMap){
modelMap.put(“key”,Object);//放在request作用域 } |
4.4 controller中使用Session
4.4.1 使用request获取
4.4.2 使用@SessionAttributes注解
|
@SessionAttributes({"user","name"}) public class RegisterController{ @RequestMapping(value="RegisterController/reg") public String register(ModelMap modelMap){
modelMap.put("user",user); --放在request作用域 modelMap.put("name","中软高科"); } }
modelMap中存的值 将会在session中也保存一份
|
4.5 关于跳转
4.5.1 转发
方法返回字符串 默认是转发方式。
4.5.2 重定向
return “redirect:index.jsp”
4.5.3 跳转路径 前缀后缀的设置
|
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> </bean> |
return “index” 将会跳转到 /WEB-INF/view/index.jsp
4.6 ModelAndView的使用
|
public ModelAndView test2(){
String name = “中软高科”; return new ModelAndView(new Redirect(“index.jsp”));
} return new ModelAndView(new Redirect(“index.jsp”),”name”,name); -- 另一种带值得方式
return new ModelAndView(new RedirectViews(“index.jsp”),map); --map 为Map 也是用来带值
}
|
|
public ModelAndView test2(){
ModelAndView mav = new ModelAndView();
mav.setViewName(viewName); //设置跳转路径 mav.addObject(obj) // 这种设置方式,带的值 key为这个对象所属类的 类名首字母小写 mav.addObject(“key”,obj)
return mav;
}
|
4.7 @ModelAttribute注解
4.7.1 获取客户端提交数据
|
public String register(@ModelAttribute User user,@RequestParam("birthday111") String birthday)
客户端提交的数据会直接封装 user中,要保证请求参数的key和user的属性相同
还会将user存入request作用域 对于Date的birthday无法完成直接的赋值,因此单独进行配置
|
4.7.2 设置前置执行方法
加在方法上,方法将会在controller中要调用的方法之前执行
|
@ModelAttribute("myList") public List<User> getList(){ //这个方法将在Controller中要调用的方法之前执行 System.out.println("getList......"); User u1 = new User(1,"aaa",20,new Date()); User u2 = new User(2,"bbb",30,new Date()); User u3 = new User(3,"ccc",40,new Date());
List<User> list = new ArrayList<User>(); list.add(u1); list.add(u2); list.add(u3);
return list; }
|
页面可以直接根据 myList使用 方法返回的list,使用C标签遍历即可。
5 声明式异常处理
|
@ExceptionHandler({Exception.class})//异常处理 public String exceptionHandler(Exception e){
System.out.println(e.getMessage());
return "exception.jsp"; }
|
6 文件上传
6.1 依赖jar包
commons-fileUpload.jar
commons-io.jars
6.2 配置解析器
|
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"> </bean>
|
6.3 单个文件上传代码实现
|
@RequestMapping public String upload(HttpServletRequest request) throws Exception{
MultipartHttpServletRequest req = (MultipartHttpServletRequest)request;
MultipartFile mf = req.getFile("myFile");
System.out.println(mf.getName()); System.out.println(mf.getOriginalFilename()); System.out.println(mf.getSize());
InputStream is = mf.getInputStream();
String folderPath = request.getSession().getServletContext().getRealPath("/upload"); OutputStream os = new FileOutputStream(folderPath+"/"+mf.getOriginalFilename());
int len=0; byte[] b = new byte[1024];
while((len=is.read(b))>0){
os.write(b, 0, len); }
is.close(); os.close();
return "success.jsp"; }
|
6.4 多文件上传代码实现
|
public String upload(HttpServletRequest request,ModelMap model) throws Exception{ MultipartHttpServletRequest req = (MultipartHttpServletRequest)request; List<MultipartFile> list = req.getFiles("myFile"); String folderPath = request.getSession().getServletContext().getRealPath("/upload"); for(MultipartFile mf:list){ if(!mf.isEmpty()){ OutputStream os = new FileOutputStream(folderPath+"/"+mf.getOriginalFilename()); InputStream is = mf.getInputStream(); byte[] b = new byte[1024]; int len = 0; while((len=is.read(b))>0){ os.write(b, 0, len); } is.close(); os.close(); System.out.println(mf.getName()); System.out.println(mf.getOriginalFilename()); } } return "success.jsp"; }
|
6.5 上传文件大小验证
|
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"> <property name="maxUploadSize"> <value>200000000000</value> </property> </bean>
SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException 该异常是SpringMVC在检查上传的文件信息时抛出来的,而此时还没有进入到Controller方法中 因此,不能依靠Controller中的异常处理方式,需要在配置文件中进行配置 <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 --> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload.jsp</prop> </props> </property> </bean>
|
7 拦截器(自定义拦截器)
7.1 实现HandlerInterceptor接口
|
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { //Object arg2 指的是下一个拦截器对象 System.out.println("Controller之前执行..."); return true; } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("controller之后,生成视图之前执行"); } @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("最后执行,一般用来释放资源"); } } |
7.2 继承 HandlerInterceptorAdapter
可以指定覆盖哪个方法
7.3 配置拦截器
拦截器定义完成后,需要在配置文件中进行配置
|
<mvc:interceptors> <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 --> <bean class="web.interceptor.MyInterceptor"/> <mvc:interceptor> <mvc:mapping path="/RegisterController.do"/> <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 --> <bean class="web.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
|
8 Controller方法返回JSON数据
8.1 添加jar包支持
jackson-core-asl.jar
jackson-mapper-asl.jar
8.2 修改配置文件
|
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html; charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </list> </property> </bean>
|
8.3 Controller中方法
|
@RequestMapping public @ResponseBody List<User> test(String name){ System.out.println(name+"-------------");
User u1 = new User("aaa","123",20); User u2 = new User("bbb","345",21); User u3 = new User("ccc","234",22);
List<User> list = new ArrayList<User>();
list.add(u1);list.add(u2);list.add(u3);
return list; }
|
浙公网安备 33010602011771号