处理静态资源
在SpringMVC中加载静态资源(例如js、css、图片)等会出现失败,这里就需要来处理一下这些静态资源。这里有两个servlet,一个是默认的servlet(DefaultServlet),另外一个是开发人员配置的servlet。我们需要配置使请求过来了以后先经过因此DispatcherServlet处理请求,找该请求是否有相对应的处理器,有则处理,无则交给DefaultServlet处理。只需要在SpringMVC的配置文件中加上下面的内容即可。
<!--解决静态资源的问题-->
<mvc:default-servlet-handler/>
<mvc:annotation-driven />
处理JSON
1.加入jar包
jackson-annotations-2.1.5.jar
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
2.在返回json数据的方法上加上@ResponseBody注解,就会自动将返回的数据转换成json。
@RequestMapping(value = "testJSON")
@ResponseBody
public Collection<Employee> testJSON(){
Collection<Employee> all = dao.getAll();
return all;
}
3.在jsp中进行对json数据进行处理。这里就将数据生成一个表格
$(function () {
$("#btn").click(function () {
$.ajax({
url:"testJSON",
type:"get",
dataType:"json",
success:function (data) {
var tb = "<table>";
tb += "<tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>departmentName</th></tr>";
for(var i in data){
var emp = data[i];
tb += "<tr><td>"+emp.id+"</td><td>"+emp.lastName+"</td><td>"+emp.email+"</td><td>"+emp.gender+"</td><td>"+emp.department.departmentName+"</td></tr>";
}
tb += "</table>";
$("body").append(tb);
}
})
})
});
文件下载和文件上传
文件下载
首先取到文件所在的绝对路径,然后创建一个输入流,将文件读入,这里要一次性读到所有的字节,可用available()方法来获取当前流的大小。然后指定协议头和状态,最后将ResponseEntity对象返回即可。在IDEA中文件是在web目录下的。
@RequestMapping("down")
public ResponseEntity<byte[]> down(HttpSession session) throws Exception{
String realPath = session.getServletContext().getRealPath("img");
String finalPath = realPath + File.separator + "1111.png";
FileInputStream is = new FileInputStream(finalPath);
byte[] bytes = new byte[is.available()];
is.read(bytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename=zzz.png");
HttpStatus status = HttpStatus.OK;
ResponseEntity<byte[]> entity = new ResponseEntity<>(bytes, headers, status);
return entity;
}
文件上传
1.首先创建一个上传的表单,注意要加上enctype=“multipart/form-data”
<form action="up" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile">
<input type="submit">
</form>
2.在SpringMVC的xml中配置一下文件解析
<!--处理文件上传,id必须为multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件解析的编码,与页面的一致-->
<property name="defaultEncoding" value="UTF-8"></property>
<!--设置上传文件的最大的大小-->
<property name="maxInMemorySize" value="102400"></property>
</bean>
3.实现功能,是通过MultipartResolver 来实现的,创建一个MultipartResolver 类型的参数即可,参数名要与表单中的name保持一致
@RequestMapping("up_old")
public String up_old(MultipartFile uploadFile,HttpSession session) throws IOException {
//获取文件名称
String fileName = uploadFile.getOriginalFilename();
String finalPath = session.getServletContext().getRealPath("img")+File.separator+fileName;
System.out.println(finalPath);
//获取输入流
InputStream is = uploadFile.getInputStream();
//创建一个输出流写到文件
FileOutputStream os = new FileOutputStream(finalPath);
int i = 0;
byte[] bytes = new byte[1024];
while ((i= is.read(bytes))!= -1 ){
os.write(bytes,0,i);
}
is.close();
os.close();
return "success";
}
@RequestMapping("up")
public String up(MultipartFile uploadFile,HttpSession session) throws IOException {
String fileName = uploadFile.getOriginalFilename();
String finalFileName = UUID.randomUUID()+fileName.substring(fileName.lastIndexOf("."));
String finalPath = session.getServletContext().getRealPath("img")+File.separator+finalFileName;
System.out.println(finalPath);
File file = new File(finalPath);
uploadFile.transferTo(file);
return "success";
}
拦截器
使用步骤
1.首先创建一个类,实现HandlerInterceptor接口,然后重写拦截器的三个方法。preHandle()是在代码执行之前
postHandle()是在代码执行之后,有异常不执行
afterCompletion()也是在代码执行之后,不过有没有异常都执行
@Component
public class FirstInterceptor implements HandlerInterceptor
{
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("First:preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("First:postHandle");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("First:afterCompletion");
}
}
2.在XML文件中进行配置拦截器
<mvc:interceptors>
<!--默认拦截所有请求-->
<bean class="com.glq.interceptor.FirstInterceptor"></bean>
<bean class="com.glq.interceptor.SencondInterceptor"></bean>
<!--自定义拦截方式-->
<!--<mvc:interceptor>-->
<!--<bean></bean>-->
<!--要拦截的请求-->
<!--<mvc:mapping path=""/>-->
<!--不拦截的请求-->
<!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
<!--</mvc:interceptor>-->
</mvc:interceptors>
多个拦截器的执行顺序
有多个拦截器都执行的话会有一个顺序问题,我们这里以两个拦截器为例子。这里preHandle若返回true就会继续执行,返回false就不在执行。
true true
当两个都为true的时候两个拦截器都会正常工作,执行的结果是preHandle()按照顺序执行,postHandle()、afterCompletion()按照相反的顺序执行。
false false
只有第一个的preHandle()方法会执行
false true
和false false一样,也是只有第一个的preHandle()方法会执行
true false
会执行第一个的preHandle()和afterCompletion(),还执行第二个的preHandle().
执行顺序总结
当有多个拦截器时,
* preHandle:按照拦截器数组的正向顺序执行
* postHandle:按照拦截器数组的反向顺序执行
* afterCompletion:按照拦截器数组的反向顺序执行
*
* 当多个拦截器的preHandle有不同的值时
* 第一个返回false,第二个返回false:只有第一个preHandle会执行
* 第一个返回true,第二个返回false:两个(全部)拦截器的preHandle都会执行 但是(全部)postHandle都不会执行,而afterCompletion只有第一个(返回false的拦截器之前的所有afterCompletion)会执行
* 第一个返回false,第二个返回true:只有第一个的preHandle会执行