默认配置文件名 中央控制器-servlet.xml
springmvc-servlet.xml 且放在 web-inf下面
改变: 1. 新建 source文件夹 –>spring.xml
2. web.xml 下面
添加 :
contextConfigLocation
classpath:springmvc.xml
即可:
此种方式是不是想起了
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 对Spring容器进行实例化 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 中央控制器 -->
<servlet>
<servlet-name>springmvc</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>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- struts习惯使用/*,在springmvc不管用 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
1.传递参数时候,表单参数name 必须要和实体类的属性setter 方法后面的字符串匹配上,首字母不区分大小写;
@RequestMapping("/toPerson.do")
public String toPerson(Person person,User user,Date birthday){
return "jsp1/index";
}
- User实体 和Person 实体如果属性名一样, 那么表单传过来的属性都会被 注入 .
充分发现这种方式 比 struts2 的驱动模型更加简约
3.注册时间类型的属性编辑器 Date birthday;
- checkbox 类型 参数 数组类型
url : localhost:8080/springmvc/toPerson.do?names=wangli&names=zhangsan
@RequestMapping("/toPerson.do")
public String toPerson(String names[]){
for(String result: names){
System.out.println(result);
}
return "jsp1/index";
}
handler(配置文件) 和 @RequestMapping 不太一样,
handler是标注在类上面的,而 @RequestMapping是标注在方法上面的
故@RequestMapping 有点像 Struts2 中的 user_* 那种 抽象 动态的 ActionModelAndView方式一:
@RequestMapping("/toPerson.do")
public ModelAndView toPerson(){
Person person = new Person();
person.setName("wangli");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = format.partse("1992-2-2");
Map <String, Object> map = new HashMap<String,Object>();
map.put("p",person);
return new ModelAndView("index",map); // 类似于Struts2 的 ActionContext.getContext().push(map); 放入了 request域内
}
前台 :
<span>${p.name}</span>
<span>${p.passwd}</span>
<span>${p.age}</span>
<span>${p.birthday }</span>
- 如果希望我们输出的日期更好看 ,可以使用jstl标签库
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatDate value="${p.birthday}" pattern="yyyy-MM-dd" />
ModelAndView方式二:
为了统一: 全部返回String类型
@RequestMapping("/toPerson.do")
public ModelAndView toPerson( Map<String,Object) map) {
Person person = new Person();
person.setName("wangli");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = format.partse("1992-2-2");
map.put("p",person);
return "index";
}
// 此种方式更加类似 与 struts2 的设计, 参数 map 会自动和return “index” 共同作为ModelAndView对象.
且 形参 map 没有像 6中那样 Map <String, Object> map = new HashMap<String,Object>();
无需new 对象, 似乎(前台表单参数 ) 以及 map 被自动放入了值栈一样,不建议使用;
由视图解析器统一处理
表单参数只要和 形参列表名称匹配就能接收前台所传过来的数据,可以自动转换成参数列表里面的类型
注意的是 值与类型之间是可以转换的 .ModelAndView方式三 :
@RequestMapping("/toPerson.do")
public ModelAndView toPerson(Model model ) {
Person person = new Person();
person.setName("wangli");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = format.partse("1992-2-2");
// 相当于把 参数值放入到 request 里面
model.addAttribute("p",person);
return "index"; // 建议使用
}
- Ajax方式1: 使用Ajax访问 ,不需要跳转 页面,返回值设置为 void 即可
@RequestMapping("/ajax.do")
public void ajax(String name,HttpServlet response ){
String result = "hello " + name;
response.getWriter().write(result);
}
- Ajax方式2:
@RequestMapping("/ajax.do")
public void ajax(String name,PrintWriter out){
String result = "hello " + name;
out.write(result);
}
Request method ‘GET’ not supported
因为后台 :
@RequestMapping(value=”/toPerson.do”,method=RequestMethod.POST) // 可以指定请求方式,那么前台必须以其指定的方式访问,否则出现405错误重定向到 本Controller
@RequestMapping("/toForm.do")
public String toForm(){
//............. 代码
return "form";
}
@RequestMapping("/redirectToForm.do")
public String redirectToForm(){
return "redirect:toForm.do"; //但是此种方式只是在本命名空间(本Controller)重定向
}
- 重定向到 其他Controller
@RequestMapping("/redirectToForm.do")
public String redirectToForm(){
return "redirect:/test1/"; // 注意必须加/ "/test1/test.do" 根路径(指定Controller 的命名空间); 不要写成 "test1/test.do" 否则仍然会在本Controller里面找
文件上传:
需要现在 xml 中配置
注意: id 必须指定如下所示:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--文件上传的最大值 单位 byte 1M= 1024*1024 ,但是不支持乘法 -->
<property name="maxUploadSize" value="1024000"
</bean>
前台:
<form method="post" enctype="multipart/form-data">
</form>
后台:
@RequestMapping(value="toPerson.do")
public String toPerson(Person person,HttpServletRequest request){
// 第一步转换request
MultipartHttpServletRequest rm = (MultipartHttpServletRequest) request;
// 获得文件
CommonsMultipartFile cfile = (CommonsMultipartFile) rm.getFile("pic");
// 获得文件的字节数组
byte [] bfile = cfile.getBytes();
String fileName = "";
// 获得当前时间
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS"); //SSS是毫秒
fileName = format.format(new Date());
Random random = new Random();
// 在文件名后面加入3个随机数子
for(int i=0;i<3;i++){
fileName = fileName + random.nextInt(9); // 0~9
}
// 获取原始文件名
String origFileName = cfile.getOriginalFilename();
// xxx.jpg --------- .jpg
String suffix = origFileName.substring(origFileName.lastIndex("."));
String path = request.getSession().getServletContext().getRealPath("/");
OutputStream out = new FileOutputStream(new FileOutputStream(new File(path+"/upload/"+fileName+suffix) ));
out.write(bfile);
out.flush();
out.close();
return "jsp1/success";
}
- 拦截器:
package cn.itcast.springmvc.interceptor;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyIntercepor implements HandlerInterceptor {
/**
* 执行时机:视图已经被解析完毕,类似try catch 后的finally -------------------------------->finally
*/
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception ex)
throws Exception {
System.out.println("afterCompletion...");
ex.printStackTrace();
System.out.println("================");
}
/**
* 执行时机:controller执行完,视图解析器没有把视图解析成页面,
* 对视图做统一的修改,主要体现在Model上
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView mv) throws Exception {
System.out.println("postHandler...");
Map<String, Object> map = mv.getModel();// 如对 某些字符的过滤 ; 或 对 model 加点东西, 在字符前面和后面加点东西
map.put("test", "append something");
}
/**
* 执行时机:在执行controller之前来执行
* 返回值类型:boolean:true代表放行可以访问controller,false不可以访问controller
Struts2拦截 返回的是 input视图 ;
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception { // arg2 表示被拦截 Controller类的实例
System.out.println("preHander...");
return true; // true 放行 false 拦截
// 常用 按钮级别的 权限 ;
}
}
springmvc.xml 中配置: 注意 , 根据配置顺序,拦截器也是先后执行, 但是注意了,拦截器1 里面的preHandle,postHandle,afterCompletion 可不是拦截器1全部方法执行完了
再执行 拦截器1 里面的preHandle,postHandle,afterCompletion。
而是
先拦截器1 preHandle(), 拦截器2 preHandle();
Controller ——>执行
拦截器1 postHandle(),拦截器2 postHandle(),
拦截器1 afterCompletion(), 拦截器2 afterCompletion();
<mvc:interceptors>
<mvc:interceptor>
<!-- 某一模块的拦截:/myPath/**, 拦截所有的请求/**-->
<mvc:mapping path="/**"/>
<bean class="cn.itcast.springmvc.interceptor.MyIntercepor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 某一模块的拦截:/myPath/**, 拦截所有的请求/**-->
<mvc:mapping path="/**"/>
<bean class="cn.itcast.springmvc.interceptor.MyIntercepor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
————————————–>
总配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- mvc的注解驱动 -->
<mvc:annotation-driven/>
<!-- 一旦有扫描器的定义mvc:annotation-driven不需要,扫描器已经有了注解驱动的功能 -->
<context:component-scan base-package="cn.itcast.springmvc"/>
<!-- 前缀+ viewName +后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- webroot到某一指定的文件夹的路径 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 视图名称的后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- id="multipartResolver"必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- maxUploadSize:文件上传的最大值以byte为单位 -->
<property name="maxUploadSize" value="1024000"></property>
</bean>
<mvc:interceptors>
<mvc:interceptor>
<!-- 某一模块的拦截:/myPath/**, 拦截所有的请求/**-->
<mvc:mapping path="/**"/>
<bean class="cn.itcast.springmvc.interceptor.MyIntercepor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>