Spring之路(25)–Spring Restful+jQuery+Bootstrap开发博客系统实例(API后端开发篇)
2020/2/8 8:05:26
本文主要是介绍Spring之路(25)–Spring Restful+jQuery+Bootstrap开发博客系统实例(API后端开发篇),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
本篇将之前实现过的博客系统的后端api改为Spring Restful风格,虽然说是修改,但实际上还是从头到尾实现一下子。
新建项目
打开eclipse,File-New-Other-Dynamic Web Project。
Project name:restfulblog
勾选Generate web.xml deployment descriptor
导入jar包
将之前一直在用的jar包拷贝到WEB-INF/lib目录下。
注意Spring Restful请求都是返回json字符串,所以需要添加转换json的jar包,同时因为要访问数据库,所以添加mysql数据链接的jar包:
后续不再逐一提供jar包下载地址,给大家一个可以搜索的jar包仓库,自行下载吧:https://mvnrepository.com/。
修改web.xml加载spring配置
修改web.xml如下,该配置文件配置了DispatcherServlet,同时指定了容器使用的配置文件springmvc-config.xml。
注意<url-pattern>/*</url-pattern>
表示匹配所有请求,此时不再限制请求路径以.do
结尾,因为跟restful风格不符合了。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>restfulblog</display-name> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
新建springmvc-config.xml,配置容器信息
在WEB/INF下新建springmvc-config.xml,添加对容器的配置,主要是开启bean自动扫描。另外开启了新的注解<mvc:annotation-driven />
为MVC提供额外的支持。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 指定扫描的包 --> <context:component-scan base-package="org.maoge.restfulblog" /> <!--注解驱动,开启通过注解配置访问路径与方法的匹配 --> <mvc:annotation-driven /> </beans>
添加数据库操作类DbHelper
注意此处我们还是使用myblog数据库,不再新建数据库了,所以url依然为jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8
然后注意我们将@Component
改为了@Repository
,@Repository
也是将DbHelper注册为bean,但是它用于持久层上,更加能表明bean的类型,一般跟持久层相关的bean使用@Repository
。OK,代码如下:
package org.maoge.restfulblog; import java.sql.Connection; import java.sql.DriverManager; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; //@Component @Repository//替代@Component public class DbHelper { @Value("com.mysql.jdbc.Driver") // 注入driver属性 private String driver; @Value("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8") // 注入数据库url属性 private String url; @Value("root") // 注入用户名属性 private String username; @Value("XXX") // 注入密码属性 private String password; /** * 初始化 */ @PostConstruct // 使用该注解,以便在项目启动时执行数据库驱动加载工作 public void init() { try { Class.forName(driver); } catch (Exception e) { // 此处应打印日志 } } /** * 获取数据库连接 */ public Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { // 此处应打印日志 } return conn; } /** * 关闭数据库连接 */ public void closeConnection(Connection conn) { if(conn!=null) { try { conn.close(); }catch(Exception e) { // 此处应打印日志 } } } }
添加博客服务类BlogService与数据对象BlogBo
注意博客服务类的注解,我们将@Component
改为了@Service
,这个道理同上,@Service
用来描述服务层(业务层)的bean。具体代码如下:
package org.maoge.restfulblog; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @theme 服务--博客 * @author maoge * @date 2020-01-27 */ //@Component @Service//替代@Component public class BlogService { @Autowired // 自动注入dbHelper组件 private DbHelper dbHelper; /** * 获取博客列表 */ public List<BlogDo> getBlogList() { List<BlogDo> blogList = new ArrayList<BlogDo>(); Connection conn = null; try { conn = dbHelper.getConnection(); String sql = "select * from blog"; PreparedStatement stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); while (rs.next()) { BlogDo blog = new BlogDo(); blogList.add(blog); blog.setAuthor(rs.getString("author")); blog.setContent(rs.getString("content")); blog.setId(rs.getLong("id")); blog.setTitle(rs.getString("title")); } } catch (Exception e) { // 此处应打印日志 } finally { dbHelper.closeConnection(conn); } return blogList; } /** * 按id获取博客信息 */ public BlogDo getBlogById(Long id) { BlogDo blog=null; Connection conn = null; try { conn = dbHelper.getConnection(); String sql = "select * from blog where id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setLong(1, id); ResultSet rs = stmt.executeQuery(); if (rs.next()) { blog=new BlogDo(); blog.setAuthor(rs.getString("author")); blog.setContent(rs.getString("content")); blog.setId(rs.getLong("id")); blog.setTitle(rs.getString("title")); } } catch (Exception e) { // 此处应打印日志 } finally { dbHelper.closeConnection(conn); } return blog; } /** * 新增博客 */ public int addBlog(BlogDo blog) { Connection conn = null; try { conn = dbHelper.getConnection(); String sql = "insert into blog(author,content,title)values(?,?,?)"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, blog.getAuthor()); stmt.setString(2, blog.getContent()); stmt.setString(3, blog.getTitle()); return stmt.executeUpdate(); } catch (Exception e) { // 此处应打印日志 return 0; } finally { dbHelper.closeConnection(conn); } } /** * 根据博客id更新博客信息 */ public int updateBlog(BlogDo blog) { Connection conn = null; try { conn = dbHelper.getConnection(); String sql = "update blog set author=?,content=?,title=? where id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, blog.getAuthor()); stmt.setString(2, blog.getContent()); stmt.setString(3, blog.getTitle()); stmt.setLong(4, blog.getId()); return stmt.executeUpdate(); } catch (Exception e) { // 此处应打印日志 return 0; } finally { dbHelper.closeConnection(conn); } } /** * 根据博客id删除对应博客 */ public int deleteBlog(Long id) { Connection conn = null; try { conn = dbHelper.getConnection(); String sql = "delete from blog where id=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setLong(1, id); return stmt.executeUpdate(); } catch (Exception e) { // 此处应打印日志 return 0; } finally { dbHelper.closeConnection(conn); } } }
BlogController实现Restful API
重点来了,之前的控制器中,我们返回的都是网页,而在Restful的风格下,我们需要返回json。
SpringMVC可以通过对方法添加@ResponseBody
注解,将返回的对象转换为json,完事了!就是这么简单,这就是极简的设计理念,完美。还可以更加简单,如果一个控制器中提供的都是Restful API方法,则可以直接将@Controller
改写为@RestController
,这样控制下所有API方法返回的对象都会被自动转换为json,比简单还简单,追求极致。
下面具体实现下,注意下注释:
package org.maoge.restfulblog; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * @theme 控制器--博客 * @author maoge * @date 2020-01-28 */ @RestController // 通过该注解,第一将BlogController注册为控制器,第二将其中方法返回值转换为json public class BlogController { @Autowired // 自动装配blogService private BlogService blogService; /** * 查询博客信息 * 1、@GetMapping表示可以使用get方法请求该api * 2、"/blog/{id}"表示请求路径为/blog/{id}的形式,其中{id}为占位符 * 3、@PathVariable("id")表示将占位符{id}的值传递给id * 4、也就是说/blog/123请求的话,会将123传递给参数id */ @GetMapping("/blog/{id}") public BlogDo getOne(@PathVariable("id") long id) { return blogService.getBlogById(id); } /** * 查询博客列表,使用get方法 */ @GetMapping("/blog") public List<BlogDo> getList(){ return blogService.getBlogList(); } /** * 新增博客 * 1、@PostMapping表示使用post方法 * 2、@RequestBody表示将请求中的json信息转换为BlogDo类型的对象信息,该转换也是由SpringMVC自动完成的 */ @PostMapping("/blog") public void add(@RequestBody BlogDo blog) { blogService.addBlog(blog); } /** * 修改博客 * 实际上此处也可以不在路径中传递id,而是整个使用json传递对象信息,但是我查询了一些文档,貌似使用路径传递id更加规范一些,此处不用纠结 */ @PutMapping("/blog/{id}") public void update(@PathVariable("id") long id,@RequestBody BlogDo blog) { //修改指定id的博客信息 blog.setId(id); blogService.updateBlog(blog); } /** * 删除博客 */ @DeleteMapping("/blog/{id}") public void delete(@PathVariable("id") long id) { blogService.deleteBlog(id); } }
浏览器简单测试
由于浏览器地址栏直接输入的请求是get类型的,所以我们可简单的从浏览器测试下查询博客信息,打开谷歌浏览器,访问http://127.0.0.1:8080/restfulblog/blog/1
,返回如下信息:
可见已成功返回json字符串。
总结
当后端可以提供规范的API,以restful风格提供服务接口,而返回值采用规范的json格式,是一个巨大的提高。
后续我们可以采用这种风格来开发web应用,前端负责界面渲染操作交互,后端提供API接口,前后端分离,更加优雅高效。
这篇关于Spring之路(25)–Spring Restful+jQuery+Bootstrap开发博客系统实例(API后端开发篇)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南