RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。RESTful(即Representational State Transfer的缩写)是一种开发理念,是对于http的很好的诠释。
对url进行规范,写成RESTful格式的url:
非REST的url:http://.../queryItems.action?id=001&type=T01
REST的url风格:http://..../items/001
特点:url简洁,将参数通过url传入服务端进行处理。
RESTful对http的方法进行规范,不管是删除、添加、更新,使用的url是一致的,若要进行删除,需要设置http的方法为delete,put,post等;
后台Controller方法:判断http方法,若为delete则执行删除,post执行添加等操作;
对http的contentType进行规范,请求时指定contentType,要json数据,设置成json格式的type等。
1、需要在项目中添加将结果转为json数据返回的jar包
jackson-annotations-2.8.4.jar
jackson-core-2.8.4.jar
jackson-databind-2.8.4.jar
如果不添加这3个jar包,会输出错误如下:
java.lang.IllegalArgumentException:No converter found for return value of type。
jackson-2.9.4.jar包将上述的3个jar包整合在一起。
2、springmvc前端控制器的配置
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/springmvc.xml
springmvc
/
注意:要实现RESTful风格的url则需要配置:
或者也可以在springmvc.xml配置文件中使用
1、需求:查询商品信息,返回json数据。
编写mapper和service接口以及实现类
ItemsMapper.xml
ItemsMapper.java
// 根据商品id获取商品信息
public Items selectItemsById(intid) throwsException;
ItemsService接口
/**
* @Description: 根据商品id获取商品信息
*
* @param id:使用int无法判断是否为空,所以一般使用Integer
*/
public ItemsCustom selectItemsById(Integer id) throws Exception;
ItemsServiceImpl添加接口实现
@Override
public ItemsCustom selectItemsById(Integer id) throws Exception {
Items items = itemsMapper.selectItemsById(id);
/**
* 中间对商品信息进行业务处理,返回Items的扩展类:ItemsCustom
* 例如商品类中只有生产日期,而没有是否过期的信息,可以做一定的操作得到该信息,封装到ItemsCustom,显示给用户
*/
ItemsCustom itemsCustom = new ItemsCustom();
// 将Items中的属性复制到ItemsCustom中
BeanUtils.copyProperties(items, itemsCustom);
return itemsCustom;
}
2、controller
定义一个方法:使用url模板映射,进行url映射,使用REST风格的url,能将查询商品信息的id传入controller,输出json,使用@ResponseBody将java对象输出为json至前端页面。
@Controller
public class TestController {
@Autowired
private ItemsService itemsService;
@RequestMapping("/itemsview/{id}")
public @ResponseBody ItemsCustom findItemsById(@PathVariable("id")Integer id) throws Exception {
ItemsCustom itemsCustom = itemsService.selectItemsById(id);
return itemsCustom;
}
}
"/itemsview/{id}"这里的{id}传入到(@PathVariable("id")Integer id) 的id里面。
如果有多个参数,例如增加name字段:@RequestMapping("/itemsview/{id}/{name}")
(@PathVariable("id")Integer id , @PathVariable("name") String diffname ),return itemsCustom会经过@ResponseBody注解转换为json数据格式。
3、测试,浏览器输入:
http://localhost:8080/SpringMvcMybatisOrders/itemsview/1
Java中没有将数据转换成JSON格式的jar包,所以需要依赖外部jackson包,否则会出现:java.lang.IllegalArgumentException错误。
采用RESTful架构后,必须将web.xml中控制器拦截的请求设置为‘/ ’;但是这样会产生一个问题,就是会将css,js,图片等静态资源拦截,发生404错误。
解决方案如下:
方法一:配置
springmvc配置文件中这样使用:
方法二:在springmvc配置文件中使用
当出现spring版本和java jdk版本不兼容时也会出现:java.lang.IllegalArgumentException异常。
通常来说spring3.x版本对应JDK7.0及以下版本,使用spring4.x以后版本,可以使用JDK8.0。
右击项目---> properties --->project facets : 修改JDK版本,需要将1.8降为1.7版本。
通过RequestMapping注解可以定义不同的处理器映射规则。
@RequestMapping(value="/items")或@RequestMapping("/items),value的值是数组,可以将多个url映射到同一个方法。
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
1、限定GET方法:@RequestMapping(method = RequestMethod.GET)
如果通过Post访问则报错:HTTP Status 405 - Request method 'POST' not supported。
例如:@RequestMapping(value="/editItems",method=RequestMethod.GET)
2、限定POST方法:@RequestMapping(method =RequestMethod.POST)
如果通过Post访问则报错:HTTP Status 405 - Request method 'GET' not supported。
3、GET和POST都可以:@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
@PathVariable映射 URL 绑定的占位符,带占位符的URL 是 Spring3.0 新增的功能,该功能在SpringMVC向 REST 目标挺进发展过程中具有里程碑的意义。通过@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL中的 {xxx} 占位符可以通过@PathVariable(“xxx“)绑定到操作方法的入参中。
/**
* @RequestMapping(value = "user/login/{id}/{name}/{status}") 中的 {id}/{name}/{status}
* 与 @PathVariable int id、@PathVariable Stringname、@PathVariableboolean status
* 一一对应,按名匹配。
*/
@RequestMapping(value = "user/login/{id}/{name}/{status}")
@ResponseBody
// @PathVariable注解下的数据类型均可用
public User login(@PathVariable int id, @PathVariableString name, @PathVariable boolean status) {
// 返回一个User对象响应ajax的请求
returnnew User(id, name, status);
}
@Responsebody注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用@RequestMapping 后,返回值通常解析为跳转路径,加上@Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。
作用:该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用。
@RequestBody注解则是将 HTTP 请求正文插入方法中,使用适合的HttpMessageConverter 将请求体写入某个对象。
作用:1)、该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
2)、再把HttpMessageConverter返回的对象数据绑定到controller中方法的参数上。
使用时机:
A)、GET、POST方式提时,根据requestheader Content-Type的值来判断:
application/x-www-form-urlencoded,可选(即非必须,因为这种情况的数据@RequestParam,@ModelAttribute也可以处理,当然@RequestBody也能处理);
multipart/form-data,不能处理(即使用@RequestBody不能处理这种格式的数据);
其他格式,必须(其他格式包括application/json,application/xml等。这些格式的数据,必须使用@RequestBody来处理);
B)、PUT方式提交时,根据requestheader Content-Type的值来判断:
application/x-www-form-urlencoded,必须;multipart/form-data,不能处理;其他格式,必须;
说明:request的body部分的数据编码格式由header部分的Content-Type指定。
@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中
public User login(@RequestBody User user){
// 这样就不会再被解析为跳转路径,而是直接将user对象写入 HTTP 响应正文中
return user;
}
使用@RequestParam常用于处理简单类型的绑定。当形参名称与页面提交的参数的名称不一致时就要使用这个注解。
value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报:TTP Status 400 - RequiredInteger parameter 'XXXX' is not present。
defaultValue:默认值,表示如果请求中没有同名参数时的默认值。
// 商品修改页面的展示
@RequestMapping("/editItems")
public ModelAndView editItems(@RequestParam(value = "id", required = true) Integer item_id) throws Exception {
}
形参名称为item_id,但是这里使用value="id"限定请求的参数名为id,所以页面传递参数的名必须为id。
注意:如果请求参数中没有id将跑出异常:HTTP Status 500 - RequiredInteger parameter 'item_id' is not present。这里通过required=true限定id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传id参数值。