JSP Model 1
jsp负责显示/逻辑控制
JSP Model 2
jsp负责显示,servlet负责逻辑
处理流程
发送请求->委托请求给处理器->调用业务对象->返回数据模型
->返回ModelAndView->渲染视图->返回控制->产生响应
-----------------------------------------------
可以用form标签
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
DispatcherServlet
Handler
@controller //标记控制器类
@RequestMapping(value,method,param) //请求映射路径
@PathVariable //得到请求url地址中的参数
@RequestParam //得到请求页面标签的name值
@ResponseBody //把对象放进body作用域
方法的返回值
ModelAndView
Model
View
String //返回逻辑视图名
Object
void
============================================================
Spring MVC
BeanNameUrlHandlerMapping------------------
spring配置(引入schema/mvc)
<!--默认 可以不写 引入这个类,页面映射RequestMapping要写在这个配置文件中-->
1. <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
2. 使用注解的方式(后面会讲到)
<!-- MyController这个类继承了AbstractController并重写其方法返回jsp文件名 -->
<!-- 页面访问url:localhost:8080/项目名/welcom -->
<bean name="/welcome" class="com.pp.controller.MyController"/>
//return new ModelAndView("welcome");
<!-- 返回的是个ModelAndView对象,会找到这个InternalResourceViewResolver类 -->
<!-- 通过前缀,后缀和返回结果拼接成路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
******************************************************************************
Web.xml配置信息
<!-- 处理字符编码的filter -->
<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>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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:DispatcherServlet-servlet.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>
<!--
1. servlet的name:DispatcherServlet要和springMVC配置文件名一样,如DispatcherServlet-servlet.xml
2. Web容器启动时,按照优先级顺序加载<load-on-startup>的参数越小级别越高,同时写在<init-param>标签下才不会报错
-->
******************************************************************************
<context:component-scan base-package="com.pp.controller"></context:component-scan>
<mvc:annotation-driven/>
<!--
在springMVC配置文件中 使用annotation注解的方式,完成映射
扫描包下所有spring注解
-->
******************************************************************************
@Controller //标记为控制器
public class MyAnnotationController {
@RequestMapping(value="/welcome2") //标记请求映射的方法
public String hello(){
System.out.println("AnnotationController");
return "welcome";
}
}
//DefaultAnnotationHandlerMapping
将请求映射给使用 RequestMapping注解的控制器和控制方法
ModelAndView----->
@Controller
@RequestMapping(value="user/")
public class MyController {
// @RequestMapping(value="/hello")
// public String handleRequestInternal(HttpServletRequest request) {
// List<User> userList=new ArrayList<User>();
// userList.add(new User("王","111","mgr1"));
// userList.add(new User("刘","222","mgr2"));
// userList.add(new User("张","333","mgr3"));
// request.setAttribute("userList", userList);
//
// return "welcome";
// }
@RequestMapping(value="/list",method=RequestMethod.GET)
public ModelAndView handleRequestInternal(HttpServletRequest request) {
Map<String,User> userList=new HashMap<String, User>();
userList.put("1", new User("王","111","mgr1"));
userList.put("2", new User("刘","222","mgr2"));
userList.put("3", new User("张","333","mgr3"));
System.out.println("success!");
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("userList", userList);
modelAndView.setViewName("userList");
return modelAndView;
}
}
//<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>
<context:component-scan base-package="com.pp"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/user/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
http://localhost:8090/SpringMVC2/user/list
==================================================
jsr303 服务器端验证
model:
@NotEmpty(message="用户名不能为空")
@Size(max=10,min=5,message="长度在5-10位")
@Email(message="输入正确的邮箱格式")
controller:
@RequestMapping(value="/add",method=RequestMethod.POST)
public String hello2(@Validated User users,BindingResult bindingResult){
if(bindingResult.hasErrors())
return "user/adduser";
userList.put(users.getUid(), users);
return "redirect:userlist";
}
jsp:打印错误信息
<form:errors path="uname"/>
跳到目标详情信息====================================
@RequestMapping(value="/view/{id}/{id2}",method=RequestMethod.GET)
public String userView(@PathVariable(value="id") String id,@PathVariable(value="id2") String id2,Model model){
model.addAttribute(userList.get(Integer.valueOf(id)));
System.out.println(id2);
return "user/view";
}
1.注解的value值里参数是{},不是${EL表达式}
2.从页面的a标签传入的参数是string类型,map的key是Integer,要记得转换
3.参数注解PathVariable取地址里的参数
4.页面参数的注解是RequestParam
********************
关于控制器的返回路径问题
配置文件中:
<property name="prefix" value="/WEB-INF/jsp/"></property> 前缀
<property name="suffix" value=".jsp"></property> 后缀
return "user/view" //逻辑视图名,文件名
return "redirect:/user/userlist" //重定向,从根开始算路径(定在了/jsp/),是基于页面的当前路径继续叠加
例如:
return "redirect:user/userlist"
http://localhost:8090/SpringMVC1/user/userlist 用户列表url
http://localhost:8090/SpringMVC1/user/3/user/userlist 删除第三条失败,跳转404
正确写法:return "redirect:/user/userlist"
*****************
创建一个类UserException去继承RunTimeException 有继承的构造方法
controller//抛出异常
throw new UserException("用户名或密码错误");
//把异常放进request作用域
@ExceptionHandler(value=UserException.class)
public String UserException(UserException e,HttpServletRequest httpServletRequest){
httpServletRequest.setAttribute("e", e);
return "user/error";
}
//页面从request作用域里去到报错信息打印
jsp:
<h2>${e.message }</h2>
-----------------------------------------------------------
全局异常
springMVC配置文件中引入
org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类
<property name="exceptionMappings">
<props >
<prop key="com.pp.controller.UserException">user/error</prop>
</props>
</property>
//Navigate-Open Type查找引入的类名可以看源码,得到全路径(myeclipse)
jsp:${exception.message}
-------------------------------------------------
配置静态文件资源访问 springMVC中无法直接访问静态文件 需要映射成url进行访问
<mvc:resources location="/statics/" mapping="/statics/**" />
**文件夹及其子文件夹下的文件
href="<%=request.getContextPath()%>/statics/css/main.css"
************************************************************
多文件上传 (单文件上传去掉数组和遍历就可以) 需要jar包fileupload/io
完整的spring配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<bean name="/welcome" class="com.pp.controller.MyController"/>
-->
<context:component-scan base-package="com.pp"></context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props >
<prop key="com.pp.controller.UserException">error</prop>
</props>
</property>
</bean>
<!-- 配置文件上传主要从这开始 -->
<context:component-scan base-package="org.springframework.web.fileupload" />
<!-- 配置文件上传 MultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000"></property>
</bean>
</beans>
controller中:
//单文件上传
//多文件上传
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String handleRequestInternal2(@Validated User user,
BindingResult bindingResult, @RequestParam MultipartFile attach,
HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
return "user/addUser";
}
if (!attach.isEmpty()) {
//得到上传文件的存放位置
String fileuploadpath = httpServletRequest.getSession() .getServletContext().getRealPath("/statics/upload/");
//得到项目路径+ 反斜杠自适应(window系统,linux系统 的反斜杠不一样) +系统时间(可以不加) + 原始文件名
File saveFile = new File(fileuploadpath + File.separator+ System.currentTimeMillis() +attach.getOriginalFilename());
try {
//上传文件 参数1: 需要上传目标文件的输入流 参数2: File对象
FileUtils.copyInputStreamToFile(attach.getInputStream(), saveFile);
} catch (IOException e) {
e.printStackTrace();
}
}
userList.put(user.getUid(), user);
return "redirect:list";
}
//多文件上传
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String handleRequestInternal2(@Validated User user,
BindingResult bindingResult, @RequestParam MultipartFile[] attachs,
HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
return "user/addUser";
}
for (MultipartFile attach : attachs) {
if (!attach.isEmpty()) {
String fileuploadpath = httpServletRequest.getSession()
.getServletContext().getRealPath("/statics/upload/");
File saveFile = new File(fileuploadpath + File.separator
+ System.currentTimeMillis()
+ attach.getOriginalFilename());
try {
FileUtils.copyInputStreamToFile(attach.getInputStream(),
saveFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
userList.put(user.getUid(), user);
return "redirect:list";
}
jsp页面中---------
attachs:<input type="file" name="attachs" /><br>
attachs:<input type="file" name="attachs" /><br>
attachs:<input type="file" name="attachs" /><br>
************************************************************
注解属性 param的作用
带了参数属性的 访问url后面就要带指定的参数 不然调用不到这个方法
url:http://localhost:8090/SpringMVC2/user/view/2?hh
@RequestMapping(value="/view/{id}",params="hh",method=RequestMethod.GET)
@ResponseBody
public User userView(@PathVariable String id){
return userList.get(Integer.valueOf(id));
}