聚类分析聚类分析12-10 14:06

SpringMVC高级应用

内容

1.SpringMVC之RESTful风格编程
2.SpringMVC之静态资源处理
3.SpringMVC之JSON数据处理
4.SpringMVC之异常处理
5.SpringMVC之拦截器
6.SpringMVC之文件上传
7.SpringMVC之文件下载

一.RESTful风格编程

1.RESTful概念

REST:即Representational State Transfer , (资源)表现层状态转化,是目前最流行的一种互联网软件架构。它结构清晰、符合标注、易于理解、方便扩展,所以越来越多的网站采用!
具体说,就是HTTP协议里面,四个表示操作方式的动词:GET POST PUT DELETE
它们分别代表着四种基本操作(一般放在请求头中):
1.GET用来获取资源
2.POST用来创建新资源
3.PUT用来更新资源
4.DELETE用来删除资源
另外,RESTful对URL链接也有要求:
URL链接上不能出现动词,也不能出现除了/和名词之外的其他字符,如.?&=都不允许出现!
所以,一个符合标准RESTful风格的url如下:
http://localhost:8080/工程名/资源位置/参数1/参数2/

2. Spring中实现RESTful风格

spring中使用该HiddenHttpMethodFilter过滤器实现RESTful风格!
原因:
浏览器form表单只支持GET和POST,不支持DELETE和PUT请求,Spring添加了一个过滤器,可以将这些请求转换为标准的http方法,支持GET,POST,DELETE,PUT请求!

3.实现步骤(get方式)

1.DispatcherServlet的拦截路径使用/表示。
2.组织符合RESTful风格的url链接
3.在Controller的方法上使用注解@PathVariable注解来标注参数

4.代码

<!--DispatcherServlet的拦截路径使用/表示-->
?
<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:springmvc.xml</param-value>
 </init-param>
 </servlet>
 <servlet-mapping>
 <servlet-name>DispatcherServlet</servlet-name>
 <url-pattern>/</url-pattern>
 </servlet-mapping>
@Controller
@RequestMapping("/rest")
public class RestController {
?
 //@PathVariable作用:把路径变量和方法形参进行绑定
 @RequestMapping(value="/test1/{id}/{username}",method=RequestMethod.GET)
 public String doRest(@PathVariable("id")int id,@PathVariable("username")String username){
 
 System.out.println(id+","+username);
 
 return "index";
 }
}
//符合RESTful风格的url请求(发送的是get请求):
http://localhost:8080/day13_springmvc/rest/test1/1/admin

5.实现步骤(post方式)

1.在web.xml文件配置过滤器
 <filter>
 <filter-name>HiddenHttpMethodFilter</filter-name>
 <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>HiddenHttpMethodFilter</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping> 
2.使用表单,且表单的method="post"发送http请求
?
3.在表单中必须有隐藏域:
 <input type="hidden" name="_method" value="GET|POST|PUT|DELETE"></input>

6.代码

支持四个动词(get|put|post|delete)的Rest编程

@Controller
@RequestMapping("/rest2")
public class RestController2 {
 
 @RequestMapping("/torest")
 public String toRest(){
 
 return "rest";
 }
 
 // 查寻
 @RequestMapping(method = RequestMethod.GET)
 public String doGet(int id) {
?
 System.out.println("get");
 System.out.println(id);
?
 return "index";
 }
 // 增
 @RequestMapping(method = RequestMethod.POST)
 public String doPost(int id, String username) {
?
 System.out.println("post");
 System.out.println(id + "," + username);
?
 return "index";
 }
 // 删
 @RequestMapping(method = RequestMethod.DELETE)
 public String doDelete(int id) {
?
 System.out.println("delete");
 System.out.println(id);
?
 return "index";
 }
?
 // 改
 @RequestMapping(method = RequestMethod.PUT)
 public String doDelete(int id, String username) {
?
 System.out.println("put");
 System.out.println(id + "," + username);
?
 return "index";
 }
}
?
<!-- get请求 -->
<form action="${pageContext.request.contextPath}/rest2" method="post">
 ID:<input type="text" name="id" >
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="GET"></input>
 
 <input type="submit" value="get">
</form>
?
<!-- post请求 -->
<form action="${pageContext.request.contextPath}/rest2" method="post">
 ID:<input type="text" name="id" >
 USRNAME:<input type="text" name="username" >
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="POST"></input>
 <input type="submit" value="post">
</form>
?
<!-- put请求 -->
<form action="${pageContext.request.contextPath}/rest2" method="post">
 ID:<input type="text" name="id" >
 USRNAME:<input type="text" name="username" >
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="PUT"></input>
 
 <input type="submit" value="put">
</form>
?
<!-- delete请求 -->
<form action="${pageContext.request.contextPath}/rest2" method="post">
 ID:<input type="text" name="id" >
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="DELETE"></input>
 
 <input type="submit" value="delete">
</form>

支持四个动词(get|put|post|delete),

且支持标准的URL传参的Rest编程。

@Controller
@RequestMapping("/rest3")
public class RestController3 {
 
 @RequestMapping("/torest2")
 public String toRest(){
 
 return "rest2";
 }
 
?
 // 查寻
 @RequestMapping(value="/{id}",method = RequestMethod.GET)
 public String doGet(@PathVariable("id")int id) {
?
 System.out.println("get");
 System.out.println(id);
?
 return "index";
 }
?
 // 增
 @RequestMapping(value="/{id}/{username}",method = RequestMethod.POST)
 public String doPost(@PathVariable("id")int id, @PathVariable("username")String username) {
?
 System.out.println("post");
 System.out.println(id + "," + username);
?
 return "index";
 }
?
 // 删
 @RequestMapping(value="/{id}",method = RequestMethod.DELETE)
 public String doDelete(@PathVariable("id")int id) {
?
 System.out.println("delete");
 System.out.println(id);
?
 return "index";
 }
?
 // 改
 @RequestMapping(value="/{id}/{username}",method = RequestMethod.PUT)
 public String doDelete(@PathVariable("id")int id, @PathVariable("username")String username) {
?
 System.out.println("put");
 System.out.println(id + "," + username);
?
 return "index";
 }
}
?
<!-- get请求 -->
<a href="javascript:void(0)" onclick="doGet()">get</a>
<form action="#" method="post" id="formget">
 ID:<input type="text" name="id" id="id1">
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="GET"></input>
</form>
?
<!-- post请求 -->
<a href="javascript:void(0)" onclick="doPost()">post</a>
<form action="#" method="post" id="formpost">
 ID:<input type="text" name="id" id="id2" >
 USRNAME:<input type="text" name="username" id="name2">
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="POST"></input>
</form>
?
<!-- put请求 -->
<a href="javascript:void(0)" onclick="doPut()">put</a>
<form action="#" method="post" id="formput">
 ID:<input type="text" name="id" id="id3">
 USRNAME:<input type="text" name="username" id="name3">
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="PUT"></input>
</form>
?
<!-- delete请求 -->
<a href="javascript:void(0)" onclick="doDelete()">delete</a>
<form action="#" method="post" id="formdelete">
 ID:<input type="text" name="id" id="id4">
 <!--隐藏域的name必须为_method-->
 <input type="hidden" name="_method" value="DELETE"></input>
</form>
?
<script type="text/javascript">
?
 //查
 function doGet(){
 
 var form = document.getElementById("formget");
 
 var id = document.getElementById("id1").value;
 
 form.action="${pageContext.request.contextPath}/rest3/"+id;
 
 form.submit();
 }
 
 //增
 function doPost(){
 
 var form = document.getElementById("formpost");
 
 var id = document.getElementById("id2").value;
 
 var name = document.getElementById("name2").value;
 
 form.action="${pageContext.request.contextPath}/rest3/"+id+"/"+name;
 
 form.submit();
 }
 
 //改
 function doPut(){
 
 var form = document.getElementById("formput");
 
 var id = document.getElementById("id3").value;
 
 var name = document.getElementById("name3").value;
 
 form.action="${pageContext.request.contextPath}/rest3/"+id+"/"+name;
 
 form.submit();
 }
 
 //删
 function doDelete(){
 
 var form = document.getElementById("formdelete");
 
 var id = document.getElementById("id4").value;
 
 form.action="${pageContext.request.contextPath}/rest3/"+id;
 
 form.submit();
 }
?
</script>

二.静态资源处理

当DispatcherServlet使用/来匹配URL时,会拦截静态资源,我们可以在Springmvc.xml配置<mvc:resources>来做相应处理。
<!-- 静态资源处理 :location匹配url中现的字符,mapping表示直接映射到相应文件夹下的资源-->
 <mvc:resources location="/static/" mapping="/static/**"></mvc:resources>
 <mvc:resources location="/imgs/" mapping="/imgs/**"></mvc:resources>
 <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
 <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>

三.数据回显

Springmvc对在控制器方法形参绑定pojo类型,默认会把该pojo对像放在request域中,其key为该Pojo类型类名的小写。
 @RequestMapping("/login.do")
 public String doLogin(User u){
 //springmvc默认会执行下面操作:key为User类名的小写
 //model.addAttribute("user", u);
 return "login";
 }
<form action="${pageContext.request.contextPath}/user/login.do" method="post">
?
 用户名:<input type="text" name="username" value="${user.username}">
 <br>
 密码:<input type="password" name="password" value="${user.password}">
 <br>
 <input type="submit" value="登录">
</form>

四.JSON数据处理

springmvc进行json数据处理时,需要依赖外部插件包。
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>2.8.9</version>
</dependency>
?
也可以引入下面包:
<dependency>
 <groupId>com.google.code.gson</groupId>
 <artifactId>gson</artifactId>
 <version>2.2.4</version>
</dependency>

1.jsp页面

<a href="javascript:void(0)" onclick="doAjax()">发送AJAX</a>
?
<script type="text/javascript">
?
 function doAjax(){
 
 //页面向控制器传递数据,可以是查询字符串,也可是json对像
 var queryStr = "username=jack&password=1234";
 
 var jsonObj = {"username":"jack","password":"1234"}
 
 $.ajax({
 data:jsonObj,
 dataType:"json",
 type:"post",
 //url:"${pageContext.request.contextPath}/json/dojson.do",
 //url:"${pageContext.request.contextPath}/json/dojson2.do",
 url:"${pageContext.request.contextPath}/json/dojson3.do",
 success:function(rec){
 
 alert(rec.username+","+rec.password);
 }
 });
 
 }
?
</script>

2.后端代码

@Controller
@RequestMapping("/json")
public class JsonController {
?
 
 @RequestMapping("/tojson.do")
 public String toJson(){
 
 return "json";
 }
 
 //返回servlet编程json数据处理方式
 @RequestMapping("/dojson.do")
 public void doJson(User user,HttpServletResponse response) throws IOException{
 
 //前端json数据到后端java对像转化
 System.out.println(user.getUsername()+","+user.getPassword());
 
 //可以向js中写入普通字符串,也可以是json格式字符串:
 PrintWriter out = response.getWriter();
 //js中的接收数据类型为text
 //out.print("ok");
 
 //js中可以用json类型接收,则会把json字符串转换为json对像
 out.print("{\"mess\":\"ok\"}");
 }
 
 
 /*
 * 返回值为String,必须使用@ResponseBody注解时行标注
 * 其作用:说明返回值不是逻辑视图名,而是数据(可以是字符串,也可以json格式字符串)
 */
 @RequestMapping("/dojson2.do")
 @ResponseBody
 public String doJson2(User user){
 
 System.out.println(user.getUsername()+","+user.getPassword());
 
 //return "ok";
 
 return "{\"mess\":\"ok\"}";
 }
 
 /*
 * 返回值为复杂的引用类型,如java中对像,集合数据等,必须使用@ResponseBody注解时行标注
 * 其作用:1.说明返回值不是逻辑视图名,而是数据
 * 2.会把java对像转化为json格式的字符串
 */
 @RequestMapping("/dojson3.do")
 public @ResponseBody User doJson3(User user){
 
 //@ResponseBody可以把java对像转化为json字符串
 return user;
 }
 
}

五.异常处理

SpringMVC通过HandlerExceptionResolver的实现类进行异常的统一处理:
1.DefaultHandlerExceptionResolver(默认被始用)
2.SimpleMappingExceptionResolver
3.AnnotationMethodHandlerExceptionResolver(默认被始用)
4.ResponseStatusExceptionResolver(默认被始用)

1.DefaultHandlerExceptionResolver进行异常处理

只需要在web.xml配置异常映射即可:
<error-page>
 <error>404</error>
 <location>/WEB-INF/jsp/404.jsp</location>
</error-page>
?
<error-page>
 <error>500</error>
 <location>/WEB-INF/jsp/500.jsp</location>
</error-page>

2.AnnotationMethodHandlerExceptionResolver进行异常处理

支持@ExceptionHandler
 1.该注解标注在控制器的方法上
 局部异常处理:只会对该控制器的所有方法发生的异常进行处理,对别的控制器发生的异常不会处理
 2.可以标注在普通的异常处理类的相应方法上
 全局异常处理:对所有控制器内部的方法产生的异常都会做统一处理。

2.1局部异常处理

@Controller
@RequestMapping("/exce")
public class ExceptionController {
?
 @RequestMapping("/test.do")
 public String doBiz(){
 
 System.out.println(1/0);
 
 return "index";
 }
 
 //只对该控制器中方法抛出的异常进行统一处理。
 @ExceptionHandler
 public String HandlerException(Exception e){
 
 e.printStackTrace();
 
 return "500";//逻辑视图名
 }
}

2.2全局异常处理

//自定义类来处理全局异常,一般该类使用@ControllerAdvice来标注

?

/**

* 自定义全局异常处理组件

* @author Administrator

*/

@ControllerAdvice

public class ExceHandler {

?

@ExceptionHandler

public String HandlerException(Exception e){

e.printStackTrace();

?

return "100";//逻辑视图名

}

}

?

如果有全局异常处理器和局部异常处理方法同时对同一异常进行处理,则优先级如下:

局部异常处理>全局异常处理

程序之家二维码

小额赞赏

000
评论