REST风格

REST风格,第1张

什么是REST?

REST:即 Representational State Transfer。(资源)表现层状态转化。

是目前 最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便, 所以正得到越来越多网站的采用

  • 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它 可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。 可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要 获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识 别符。

  • 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层 (Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格 式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。

  • 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一 次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器 端。因此,如果客户端想要 *** 作服务器,必须通过某种手段,让服务器端发生“ 状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “ 表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示 *** 作方式的动 词:GET、POST、PUT、DELETE。

它们分别对应四种基本 *** 作:GET 用来获 取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便, 所以正得到越来越多网站的采用。

什么是REST FUL?

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

  • 需求示例: /某路径/1 HTTP GET :得到 id = 1 的 user /某路径/1 HTTP DELETE:删除 id = 1的 user /某路径 HTTP PUT :更新查询id = 1的 user,进行PUT请求更新 /某路径 HTTP POST :新增 user

http://localhost:8080/pro/user/1 GET

http://localhost:8080/pro/user/1 DELETE

http://localhost:8080/pro/user/1 PUT

http://localhost:8080/pro/user/ POST

@PathVariable

注解:映射 URL 绑定的占位符

带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的 意义

通过 @PathVariable 可以将 URL 中占位符参数绑定到控 制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到 *** 作方法的入参中。

    /**
     * REST风格
     */
   @RequestMapping("/rest/{name}/{age}")
   @ResponseBody
    public String rest(@PathVariable("name") String name, @PathVariable Integer age, Model model){
        return "hello:"+name+",age="+age;
   }
  • @PathVariable:不能省略

  • @PathVariable("name"):中“name"如果有{name}名称相同,可以省略"name"

  • 优雅的 REST 风格的资源URL 不希望带 .html 或 .do 等后缀,需将 DispatcherServlet 请求映射配置为 /,则 Spring MVC 将捕获 WEB 容器的所有请求,包括静态资源的请求, SpringMVC 会将他 们当成一个普通请求处理,因找不到对应处理器将导致错误

SpringMVC访问静态文件
    
    

mapping:将静态资源映射到指定的路径下 location:本地静态资源文件所在的目录

数据格式化
  1. 实现方式

    • 接口方式:org.springframework.format.Formatter

    • 注解方式:org.springframework.format.AnnotationFormatterFactory

  2. 内置API

    • @DateTimeFormat

    • @NumberFormat

  3. 全局注册

    • Java configuration

    • XML-based configuration


        
        
            
                
                
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    
  1. 日期默认情况下转换失败

HTTP Status 400 – Bad Request

异常处理器

springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

public class CustomException extends RuntimeException {
​
    /** serialVersionUID*/
    private static final long serialVersionUID = -5212079010855161498L;
    
    public CustomException(String message){
        super(message);
        this.message = message;
    }
​
    //异常信息
    private String message;
​
    public String getMessage() {
        return message;
    }
​
    public void setMessage(String message) {
        this.message = message;
    }
}

根据项目需求 创建多种异常,但一般继承RuntimeException

自定义异常处理器
public class CustomExceptionResolver implements HandlerExceptionResolver {
​
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
​
        ex.printStackTrace();
​
        CustomException customException = null;
        
        //如果抛出的是系统自定义异常则直接转换
        if(ex instanceof CustomException){
            customException = (CustomException)ex;
        }else{
            //如果抛出的不是系统自定义异常则重新构造一个未知错误异常。
            customException = new CustomException("未知错误,请与系统管理 员联系!");
        }
        
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", customException.getMessage());
        modelAndView.setViewName("error");
​
        return modelAndView;
    }
​
}
错误页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> 




错误页面
​


您的 *** 作出现错误如下:
${message } ​ ​
异常处理器配置

在springmvc.xml中添加:


handlerExceptionResolver名称不能更名,同multipartResolver

异常测试

修改商品信息,id输入错误提示商品信息不存在。

修改controller方法“editItem”,调用service查询商品信息,如果商品信息为空则抛出异常:

		// 调用service查询商品信息
		Items item = itemService.findItemById(id);
		
		if(item == null){
			throw new CustomException("商品信息不存在!");
		}

请自行实现在service、dao中跑出异常。

json数据交互 @RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json

@ResponseBody

作用:

该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

  1. 在WebMvcConfigurationSupport中的addDefaultHttpMessageConverters添加默认实现

  2. HttpMessageConvert负责将一个请求信息转换为一个对象(类型为T),将对象(类型为T)转换为响应信息。DispatcherServlet默认安装了AnnotationMethodHandlerAdapter做为HandlerAdapter的组件实现类,HttpMessageConverter即由AnnotationMethodHandlerAdapter使用,将请求信息转换成对象,或将对象转换成响应信息

  3. 参数解析

    1. InvocableHandlerMethod

      • 在HandlerAdapter执行目标方法之前,需要调用resolveArgument() 依次解析出每个入参对象,然后才会执行目标方法

    2. HandlerMethodArgumentResolverComposite

      • 在resolveArgument()内部,首先调用getArgumentResolver() 获得能解析当前入参的HandlerMethodArgumentResolver解析器,然后调用这个解析器的resolveArgument() 获得一个入参对象。

      • getArgumentResolver() 会返回什么类型的HandlerMethodArgumentResolver,这与入参类型和入参上的注解有关,Spring MVC默认注册了以下方法参数解析器:

      • 有一些解析器是调用binder.convertIfNecessary(),使用绑定器的ConversionService内部适当的Converter进行类型转换,通常是字符串转入参对象(因为是超文本协议嘛),比如PathVariableMethodArgumentResolver、RequestParamMethodArgumentResolver等。

      • 有一些解析器是调用readWithMessageConverters(),使用适当的HttpMessageConverter将HTTP请求转换为入参对象,比如RequestResponseBodyMethodProcessor、HttpEntityMethodProcessor等。

响应json实现: 环境准备

Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入fastjson的包,如下:



    com.alibaba
    fastjson
    1.2.47


    com.fasterxml.jackson.core
    jackson-databind
    2.11.4

乱码
  • 方式一:

    • produces="application/json; charset=utf-8"

 	/**
     * 新增用户
     */
    @PostMapping(produces="application/json; charset=utf-8")
    public String add(@RequestBody SysUser sysUser){
        return "新增用户";
    }
  • 方式二:


        
            
                
            
            
                
                    
                        
                    
                
            
        
    

响应类
public class AjaxResult {
    private boolean success = true;
    private String msg="";

    public boolean getSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
controller方式一
@Controller
@RequestMapping("/demo4")
public class JsonController {
    /**
     * 前端通过ajax请求checkUserName方法,判断此用户名是否存在
     * @ResponseBody:将当前方法,以Ajax方式响应客户端
     */
    @ResponseBody
    @RequestMapping("/checkUserName")
    public AjaxResult checkUserName(){
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.setMsg("");
        return ajaxResult;
    }
}

@ResponseBody将当前方法,以Ajax方式响应客户端

controller方式二
@RestController
@RequestMapping("/demo4")
public class JsonController2 {
    /**
     * 前端通过ajax请求checkUserName方法,判断此用户名是否存在
     */
    @RequestMapping("/checkUserName2")
    public AjaxResult checkUserName(){
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.setMsg("");
        return ajaxResult;
    }
}

@RestController将Controller中的所有方法以Ajax方法响应

ajax请求
	$.ajax({
			type:"GET",//请求类型
			url:path+"/jsp/user.do",//请求的url
			data:{method:"ucexist",userCode:userCode.val()},//请求参数
			dataType:"json",//ajax接口(请求url)返回的数据类型
			success:function(data){//data:返回数据(json对象)
				if(data.userCode == "exist"){//账号已存在,错误提示
					validateTip(userCode.next(),{"color":"red"},imgNo+ " 该用户账号已存在",false);
				}else{//账号可用,正确提示
					validateTip(userCode.next(),{"color":"green"},imgYes+" 该账号可以使用",true);
				}
			},
			error:function(data){//当访问时候,404,500 等非200的错误状态码
				validateTip(userCode.next(),{"color":"red"},imgNo+" 您访问的页面不存在",false);
			}
		});

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


登录名:

密码:

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/729282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存