17.当出现遍历的情况我们就是用JSTL标签
当我们使用下拉菜单及单选按钮、多选按钮的时候我们就使用springmvc提供的表单标签,在表单标签中的path属性值相当于我们原生HTML中的name属性值!
18.对于静态资源文件如【js/css/图片】的访问我们需要在spingmvc配置文件中配置一个标签,如下所示:
<!-- 1.可以映射静态资源的访问请求 --><mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
此时可以在浏览器地址栏中直接访问js文件地址来测试js是否可用
19. <form:select>和<form:radiobuttons>会自动根据path和item的值以及modelAttribute传入的对象,为选框赋予默认值
20.EmployeeCRUD:
SpringMVC处理静态资源【导入js文件】:1.为什么出现这样的问题:
优雅的REST风格的资源URL不希望带.html或.do等后缀,若将DispatcherServlet请求映射配置为/,
则SpringMVC将捕获WEB容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通请求处理,因此找不到对应处理器将导致错误。
2.解决:在SpringMVC的配置文件中配置<mvc:default-servlet-handler>
例:Rest风格提交delete请求
后端设置RequesMethod为DELETE不再赘述
前端:
写一个form表单用来提交REST风格请求,此处将form的method设置为delete
<form action="" method="POST">
<input type="hidden" name="_method" value="delete">
</form>
注意:在web.xml中需要配置HiddenHttpMethodFilter
此处给所要提交的<a>标签的class设为"del"
导入jquery包并编写函数,注意导入jquery包的的<script>标签中写的函数是无效的!
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$(".del").click(function(){
var url=$(this).attr("href");
$("form").attr("action",url).submit();
return false;
});
});
</script>
return false是为了不让<a>标签以自己的get方式提交。
21. 当需要表单回显或者使用下拉列表的时候,就使用form表单标签,而如果使用遍历的标签就使用JSTL标签【导包】!
重申:path为name,items为所要遍历的集合对象,itemLabel为文本值,itemValue为value,这两个可以不写,自动根据集合的映射生成!
22.视图和视图解析器
请求处理方法执行完成后,最终返回一个 ModelAndView 对象。对于那些返回 String,View 或 ModeMap 等类型的处理方法,SpringMVC 也会在内部将它们装配成一个 ModelAndView 对象,它包含了逻辑名和模型对象的视图Spring MVC 借助视图解析器(ViewResolver)得到最终 的视图对象(View),最终的视图可以是 JSP ,也可能是Excel、JFreeChart等各种表现形式的视图
视图
视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。
视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全的问题。
自定义视图
1.自定义视图,实现view接口或者继承AbstractView抽象类,并加入到IOC容器中。
@Component
public class AView extends AbstractView{
@Override
protected void renderMergedOutputModel(Map<String, Object> arg0, HttpServletRequest request, HttpServletResponse response)
throws Exception {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf8");
System.out.println("render执行了");
response.getWriter().print("Hello View");
}
}
@Component和@Controller都可将组件注入IOC容器,@Component主要注释于一个组件,@Controller注释于Control层,@Controller是一个特殊的@Component
2.在springmvc配置文件中配置BeanNameViewResolver视图解析器。
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
order表示解析顺序的权重,value越小越先执行
23. 数据格式化标签:
1.在SpringMVC配置文件中配置<mvc:annotation-driven/>
2.在目标POJO对象的属性上加上@NumberFormat 或者 @DateTimeFormat 注解!
@DateTimeFormat
– pattern 属性:类型为字符串。指定解析/格式化字段数据的模式, 如:”yyyy-MM-dd hh:mm:ss”
@NumberFormat
–pattern:类型为 String,自定义样式, 如patter="#,###";
24.数据类型转换以及数据格式化标签:
数据类型转换【了解】
1. 自定义类型转换器实现Converter<S,T>接口并加入到SpringMVC的IOC容器中,
@Component
public class MyConvert implements Converter<String, Student>{
@Override
public Student convert(String source) {
// TODO Auto-generated method stub
System.out.println("convert执行了");
if (source != null) {
String[] stu = source.split("-");
if (stu.length==1) {
String name=stu[0];
Student student = new Student();
student.setName(name);
return student;
}else if (stu.length==2) {
String name=stu[0];
Integer gender=Integer.parseInt(stu[1]);
Student student = new Student();
student.setName(name);
student.setGender(gender);
return student;
}else if (stu.length==3) {
String name=stu[0];
Integer gender=Integer.parseInt(stu[1]);
SimpleDateFormat sd=new SimpleDateFormat("yyyy年MM月dd日");
Date birth=null;
try {
birth=sd.parse(stu[2]);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Student student = new Student();
student.setName(name);
student.setGender(gender);
student.setBirth(birth);
return student;
}
}
return null;
}
}
此处我的converter为前端传入一个"姓名-年龄-生日"格式的String对象,并直接转换为一个具有姓名、年龄、生日三个属性的Student对象
2.配置自定义转换器到FormattingConversionServiceFactoryBean工厂中!
<!-- 将ConversionService再作为annotation-driven的一个属性存在! -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置ConversionService -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="myConvert"/>
</set>
</property>
</bean>
之后Controller中可直接使用POJO获得前端以String形式传入的Student对象
25.SpringMVC如何处理JSON数据?
1.加入json的3个jar包jackson-annotations-2.1.5.jar
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
2. 编写目标方法,使其返回 JSON 对应的对象或集合
3. 在方法上添加 @ResponseBody 注解
例:
Control层返回一个List<Student>对象
@RequestMapping(value="/testJson",method=RequestMethod.POST)
@ResponseBody
public List<Student> testJson() {
List<Student> students=new ArrayList<Student>();
students.add(new Student("test1", 1, new Date(1989, 6, 4)));
students.add(new Student("test2", 0, new Date(1995, 11, 2)));
students.add(new Student("test3", 1, new Date(1997, 7, 1)));
System.out.println(students);
return students;
}
此处仅在函数前增加了@ResponseBody注释
在前端使用ajax进行测试
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.min.js"></script>
<script>
$(function() {
$("#btn1").click(function(){
var url="${pageContext.request.contextPath}/testJson";
var data={};
function callback(data1){
for(var i=0;i<data1.length;i++){
alert(data1[i].name);
}
}
$.post(url,data,callback);
})
});
</script>
26.文件上传
Spring MVC 上下文中默认没有为文件上传提供了直接的支持,因 此默认情况下不能处理文件的上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置
CommonsMultipartResovler:
1.加入jar包:
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
2.在SpringMVC配置文件中配置CommonsMultipartResovler
<!-- 配置CommonsMultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<!-- 以字节为单位 -->
<property name="maxUploadSize" value="10240000"></property>
</bean>
注意:此处的CommonsMultipartResolver的bean中必须配置id名!
2.表单:POST请求,file类型, enctype="multipart/form-data"
Controller:
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest request, @RequestParam(value="desc")String desc,@RequestParam(value="photo")CommonsMultipartFile file) {
ServletContext servletContext = request.getServletContext();
String realPath = servletContext.getRealPath("/image");
File file1 = new File(realPath);
if (!file1.exists()) {
file1.mkdirs();
}
OutputStream out = null;
InputStream input = null;
String prefix = UUID.randomUUID().toString();
prefix = prefix.replace("-", "");
String filename=prefix+"_"+file.getOriginalFilename();
System.out.println(filename);
try {
out=new FileOutputStream(new File(realPath+"/"+filename));
input=file.getInputStream();
IOUtils.copy(input, out);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
out.close();
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "success";
}
传入的<input type="file" name="photo">在controller中接收是,@Requestparam注释的对象类名为CommonsMultipartFile
不使用IOUtils,使用原生字节流:
out=new FileOutputStream(new File(realPath+"/"+filename)); input=file.getInputStream(); //IOUtils.copy(input, out); byte[]buffer=new byte[1024]; while(input.read(buffer)!=-1) { out.write(buffer); out.flush(); }
3.用ResponseEntity<byte[]> 返回值完成文件下载:
@RequestMapping(value="/testDownload") public ResponseEntity<byte[]> testDownload(HttpServletRequest request)throws Exception{ ServletContext servletContext = request.getServletContext(); String fileName="HelloFile.mp3"; String realPath = servletContext.getRealPath("WEB-INF/"+fileName); InputStream input=new FileInputStream(realPath); byte[]body=new byte[input.available()]; input.read(body); HttpHeaders headers=new HttpHeaders(); fileName=new String(fileName.getBytes("gbk"), "iso8859-1"); headers.add("Content-Disposition","attachment;filename="+fileName); HttpStatus statusCode = HttpStatus.OK; ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(body, headers, statusCode); return responseEntity; }