一.视图及视图解析器
1.视图是由视图解析器解析得到的。 视图解析器解析得到视图以后,视图再去处理模型数据.(将模型数据设置到request对象中.),最终通过转发的方式响应到客户端.
eg: InternalResourceViewResolver =>InternalResourceView=>转发
eg: RedirectView=>重定向
<!配置视图解析器 用于页面展示-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>前缀
<property name="suffix" value=".jsp"></property>后缀
</bean>
控制类中:
@RequestMapping(value="/testModelAndView",method=RequestMethod.GET)
public ModelAndView testModelAndView(){
System.out.println("----testModelAndView: ");
ModelAndView mv = new ModelAndView();
mv.addObject("testModelAndView","testModelAndView110");
mv.setViewName("ok");//视图页面
return mv;
}
ok页面中获取到值:
testModelAndView:${requestScope.testModelAndView}
2.工作流程:
- a.调用目标方法,得到ModelAndView对象. mav中包含视图名称以及模型数据
- b.处理结果:先通过视图名称配合视图解析器得到真正的视图.
- c.视图去处理模型数据,主要就是将模型数据设置到request对象中
- d.获取转发器,转发到页面中
3.自定义视图解析器:
- 定义一个包,包下放自定义的视图类
- 控制类中return到定义的视图类中,类名首字母小写
视图类:
@Component
public class HelloViews implements View {
@Override
public String getContentType() {
return "text/html;charset=UTF-8";
}
@Override
public void render(Map<String, ?> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
response.getWriter().write("hello myView");
response.getWriter().flush();
response.getWriter().close();
}
}
主入口:
testMySelfView:<a href="${pageContext.request.contextPath}/testMySelfView">testMySelfView</a>
控制类:
@RequestMapping(value="/testMySelfView",method=RequestMethod.GET)
public String testMySelfView(){
System.out.println("-----testMySelfView:");
return "helloViews";
}
springMVC.xml中添加配置:
<bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="50"></property>
</bean>
4.重定向: RedirectView
主入口:
testRedirect:<a href="${pageContext.request.contextPath}/testRedirect">testRedirect</a>
转入到控制类:
@RequestMapping(value="/testRedirect",method=RequestMethod.GET)
public String testRedirect(){
System.out.println("-----testRedirect:");
return "redirect:/myRedirect.jsp";//重定向到某界面
}
二.Rest风格的CRUD
1.查询
主入口:
显示所有员工信息:<a href="${pageContext.request.contextPath}/emps">show all employees</a>
控制类层:
@RequestMapping(value="/emps",method= RequestMethod.GET)
public String list(Map<String, Object> map){
map.put("employees",employeeDao.getAll());
return "list";
}
list页面:
<c:if test="${requestScope.employees==null}">
it is nothing...
</c:if>
<c:if test="${requestScope.employees!=null}">
<table border="1" cellpadding="10" cellspacing="2">
<tr>
<td>id</td>
<td>lastName</td>
<td>email</td>
<td>gender</td>
<td>department</td>
<td>edit</td>
<td>delete</td>
</tr>
<c:forEach items="${requestScope.employees}" var="employee">
<tr>
<td>${employee.id}</td>
<td>${employee.lastName}</td>
<td>${employee.email}</td>
<td>${employee.gender == 1 ? 'male':'female'}</td>
<td>${employee.department.departmentName}</td>
<td><a href="${pageContext.request.contextPath}/emp/${employee.id}">edit</a></td>
<td><a class="deleteCss" href="${pageContext.request.contextPath}/emp/${employee.id}">delete</a></td>
</tr>
</c:forEach>
</table>
</c:if>
2.新增
主入口:
add:testInput:<a href="${pageContext.request.contextPath}/emp">Input</a>
控制类层:
/**
* 跳转入新增页面
* @return
*/
@RequestMapping(value="/emp",method=RequestMethod.GET)
public String input(Map<String,Object> map){
map.put("departments",departmentDao.getDepartments());
map.put("genders",getGendersUtils());
map.put("employee",new Employee());
return "input";
}
//辅助类
public Map<String,String> getGendersUtils(){
Map<String,String> map = new HashMap<String,String>();
map.put("1","male");
map.put("0","female");
return map;
}
input页面:
<form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee">
lastName:<form:input path="lastName"/> <form:errors path="lastName"></form:errors><br>
email:<form:input path="email"/> <form:errors path="email"></form:errors><br>
gender:<form:radiobuttons path="gender" items="${requestScope.genders}"/><br>
department:<form:select path="department.id" items="${requestScope.departments}"
itemValue="id" itemLabel="departmentName"></form:select><br>
<input type="submit" value="save_commit">
</form:form>
实现增加:
//保存
@RequestMapping(value="/emp",method=RequestMethod.POST)
public String save(Employee employee){
employeeDao.save(employee);
return "redirect:/emps";//重定向到查询部分,再一次显示出全部信息包括新增的
}
3.删除
入口(点击删除):
<td><a class="deleteCss" href="${pageContext.request.contextPath}/emp/${employee.id}">delete</a></td>
写一个form,里边有隐藏域DELETE:
<form id="deleteForm" action="" method="post">
<input type="hidden" name="_method" value="DELETE">
</form>
jquery部分:
<script type="text/javascript">
$(function(){
$(".deleteCss").click(function(){
var action=$(this).attr("href");
$("#deleteForm").attr("action",action).submit();
return false;
})
})
</script>
控制类层:
//删除
@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
public String delete(@PathVariable("id") Integer id){
new ArrayList();
employeeDao.delete(id);
return "redirect:/emps";
}
springMVC.xml添加配置:
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
4.修改
<td><a href="${pageContext.request.contextPath}/emp/${employee.id}">edit</a></td>
/**
* 跳转到修改编辑页面
* @return
*/
@RequestMapping(value="/emp/{id}",method=RequestMethod.GET)
public String edit(@PathVariable("id") Integer id,Map<String,Object> map){
map.put("departments",departmentDao.getDepartments());
map.put("genders",getGendersUtils());
map.put("employee",employeeDao.get(id));
return "edit";
}
@ModelAttribute
public void getEmployeeById(@RequestParam(value = "id",required = false) Integer id,Map<String,Object> map){
if(id!=null){
map.put("employee",employeeDao.get(id));
}
}
@RequestMapping(value="/emp",method=RequestMethod.PUT)
public String update(Employee employee){
employeeDao.save(employee);
return "redirect:/emps";
}
edit.jsp页面:
<body>
<form:form action="${pageContext.request.contextPath}/emp" method="post" modelAttribute="employee">
<input type="hidden" name="_method" value="PUT">
<form:hidden path="id"></form:hidden>
email:<form:input path="email"/> <form:errors path="email"></form:errors><br>
gender:<form:radiobuttons path="gender" items="${requestScope.genders}"/><br>
department:<form:select path="department.id" items="${requestScope.departments}"
itemValue="id" itemLabel="departmentName"></form:select><br>
<input type="submit" value="update_commit">
</form:form>
</body>
三.数据绑定流程
前台到后台有一个转换的过程。清洗并验证(验证器Validator),将正确格式的数据传给后台处理
数据绑定核心部件:DataBinder
conversionService处理数据,validators同时验证,bindingResult将数据结果统一整理
四.自定义类型转换器
配置
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<ref bean="employeeConverts"></ref>引入的自定义类转换器,类名首字母小写
</list>
</property>
</bean>
</beans>
自定义类转换器:
@Component
public class EmployeeConverts implements Converter<String, Employee> {
@Override
public Employee convert(String source) {
Employee result=null;
if(source!=null){
String[] empInfos = source.split(";");
if(empInfos!=null&&empInfos.length==4){
result = new Employee();
result.setLastName(empInfos[0]);
result.setEmail(empInfos[1]);
result.setGender(Integer.parseInt(empInfos[2]));
Department department = new Department();
result.setId(Integer.parseInt(empInfos[3]));
result.setDepartment(department);
}
}
return result;
}