在Java中真正的前后端分离不是把前端资源放在spring boot的资源下,通过GetMapping的注释来管理,这样只能算作是前后端半解耦,真正的前后端分离是前端返回访问方式和访问地址,后端向前端返回json文件。这样才是在修改后端逻辑时不影响前端查看,前端调整页面时不影响后端运行。下面我用登录注册的界面来演示。
先将后端接受发送文件的格式定义为一个类,来直接接受发送数据:
public class LoginRequestDTO {
private String username;
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
接着注册Controller,向springboot表明这个类可以接受前端发送的文件,接着要表明接口地址,具体代码如下:
@RestController()
@RequiredArgsConstructor
public class Login {
private final SysUserMapper sysUserMapper;
@PostMapping("/login")
public Map<String,Object> loginPost(@RequestBody LoginRequestDTO dto){
Map<String,Object> map = new HashMap<>();
User user =sysUserMapper.findByUsername(dto.getUsername());
if (user==null){
map.put("success",false);
map.put("err","用户不存在");
return map;
}
if(dto.getPassword().equals(user.getPassword())){
map.put("success",true);
map.put("id",user.getId());
map.put("username",user.getUsername());
return map;
}else {
map.put("success",false);
map.put("err","密码错误");
return map;
}
}
}
这里的逻辑时通过访问数据库,查看用户输入的是否正确。
接着写入前端代码与后端的对接,要表明访问的方式以及地址:
const AuthService = {
login(username, password) {
return request.post('/login', { username, password });
},
};
async function handleLogin() {
const u = document.getElementById('loginUser').value;
const p = document.getElementById('loginPass').value;
if (!u || !p) return alert("请输入完整信息");
try {
const res = await AuthService.login(u, p);
if (res.success) {
localStorage.setItem('username', res.username);
window.location.href = "home.html";
} else {
alert("失败: " + res.err);
}
} catch (e) { console.error(e); }
}
完善逻辑后,可以使用ide自带的前端来访问前端查看页面,后端不受影响。除此之外还有重要的一点,由于前后端完全解耦,所以他们所在的端口位置不同,需要在后端中添加一个类来让后端代码可以获取所有端口发来的信息:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 允许所有接口
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
}
这也叫做CORS配置,是用于解决浏览器的同源策略限制,做到跨域访问资源。下面我来解释每一行的配置:addMapping是在对路径进行限制,比如输入/login只有这个路径下的可以访问到后端资源,这里的/**是所有路径都可以访问。allowedOriginPatterns是则是限制你的访问来源也就是协议+域名+端口号,这里的*是允许所有来源,而在早期的版本中是使用.allowedOrigins("https://your-domain.com")和.allowCredentials(true)来表明这个来源可以访问,早期版本设置.allowCredentials(true)就不能使用*来让所有来源通过了,而现在则是作为一个限制,可以让特定来源访问,也可以拒绝特定的网站。.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")则是允许括号中的访问方式。浏览器在发送请求之前会先发送一个消息头,提前表明这个来源要来访问了,而.allowedHeaders()就是允许那些消息头通过,只有消息头通过了前端才可以发起请求。