前后端分离 天啦噜,我们希望『前后端分离』,前端的组件是css/js/html/图片,负责显示数据。数据打哪儿来?答案是后端。
后端服务器专门服务于前端,兢兢业业,勤勤恳恳,前端要什么,后端就给什么。
比如,前端向后端发出请求:www.ilovcecl.com/users/,目的是获取用户列表;逻辑复杂的后端服务器掐指一算,洞悉前端要的数据,便以JSON格式返回用户列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ { "id" : 3 , "name" : "Jerome" , "age" : 45 , "salary" : 30000 } , { "id" : 4 , "name" : "Silvia" , "age" : 50 , "salary" : 40000 } ]
可见,前后端分离的过程中,后端会以JSON格式返回数据,数据URI符合Rest风格(当然前后端通信除了Rest外还有其它架构)。
本文给出的正是以JSON风格返回数据、符合Rest风格的后端web项目,不依赖于xml配置,结构简单。
操作说明 你可以从GitHub下载项目源码:https://github.com/qiuyongchen/rcs-web/archive/v1.0.0.zip 使用IntelliJ IDEA导入项目,自动刷新pom依赖(部分IDEA版本有Bug无法刷新,请在shell中输入mvn clean package,手动刷新);导入完成后配置tomcat,启动项目,访问http:localhost:8080/user/ ,耐心等待几秒钟,JSON即展现你眼前。
你也可以一步步地创建项目,添加文件,最后启动。
项目结构 本项目里,除了一个pom文件外,其余的均是java文件,不依赖传统的spring配置xml。 结构图:
src pom文件 整个项目里唯一的配置有木有!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.ilovecl</groupId > <artifactId > rcs-web</artifactId > <packaging > war</packaging > <version > 1.0.0</version > <name > rcs-web</name > <properties > <springframework.version > 4.2.0.RELEASE</springframework.version > <jackson.version > 2.5.3</jackson.version > </properties > <dependencies > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${springframework.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-tx</artifactId > <version > ${springframework.version}</version > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > ${jackson.version}</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > </dependency > </dependencies > <build > <pluginManagement > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.2</version > <configuration > <source > 1.7</source > <target > 1.7</target > </configuration > </plugin > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-war-plugin</artifactId > <version > 2.4</version > <configuration > <warSourceDirectory > src/main/java</warSourceDirectory > <warName > rcs-web</warName > <failOnMissingWebXml > false</failOnMissingWebXml > </configuration > </plugin > </plugins > </pluginManagement > <finalName > rcs-web</finalName > </build > </project >
项目初始化 WebInitilizer.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class WebInitilizer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class []{WebConfiguration.class}; } @Override protected Class<?>[] getServletConfigClasses() { return null ; } @Override protected String[] getServletMappings() { return new String []{"/" }; } }
项目配置类 WebConfiguration.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.EnableWebMvc;@Configuration @EnableWebMvc @ComponentScan(basePackages = ".") public class WebConfiguration {}
控制类 RcsController.java 一个web项目最重要的类…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 package controller;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.util.UriComponentsBuilder;import model.User;import service.UserService;@RestController public class RcsController { @Autowired UserService userService; @RequestMapping(value = "/user/", method = RequestMethod.GET) public ResponseEntity<List<User>> listAllUsers () { List<User> users = userService.findAllUsers(); if (users.isEmpty()) { return new ResponseEntity <List<User>>(HttpStatus.NO_CONTENT); } return new ResponseEntity <List<User>>(users, HttpStatus.OK); } @RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<User> getUser (@PathVariable("id") long id) { System.out.println("Fetching User with id " + id); User user = userService.findById(id); if (user == null ) { System.out.println("User with id " + id + " not found" ); return new ResponseEntity <User>(HttpStatus.NOT_FOUND); } return new ResponseEntity <User>(user, HttpStatus.OK); } @RequestMapping(value = "/user/", method = RequestMethod.POST) public ResponseEntity<Void> createUser (@RequestBody User user, UriComponentsBuilder ucBuilder) { System.out.println("Creating User " + user.getName()); if (userService.isUserExist(user)) { System.out.println("A User with name " + user.getName() + " already exist" ); return new ResponseEntity <Void>(HttpStatus.CONFLICT); } userService.saveUser(user); HttpHeaders headers = new HttpHeaders (); headers.setLocation(ucBuilder.path("/user/{id}" ).buildAndExpand(user.getId()).toUri()); return new ResponseEntity <Void>(headers, HttpStatus.CREATED); } @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT) public ResponseEntity<User> updateUser (@PathVariable("id") long id, @RequestBody User user) { System.out.println("Updating User " + id); User currentUser = userService.findById(id); if (currentUser == null ) { System.out.println("User with id " + id + " not found" ); return new ResponseEntity <User>(HttpStatus.NOT_FOUND); } currentUser.setName(user.getName()); currentUser.setAge(user.getAge()); currentUser.setSalary(user.getSalary()); userService.updateUser(currentUser); return new ResponseEntity <User>(currentUser, HttpStatus.OK); } @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) public ResponseEntity<User> deleteUser (@PathVariable("id") long id) { System.out.println("Fetching & Deleting User with id " + id); User user = userService.findById(id); if (user == null ) { System.out.println("Unable to delete. User with id " + id + " not found" ); return new ResponseEntity <User>(HttpStatus.NOT_FOUND); } userService.deleteUserById(id); return new ResponseEntity <User>(HttpStatus.NO_CONTENT); } @RequestMapping(value = "/user/", method = RequestMethod.DELETE) public ResponseEntity<User> deleteAllUsers () { System.out.println("Deleting All Users" ); userService.deleteAllUsers(); return new ResponseEntity <User>(HttpStatus.NO_CONTENT); } }
Model类 User.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 package model;public class User { private long id; private String name; private int age; private double salary; public User () { id = 0 ; } public User (long id, String name, int age, double salary) { this .id = id; this .name = name; this .age = age; this .salary = salary; } public long getId () { return id; } public void setId (long id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } public double getSalary () { return salary; } public void setSalary (double salary) { this .salary = salary; } @Override public int hashCode () { final int prime = 31 ; int result = 1 ; result = prime * result + (int ) (id ^ (id >>> 32 )); return result; } @Override public boolean equals (Object obj) { if (this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; User other = (User) obj; if (id != other.id) return false ; return true ; } @Override public String toString () { return "User [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + "]" ; } }
Service接口 UserService.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package service;import model.User;import java.util.List;public interface UserService { User findById (long id) ; User findByName (String name) ; void saveUser (User user) ; void updateUser (User user) ; void deleteUserById (long id) ; List<User> findAllUsers () ; void deleteAllUsers () ; public boolean isUserExist (User user) ; }
Service接口实现类 UserServiceImpl.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 package service.impl;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.concurrent.atomic.AtomicLong;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import model.User;import service.UserService;@Service("userService") @Transactional public class UserServiceImpl implements UserService { private static final AtomicLong counter = new AtomicLong (); private static List<User> users; static { users = populateDummyUsers(); } public List<User> findAllUsers () { return users; } public User findById (long id) { for (User user : users) { if (user.getId() == id) { return user; } } return null ; } public User findByName (String name) { for (User user : users) { if (user.getName().equalsIgnoreCase(name)) { return user; } } return null ; } public void saveUser (User user) { user.setId(counter.incrementAndGet()); users.add(user); } public void updateUser (User user) { int index = users.indexOf(user); users.set(index, user); } public void deleteUserById (long id) { for (Iterator<User> iterator = users.iterator(); iterator.hasNext(); ) { User user = iterator.next(); if (user.getId() == id) { iterator.remove(); } } } public boolean isUserExist (User user) { return findByName(user.getName()) != null ; } private static List<User> populateDummyUsers () { List<User> users = new ArrayList <User>(); users.add(new User (counter.incrementAndGet(), "Sam" , 30 , 70000 )); users.add(new User (counter.incrementAndGet(), "Tom" , 40 , 50000 )); users.add(new User (counter.incrementAndGet(), "Jerome" , 45 , 30000 )); users.add(new User (counter.incrementAndGet(), "Silvia" , 50 , 40000 )); return users; } public void deleteAllUsers () { users.clear(); } }