SpringMvc详解(二)

springMVC(下集)
SpringMVC 的常用注解
SpringMVC 静态资源的处理
SpringMVC 的文件上传和下载
SpringMVC 的统一异常处理
SpringMVC 的拦截器
SpringMVC 的自动校验

1.springmvc常用注解
(1)使用cookie获取页面设置的cookie值,代码示例:
构建页面进行cookie的值的设置

<head>
      <script type="text/javascript">
      //(path)必须要填写,因为JS的默认路径是当前页,如果不填,此cookie只在当前页面生效!~
          document.cookie="name=wwj;path=/"  
          document.cookie="age=32;path=/"     
      </script>
  </head>
  <body>
    <a href="testCookie">查看Cookie</a>
  </body>

后台业务代码

@Controller
public class CookieController {
	@RequestMapping("/testCookie")
	public String testCookie(@CookieValue(value = "name", required = false) String name,
			@CookieValue(value = "age", required = false) Integer age) {
		System.out.println(name + "," + age);
		return "hello";
	}
}

操作访问,先访问jsp页面进行cookie值的设置。在进行请求的访问

(2)使用@SessionAttributes将数据放入session作用域中

需要注意的是@SessionAttributes只能用在类上

常用的设置@SessionAttributes(value={“user1”, “user2”}) 会将model中属性名为user1和user2的属性添加到会话中

@SessionAttributes(value={"user"})
@Controller
public class SessionController {

    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Model model){
        model.addAttribute("user", "wwj");
        return "success";
    }
}

访问连接,分别在不用的页面进行取值

(3)使用@ModelAttribute
注释在一个普通方法(初始化数据)

//构建一个模型
public class Girl {
	private  String name;
	private  int age;
}
@Controller
public class ModelController {
    @ModelAttribute("girl")
    public Girl init(Model model){
        Girl g  = new Girl();
        g.setAge(28);
        g.setName("菲菲");
        return g;
    }
    @RequestMapping("/m1")
    public String m1(Model model) {
        System.out.println(model.containsAttribute("girl"));
        return "msg";
    }
}

直接接收restful格式并进行封装

路径请求 <a href="m2/wwj/32">restful操作</a>

接收restful
 @RequestMapping("/m2/{name}/{age}")
    public String m1(@ModelAttribute Girl girl) {
        System.out.println(girl.getName()+girl.getAge());
        return "msg";
    }

注意数据:数据被封装到modelattr中,同时也是在model中的

(4)设置请求方式 (了解)
@RequestMapping(value=”m3”,method=RequestMethod.POST)

通过method来设置http的请求方式

总结:其实不在乎注解的与多少,毕竟是属于对servlet的包装,可以假定不管使用什么方式,接收到前台所传递的参数

2.springMVC对于静态资源的处理

使用 <mvc:resources> 掌握

在这里插入图片描述
静态资源在加载的时候,被拦截了。这个时候需要我们在springmvc中标注哪些为静态资源,不受springmvc进行拦截

<mvc:resources location="/js/" mapping="/js/**"/>

location代表着webcontext容器下路径。映射所有js下面的资源为静态资源
观察浏览器资源加载列表

使用<mvc:default-servlet-handler/>(掌握)

3.SpringMVC的文件上传和下载
文件上传
构建form表单 需要设置enctype(编码格式) 为 multipart/form-data 不仅包含文本数据,还包含文件数据

<!-- 多文件上传 -->
	<form action="uploadUrl" method="post" enctype="multipart/form-data">
		<input type="file" name="filename" /> <input type="file"
			name="filename" /> <input type="submit" value="文件上传" />
	</form>

引入对应的jar包
Commons-fileupload.jar和commons-io.jar 2个包属于依赖关系翻译过来就是通用的上传与通用的读写操作

设置对应的上传数据要求在springmvc.xml中

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设置请求编码格式,必须与JSP中的pageEncoding属性一致 -->
		<property name="defaultEncoding" value="UTF-8" />
		<!-- 设置允许上传文件的最大值(2MB),单位为字节 -->
		<property name="maxUploadSize" value="2097152" />
	</bean>

处理对应上传的处理类
在这里插入图片描述

@Controller
public class UploadController {

	@RequestMapping("/uploadUrl")
	public String   handleFormUpload(@RequestParam("filename") MultipartFile[] files,HttpServletRequest  req){
		//判断文件是否存在
		if(files.length>0){
			for (MultipartFile multipartFile : files) {
				//获取上传文件的原始名字
				String originalFilename = multipartFile.getOriginalFilename();
				//一般决定于项目设计的时候所规范的路径
				String dirPath = req.getServletContext().getRealPath("/upload/");
				File filePath = new File(dirPath);
				 //如果保存文件的地址不存在,就先创建目录
                if(!filePath.exists()) {
                    filePath.mkdirs();
                }
                String newFilename = UUID.randomUUID()+"_"+originalFilename;
                try {
					multipartFile.transferTo(new File(dirPath + newFilename));
				} catch (IllegalStateException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		return null;
	}
}

注意:UUID 是 通用唯一识别码(Universally Unique Identifier),是一种软件建构的标准

在这里插入图片描述
使用ajax进行文件的上传
注意事项:

需要使用到js中一个叫做formData对象
尽量使用goole或者火狐浏览器

function testup(){
        var form = new FormData(document.getElementById("tf"));
        $.ajax({
            url:"uploadUrl1",
            type:"post",
            data:form,
            processData:false,
            contentType:false,
            success:function(data){
            		console.log(data)
                if(data=="ok"){
                    alert("上传成功")
                }else {
                    alert("上传失败")
                }
            }
        });
    }

注意:contentType 和 processData 设置为false 使其能够正确的对formdata进行处理

文件的下载
构建请求

<a href="downloadone">下载单文件</a>
	<a href="downloadmore">下载多文件</a>

构建处理类:
单文件下载

@Controller
public class DownloadController {

@RequestMapping("/downloadone")
	public ResponseEntity<byte[]> download(HttpServletRequest req) throws IOException {
		// 这个路径由数据库中取出
		String resourceName = "计划.txt";
		// 指定全路径位置
		File file = new File(req.getServletContext().getRealPath("/upload/")+resourceName);
		HttpHeaders headers = new HttpHeaders();
		// 避免出现文件名乱码
		String filename = new String(resourceName.getBytes("iso-8859-1"),"utf-8");
		//设置响应的内容   attachment 附件
		headers.setContentDispositionFormData("attachment", filename);
		// 设置响应的内容为流的方式
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED);
	}

多文件需要考虑进行打包

@RequestMapping("/downloadmore")
	public ResponseEntity<byte[]> download1s(HttpServletRequest req) throws IOException {

		//数据库中提取
		List<String> list = new ArrayList<String>();
		list.add("计划.txt");
		list.add("进度.txt");
		
		//压缩后的文件名
		String resourcesName = "test.zip";
		//压缩后的全路径
		String  pathName = req.getServletContext().getRealPath("/upload/");
		File  zipFile = new File(pathName+resourcesName);
		ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
		//读取并写入到压缩包里面
		InputStream input = null;
		for (String str : list) {
			String name = pathName+str;
			input = new FileInputStream(new File(name));  
            zipOut.putNextEntry(new ZipEntry(str));  
            int temp = 0;  
            while((temp = input.read()) != -1){  
                zipOut.write(temp);  
            }  
            input.close();
		}
		zipOut.close();
		File file = new File(pathName+resourcesName);
		HttpHeaders headers = new HttpHeaders();
		String filename = new String(resourcesName.getBytes("iso-8859-1"),"utf-8");
		headers.setContentDispositionFormData("attachment", filename);
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED);

	}

4.SpringMVC 的统一异常处理(掌握) (避免在controller中进行冗余的try catch操作)
先自定义异常

/**
 * 自定义异常
 * @author Yun
 *
 */
public class ServiceException extends RuntimeException {

	public ServiceException(String msg){
		super(msg);
	}

}

定义全局异常处理类 (需要用到@ControllerAdvice以及@ExceptionHandler(ServiceException.class))

@ControllerAdvice
public class GlobalExceptionResolver {
	   /**
     * 处理所有业务异常
     *
     * @param e 业务异常
     * @return json结果
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Girl handleOpdRuntimeException(ServiceException e) {
    		Girl g = new Girl();
    		g.setAge(18);
    		g.setName("wwj");
        return g;
    }

}

controller业务处理

@Controller
public class Econtroller {

    /**
     * 测试返回异常信息
     * @return
     */
    @RequestMapping("/exception")
    public void returnExceptionInfo() {
        if (1 != 2) {
            // 用户民错误或不存在异常
            throw new ServiceException("错误");
        }
    }
}

注意:开发中,我们在设计业务功能模块,都需要配置对应的exception处理

注解详解
@ControllerAdvice:在spring3.2中,新增,可以用于定义@ExceptionHandler、@InitBinder、
@ModelAttribute,并应用到所有的@requestMapping中。它相当于对Controller的增强,特使aop机制的事项

5.SpringMVC 拦截器 (掌握) 拦截 Interceptor
拦截器是对过滤器操作的一种升华。拦截器本身的机制也是aop进行实现

操作方式

public class MyInterceptor implements HandlerInterceptor{

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("afterCompletion");
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("postHandle");
	}

	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("preHandle");
		return true;
	}

}

配置文件

  <mvc:interceptors>
        <mvc:interceptor>
            <!-- 拦截所有的请求,这个必须写在前面,也就是写在【不拦截】的上面 -->
            <mvc:mapping path="/**" />
            <!-- 但是排除下面这些,也就是不拦截请求 -->
            <mvc:exclude-mapping path="/login.html" />
            <bean class="com.wwj.interceptor.MyInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

执行的顺序为

preHandle 在业务处理器处理请求之前被调用(如果preHandle返回false)
postHandle 在业务处理器处理请求执行完成后,生成视图之前执行
afterCompletion 完全处理完请求后被调用,可用于清理资源等

6.SpringMVC 的自动校验(了解)
引入相关的jar包
在这里插入图片描述
构建实体类 (有一些注解可以对对象的某个字段进行检验)

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

public class User {
	
	@NotNull(message="id不能为空!")
	private  int  uid;
	@NotBlank(message="用户名不能为空!")
	private  String uname;
	}

(将配置文件中拦截器代码剔除)

<form action="user1" method="post">
	<input type="text" name="uid"/>
	<input type="text" name="uname"/>
	<button>提交</button>
</form>

控制代码中通过提供的errorObj来获取验证的信息

@Controller
public class Vcontroller {
    @RequestMapping("/user1")
    @ResponseBody
    public User test(@Validated User user, BindingResult result) {
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            for (ObjectError error : errors) {
                System.out.println(error.getDefaultMessage());
            }
        }
        return user;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值