在學習了《Spring實戰》的一些章節後,我打算寫一個項目來鍛鍊一下。在創建項目前,我希望用全註解的方式來開發。後來就知道,debug掉的頭髮,都是前期拍腦袋進的水——網上關於註解的資料也太少了吧!!!
經過千辛萬苦後,我終於順利完成了項目的搭建:)
項目的源代碼地址:https://github.com/FuGaZn/SpringBlog
歡迎給個star哦 ( ̄∇ ̄)
概述
首先介紹一下這個SpringBlog項目:
本項目基於Spring+SpringMVC+Mybatis的技術框架,實現個人博客的登入登出、管理文章、在線編寫和發佈文章、瀏覽博客等基本功能。
在一步步搭建項目的過程中,你將學習到:
- DispatcherServlet的配置
- Web界面訪問的配置
- 用Interceptor實現攔截功能
- 自動裝配(Auto wire)
- Controller和Service的編寫
- 基於Mybatis實現的Mapper接口
以上所有功能將使用註解的形式配置!
(除了使用web.xml配置對靜態資源的訪問)
博客界面示例
登陸界面:
後臺管理界面:
撰寫文章界面:
博客主頁:
查看博客界面:
搭建項目
新建一個Java web項目,引入Maven框架,將pom.xml的內容配置好就完成了基本的搭建。
項目結構:
本項目採用Maven來管理,pom.xml文件內容如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<groupId>com.fjx.blog.spring</groupId>
<artifactId>SpringBlog</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
<!--spring依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<!--springMVC依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<!--springMVC依賴結束-->
</dependencies>
</project>
編寫Java web Config文件
java web cofig配置類是xml配置文件的替代,在Java類上添加@Configuration註解後,該類會被Spring識別爲配置類。
配置DispatherServlet
DispatcherServlet用於將請求發送給SpringMVC控制器(controller)DispatcherServlet 會查詢一個或多個處理器映射( handler mapping ) 來確定請求的下一站在哪裏。處理器映射會根據請求所攜帶的 URL 信息來進行決策。
MyWebInitializer.java:
package com.fjx.blog.spring.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//根配置 和我們目前的項目無關,所有不用去關心
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {RootConfig.class};
}
//指定配置類
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}
//將DispatcherServlet映射到“/”,即該DispatcherServlet會處理所有的請求
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
《Spring實戰》對AbstractAnnotationConfigDispatcherServletInitializer的講解:
配置WebConfig
package com.fjx.blog.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@ComponentScan("com.fjx.blog.spring")
public class WebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Bean(name = "multipartResolver") // bean必須寫name屬性且必須爲multipartResolver
//用於傳輸MultipartFile
protected CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setMaxUploadSize(5 * 1024 * 1024);
commonsMultipartResolver.setMaxInMemorySize(0);
commonsMultipartResolver.setDefaultEncoding("UTF-8");
return commonsMultipartResolver;
}
@Override
//用於處理靜態資源
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resource/**").addResourceLocations("/resource/asset/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
InternalResourceViewResolver用於查找JSP文件,對於傳入的視圖名稱(Controller裏@RequestMapping註解的方法返回的String是視圖名稱),爲其添加前綴和後綴,在web/webapp文件夾下查找對應的JSP文件。
例如,對以下方法:
@RequestMapping({"/index","/"})
public String index(Model model){
return "home/index";
}
InternalResourceViewResolver接收到“/home/index”字符串後,拼接前綴後綴得“/WEB-INF/views/home/index.jsp”。
注意:setPrefix方法裏的/WEB-INF/views/不能寫成WEB-INF/views/,前者通過相對路徑訪問資源,後者使用絕對路徑,因此後者會出錯。
addResourceHandlers方法用於處理對靜態資源的訪問。如果不設置,訪問靜態資源會被攔截。
如果addResourceHandlers不起作用的話,可以在web.xml中配置如下內容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringBlog</display-name>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.woff</url-pattern>
<url-pattern>*.svg</url-pattern>
<url-pattern>*.ttf</url-pattern>
<url-pattern>*.woff2</url-pattern>
<url-pattern>*.eot</url-pattern>
<url-pattern>*.otf</url-pattern>
<url-pattern>*.ico</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
</web-app>
RootConfig.java:
package com.fjx.blog.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"com.fjx.blog.spring"},
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class))
public class RootConfig {
}
配置SecurityConfig.java以實現對登陸狀態的判斷
package com.fjx.blog.spring.config;
import com.fjx.blog.spring.interceptor.SecurityInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class SecurityConfig extends WebMvcConfigurationSupport {
@Bean
public SecurityInterceptor securityInterceptor() {
return new SecurityInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration registration = registry.addInterceptor(securityInterceptor());
registration.excludePathPatterns("/home/*"); //排除對該路徑的攔截
registration.excludePathPatterns("/");
registration.excludePathPatterns("/login");
registration.addPathPatterns("/admin/*"); //添加對該路徑的攔截
registration.addPathPatterns("/admin");
}
}
SecurityInterceptor.java的內容:
package com.fjx.blog.spring.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws IOException {
//這裏根據session的用戶來判斷角色的權限,根據權限來轉發不同的頁面
if(request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
}
在第一次訪問被SecurityConfig攔截的界面時,因爲session裏的user屬性不存在,所以會重定向到login界面。登陸後,添加user屬性,再次訪問這些界面時,就不會被重定向了。
配置Mybatis:
在resources文件夾下建立properties文件,添加如下內容:
server.port=8080
# 數據庫連接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springblog
# 用戶名
spring.datasource.username=root
# 密碼
spring.datasource.password=123456
# 數據庫驅動
spring.datasource.driver=com.mysql.jdbc.Driver
#mybatis設置相關
mybatis.type.alias.package=com.bdqn.lyrk.ssm.study.entity
logging.leve.com.fjx.blog.spring.mapper=debug
mybatis.configuration.mapUnderscoreToCamelCase=true
添加PropertiesConfig.java:
package com.fjx.blog.spring.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@PropertySource("classpath:application.properties")
public class PropertiesConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.driver}")
private String driver;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${mybatis.type.alias.package}")
private String mybatisTypeAliasPackage;
public String getUrl() {
return url;
}
public String getDriver() {
return driver;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
添加MyBatisConfig.java:
package com.fjx.blog.spring.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan("com.fjx.blog.spring.mapper")
public class MyBatisConfig {
@Autowired
PropertiesConfig propertiesConfig;
@Bean
//如果項目運行後報“Error querying database. Cause: java.lang.NullPointerExceptio”這樣的錯誤,你或許要檢查一下這裏的配置,看看是不是url或者driverClassName爲空
public DataSource dataSource(PropertiesConfig propertiesConfig) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(propertiesConfig.getUsername());
dataSource.setPassword(propertiesConfig.getPassword());
dataSource.setUrl(propertiesConfig.getUrl());
dataSource.setDriverClassName(propertiesConfig.getDriver());
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
//不能用new PropertiesConfig()的方式引入參數,否則得不到變量
sessionFactory.setDataSource(dataSource(propertiesConfig));
return sessionFactory.getObject();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
return propertySourcesPlaceholderConfigurer;
}
}
在以上所有文件都配置完畢後,我們就可以開發具體頁面啦!是不是很激動呢,如果你是第一次開發SpringMVC項目,可能會覺得上面的配置很繁瑣,但是如果你接觸過用XML文件進行配置的話,那肯定會覺得上面的配置太簡單了。
而且接下來,當我們配置Controller、Service、Mapper時,只需要在類上添加註解就可以完成了,不用在辛辛苦苦寫完java文件後,還要在xml文件裏進行添加或修改。
接下來讓我們以登陸操作爲例,從數據庫到jsp頁面,自底向上一條龍講述其中的全部操作。
登陸:Mapper->Service->Controller->JSP
Mapper
我們先在數據庫中建立一張表,名字爲users(在IDEA裏可以圖形化操作)
-- auto-generated definition
CREATE TABLE users
(
id INT AUTO_INCREMENT
PRIMARY KEY,
ukey VARCHAR(255) NULL,
name VARCHAR(255) NULL,
password VARCHAR(255) NULL,
CONSTRAINT user_uid_uindex
UNIQUE (id)
)
ENGINE = InnoDB;
然後創建對應的User.java:
package com.fjx.blog.spring.entity;
public class User {
private int id;
private String name; //暱稱
private String ukey; //用戶身份識別key,登陸使用
private String password;
//還有一系列getter和setter方法,別忘了哦。在IDEA裏,同時摁住Alt和Insert鍵,可以一鍵添加全部getter和setter方法哦
}
配置UserMapper.java:
package com.fjx.blog.spring.mapper;
import com.fjx.blog.spring.entity.User;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;
import java.util.List;
@Mapper
@Component(value = "userMapper")
public interface UserMapper {
@Select("select * from users")
List<User> selectAll();
@Select("select * from users where ukey = #{ukey}")
List<User> selectUserByKey(String ukey);
@Insert("insert into users values(#{user.id},#{user.ukey},#{user.name},#{user.password},#{user.userLastLoginIp})")
@Options(useGeneratedKeys = true)
int save(@Param("user") User user);
}
@Mapper註解表明該類是一個Mybatis Mapper
@Select/@Insert註解等用來操作sql語句。在傳入對象參數時,在參數前使用@Param註解,否則會報 xxx not found錯誤。
Mybatis的註解詳細用法可以參照:MyBatis常用11種註解
創建UserService和UserServiceImpl文件:
package com.fjx.blog.spring.service;
import com.fjx.blog.spring.entity.User;
public interface UserService {
User getUserByKey(String key);
void save(User user);
}
package com.fjx.blog.spring.service.impl;
import com.fjx.blog.spring.entity.User;
import com.fjx.blog.spring.mapper.UserMapper;
import com.fjx.blog.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getUserByKey(String key) {
List<User> users = userMapper.selectUserByKey(key);
if (users == null || users.size() == 0){
return null;
}else
return users.get(0);
}
public void save(User user) {
int i = userMapper.save(user);
}
}
可以看到UserServiceImpl實現自UserServcie接口,@Service註解要放在UserServiceImpl上
使用@AutoWired註解來爲UserMapper自動裝配
創建LoginController.java:
package com.fjx.blog.spring.controller.admin;
import com.fjx.blog.spring.entity.User;
import com.fjx.blog.spring.service.UserService;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* @author fujiaxing
* 登陸登出功能
*/
@Controller
public class LoginController {
@Autowired
UserService userService;
@RequestMapping({"/login","/"})
public String login(){
return "/admin/login";
}
@RequestMapping(value = "/loginVerify",method = RequestMethod.POST)
@ResponseBody
public String loginVerify(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> map = new HashMap();
String userkey = request.getParameter("ukey");
String password = request.getParameter("password");
String rememberme = request.getParameter("rememberme");
User user = userService.getUserByKey(userkey);
if (user == null) {
map.put("code", 0);
map.put("msg", "用戶名無效!");
} else if (!user.getPassword().equals(password)) {
map.put("code", 0);
map.put("msg", "密碼錯誤!");
} else {
System.out.println("登陸成功");
//登錄成功
map.put("code", 1);
map.put("msg", "");
//添加session
request.getSession().setAttribute("user", user);
if (rememberme != null) {
//創建兩個Cookie對象
Cookie keyCookie = new Cookie("ukey", userkey);
//設置Cookie的有效期爲3天
keyCookie.setMaxAge(60 * 60 * 24 * 3);
Cookie pwdCookie = new Cookie("password", password);
pwdCookie.setMaxAge(60 * 60 * 24 * 3);
response.addCookie(keyCookie);
response.addCookie(pwdCookie);
}
// user.setUserLastLoginTime(new Date());
user.setUserLastLoginIp(getIpAddr(request));
userService.save(user);
}
String result = new JSONObject(map).toString();
return result;
}
@RequestMapping(value = "/logOut",method = RequestMethod.GET)
@ResponseBody
public String loginOut(HttpServletRequest request, HttpServletResponse response){
request.getSession().removeAttribute("user");
Map<String, Object> map = new HashMap();
map.put("code", 1);
map.put("msg", "");
String result = new JSONObject(map).toString();
return result;
}
}
可以看到,在LoginController裏,自動裝配的對象是UserService, 而不是UserServiceImpl
login()方法上註解配置了映射“/login”,對應的jsp文件則是/WEB-INF/views/admin/login.jsp
上文提到,我們使用session裏的user屬性判斷用戶是否需要登陸,在執行登陸操作後,我們調用request.getSession().addAttribute()方法添加user屬性。在登出系統後,我們調用request.getSession().removeAttribute()方法刪除user屬性
後端的所有類和方法都寫好啦,接下來我們就可以編寫前端界面和js代碼了。
新建一個/admin/login.jsp文件,添加如下代碼:
<body>
<%
String username = "", password = "";
Cookie[] cookies = request.getCookies();
if (cookies!=null){
for (int i = 0; i < cookies.length; i++) {//對cookies中的數據進行遍歷,找到用戶名、密碼的數據
if ("ukey".equals(cookies[i].getName())) {
username = cookies[i].getValue();
} else if ("password".equals(cookies[i].getName())) {
password = cookies[i].getValue();
}
}
}
%>
<form name="loginForm" id="loginForm" method="post">
<input type="text" placeholder="用戶名" name="username" id="user_login" class="input" value="<%=username%>" size="20" required/>
<input type="password" placeholder="密碼" name="password" id="user_pass" class="input" value="<%=password%>" size="20" required/>
<p class="forgetmenot"><label for="rememberme"><input name="rememberme" type="checkbox" id="rememberme" value="1" checked /> 記住密碼</label></p>
<a class="submit">登陸
<input type="button" name="wp-submit" id="submit-btn" value="登錄" />
</a>
<p id="backtoblog" style="margin-left: 160px;color: black"><a href="/index">← 返回到博客</a></p>
</form>
</body>
<script src="/resource/assets/js/jquery.min.js"></script>
<script type="text/javascript">
$("#submit-btn").click(function () {
var user = $("#user_login").val();
var password = $("#user_pass").val();
console.log(user+' '+password)
if(user=="") {
alert("用戶名不可爲空!");
} else if(password==""){
alert("密碼不可爲空!");
} else {
$.ajax({
async: false,//同步,待請求完畢後再執行後面的代碼
type: "POST",
url: '/loginVerify',
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: $("#loginForm").serialize(),
dataType: "json",
success: function (data) {
if(data.code==0) {
alert(data.msg);
} else {
window.location.href="/admin";
}
},
error: function () {
alert("數據獲取失敗")
}
})
}
})
只摘取了關鍵代碼,要看全部代碼可以點擊Github: SpringBlog/Login.sjp
全部完成後,運行tomcat,就可以在localhost:8080上看到我們寫的界面啦,並且可以正常使用哦!
總結
好的,本篇文章到這裏就結束了。似乎寫了不少內容(好吧,大部分都是代碼)
註解有着比xm更簡單的配置和更好的可讀性,使用得當的話會大大減輕springmvc開發的複雜度和代碼量。
本文也未涉及深層次的spring知識,主要還是以一個簡單的登陸流程爲例,講一下如何以全註解的方式來開發一個springmvc項目。
如果對這個簡單的個人博客框架有興趣的話,可以關注https://github.com/FuGaZn/SpringBlog
SpringMVC相對於SpringBoot來說,開發起來還是太複雜了。所以這個博客項目僅用於熟悉springmvc註解配置的用法,不會搭建爲成熟的博客系統。
博客的在線編輯功能使用了Editormd,如果想了解Editormd的用法,可以看:Editormd的使用——在線編輯和查看文章