The previous article explains the integration of Spring boot with JdbcTemplate, JPA and MyBatis to achieve access to the database. Today I will mainly share with you how to return data to the front-end through Spring boot.
In the current development process, in order to maximize the separation of the front and back ends, the backend interface usually only provides data interfaces, and the frontend obtains data from the backend through Ajax requests and renders it to the user. The most common way we use is that the backend will return a JSON string to the frontend, and the frontend parses the JSON string to generate a JavaScript object, and then process it. This article will demonstrate how Spring boot implements this model. This article will focus on how to design a Restful API and implement related APIs through Spring boot. However, in order for everyone to better understand the Restful-style API, we will first design a traditional data return interface so that everyone can understand it in comparison.
Let’s take the article list as an example to implement an interface that returns the article list, the code is as follows:
@Controller@RequestMapping("/article")public class ArticleController { @Autowired private ArticleService articleService; @RequestMapping("/list.json") @ResponseBody public List<Article> listArticles(String title, Integer pageSize, Integer pageNum) { if (pageSize == null) { pageSize = 10; } if (pageNum == null) { pageNum = 1; } int offset = (pageNum - 1) * pageSize; return articleService.getArticles(title, 1L, offset, pageSize); }}The implementation of ArticleService is very simple, which simply encapsulates the operation of ArticleMapper. You can refer to the previous article. The implementation class of ArticleService is as follows:
@Servicepublic class ArticleServiceImpl implements ArticleService { @Autowired private ArticleMapper articleMapper; @Override public Long saveArticle(@RequestBody Article article) { return articleMapper.insertArticle(article); } @Override public List<Article> getArticles(String title,Long userId,int offset,int pageSize) { Article article = new Article(); article.setTitle(title); article.setUserId(userId); return articleMapper.queryArticlesByPage(article,offset,pageSize); } @Override public Article getById(Long id) { return articleMapper.queryById(id); } @Override public void updateArticle(Article article) { article.setUpdateTime(new Date()); articleMapper.updateArticleById(article); }}Run the Application.java class, and then visit: http://locahost:8080/article/list.json, you can see the following results:
ArticleServiceImpl is a very ordinary class, with only one Spring annotation @Service, identified as a bean for easy management through Spring IoC containers. Let’s take a look at the ArticleController class. In fact, those who have used Spring MVC should be familiar with these annotations. Here is a brief explanation:
@Controller Identifies a class as a controller.
@RequestMapping URL mapping.
@ResponseBody Returns the result converted to a JSON string.
@RequestBody means receiving JSON format string parameters.
Through these three annotations, we can easily implement the function of returning JSON format data to the front-end through URLs. But everyone must be a little confused. Are these things from Spring MVC? What does it have to do with Spring boot? In fact, the function of Spring boot is to save us the configuration process. Other functions are indeed provided by Spring and Spring MVC for us. Everyone should remember that Spring boot provides us with automatic configuration services through various starters. This dependency was introduced in our project before:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>
This is a jar package that all Spring boot web projects need to be introduced. That is to say, as long as Spring boot web projects support the above functions by default. Here we further find that developing web engineering through Spring boot does save us a lot of configuration work.
OK, let's take a look at how to implement the Restful API. In fact, Restful itself is not a profound technology, but just a programming style, or a design style. In the traditional http interface design, we generally only use the get and post methods, and then use the vocabulary we define ourselves to represent different operations. For example, the interface for querying articles above, we define article/list.json to represent querying article lists, which can be accessed through get or post methods. The design of Restful API uses HTTP to represent CRUD-related operations. Therefore, in addition to get and post methods, other HTTP methods are also used, such as PUT, DELETE, HEAD, etc., to represent operations with different meanings through different HTTP methods. Below is a set of Restful APIs designed by me for adding, deleting, modifying and checking articles:
| Interface URL | HTTP Methods | Interface description |
| /article | POST | Save the article |
| /article/{id} | GET | Query article list |
| /article/{id} | DELETE | Delete articles |
| /article/{id} | PUT | Update article information |
It can be seen here that the URL is just a way to identify resources, and the specific behavior is specified by the HTTP method.
Now let’s take a look at how to implement the above interface. I won’t say much about it, just look at the code:
@RestController@RequestMapping("/rest")public class ArticleRestController { @Autowired private ArticleService articleService; @RequestMapping(value = "/article", method = POST, produces = "application/json") public WebResponse<Map<String, Object>> saveArticle(@RequestBody Article article) { article.setUserId(1L); articleService.saveArticle(article); Map<String, Object> ret = new HashMap<>(); ret.put("id", article.getId()); WebResponse<Map<String, Object>> response = WebResponse.getSuccessResponse(ret); return response; } @RequestMapping(value = "/article/{id}", method = DELETE, produces = "application/json") public WebResponse<?> deleteArticle(@PathVariable Long id) { Article article = articleService.getById(id); article.setStatus(-1); articleService.updateArticle(article); WebResponse<Object> response = WebResponse.getSuccessResponse(null); return response; } @RequestMapping(value = "/article/{id}", method = PUT, produces = "application/json") public WebResponse<Object> updateArticle(@PathVariable Long id, @RequestBody Article article) { article.setId(id); articleService.updateArticle(article); WebResponse<Object> response = WebResponse.getSuccessResponse(null); return response; } @RequestMapping(value = "/article/{id}", method = GET, produces = "application/json") public WebResponse<Article> getArticle(@PathVariable Long id) { Article article = articleService.getById(id); WebResponse<Article> response = WebResponse.getSuccessResponse(article); return response; }}Let's analyze this code again. The difference between this code and the previous code is:
(1) We are using the @RestController annotation, not @Controller. However, this annotation is also not provided by Spring boot, but an annotation provided in Spring MVC4, indicating a controller that supports Restful.
(2) There are three URL maps in this class that are the same, that is, they are all /article/{id}, which is not allowed to appear in the class identified by @Controller. Here, we can distinguish it by method. The function of produces is to indicate that the type of return result is JSON.
(3) The annotation @PathVariable is also provided by Spring MVC. Its function is to indicate that the value of the variable is obtained from the access path.
So after all, this code still has little to do with Spring boot. Spring boot only provides automatic configuration functions, which is also an important reason why Spring boot is very comfortable to use, because it is very invasive and you basically don’t feel its existence.
After the code is finished, how to test it? Except for the GET method, we cannot access it directly through the browser. Of course, we can directly send various http requests through postman. However, I still support testing various methods through unit test classes. Here we will test each method through Junit:
@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = Application.class)public class ArticleControllerTest { @Autowired private ArticleRestController restController; private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(restController).build(); } @Test public void testAddArticle() throws Exception { Article article = new Article(); article.setTitle("test article0000000"); article.setType(1); article.setStatus(2); article.setSummary("This is a test article"); Gson gosn = new Gson(); RequestBuilder builder = MockMvcRequestBuilders .post("/rest/article") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(gosn.toJson(article)); MvcResult result = mvc.perform(builder).andReturn(); System.out.println(result.getResponse().getContentAsString()); } @Test public void testUpdateArticle() throws Exception { Article article = new Article(); article.setTitle("Update Test Article"); article.setType(1); article.setStatus(2); article.setSummary("This is an update test article"); Gson gosn = new Gson(); RequestBuilder builder = MockMvcRequestBuilders .put("/rest/article/1") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8) .content(gosn.toJson(article)); MvcResult result = mvc.perform(builder).andReturn(); } @Test public void testQueryArticle() throws Exception { RequestBuilder builder = MockMvcRequestBuilders .get("/rest/article/1") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8); MvcResult result = mvc.perform(builder).andReturn(); System.out.println(result.getResponse().getContentAsString()); } @Test public void testDeleteArticle() throws Exception { RequestBuilder builder = MockMvcRequestBuilders .delete("/rest/article/1") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON_UTF8); MvcResult result = mvc.perform(builder).andReturn(); }}I won’t post the execution results here. If you are interested, you can experiment with it yourself. There are still very few points to explain in the entire class. The main reason for these things is that they have nothing to do with Spring boot. The reason for supporting these operations is to introduce the corresponding starter mentioned in the previous article:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope></dependency>
Because HTTP requests are to be executed, MockMvc is used here. ArticleRestController is instantiated through injection and cannot be directly new. Otherwise, ArticleRestController cannot be managed through Spring IoC containers, so other classes it depends on cannot be injected normally. Through MockMvc, we can easily implement HTTP DELETE/PUT/POST and other methods.
This article explains that if Spring boot is used to implement Restful API, most of the things are provided by Spring and Spring MVC, and Spring boot only provides automatic configuration functions. However, it is this automatic configuration that reduces a lot of development and maintenance work for us, allowing us to implement a web project more simply and efficiently, so that we can focus more on the development of the business itself without caring about the framework. In this article, we mentioned that we can access the Restful interface through postman and junit. In the next article, we will introduce another way to access it. If you are interested, you can continue to pay attention.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.