學(xué)習(xí)Spring這些技術(shù)性框架,光掌握理論知識(shí)是遠(yuǎn)遠(yuǎn)不夠了,我們要懂得學(xué)以致用,用鍵盤將學(xué)到的敲出來,在正確與錯(cuò)誤中尋找Spring的用法。
創(chuàng)新互聯(lián)建站主營(yíng)金溪網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app開發(fā),金溪h5微信小程序搭建,金溪網(wǎng)站營(yíng)銷推廣歡迎金溪等地區(qū)企業(yè)咨詢
為了給讀者一個(gè)直觀的概念,這里我用Spring搭建一個(gè)簡(jiǎn)單的登錄,可以讓你很快的了解Spring在持久層、業(yè)務(wù)層、表現(xiàn)層是怎么運(yùn)作的,這樣后面我們分模塊講解的時(shí)候,讀者也能很快的知道。
本文所用工具為Eclipse IDE,數(shù)據(jù)庫為Oracle 11g。
首先我們來了解登錄這個(gè)功能,用戶訪問登錄頁面,輸入賬號(hào)和密碼,點(diǎn)擊登錄,后臺(tái)驗(yàn)證是否有賬號(hào)和密碼匹配,如果匹配成功,則跳到歡迎頁面,并顯示用戶積分,如果登錄失敗則返回登錄頁面,并提示登錄失敗信息。
簡(jiǎn)化圖:
有經(jīng)驗(yàn)的程序員知道在開發(fā)之前都會(huì)先寫開發(fā)設(shè)計(jì)或者畫類圖,這里面筆者也從開發(fā)設(shè)計(jì)開始,針對(duì)登錄的全過程先設(shè)計(jì)好再開發(fā),畢竟磨刀不誤砍材功。
上面是登錄功能設(shè)計(jì)的全部過程大致描述一下:
1.首先訪問login.jsp,返回可輸入用戶賬號(hào)以及密碼的表單登錄頁面
2.用戶在登錄頁面輸入賬號(hào)、密碼,提交表單到服務(wù)器,Spring根據(jù)配置調(diào)用LoginController控制器響應(yīng)請(qǐng)求。
3.LoginController調(diào)用LoginService/isExistUser方法,根據(jù)傳遞的用戶、密碼參數(shù)查詢是否存在用戶,LoginService內(nèi)部通過持久層LoginDao與數(shù)據(jù)進(jìn)行交互。
4.如果匹配不到用戶,則返回Login.jsp,并返回提示信息,如果匹配成功,則進(jìn)入下一步。
5.LoginController調(diào)用LoginService/findUserByUsername獲取當(dāng)前登錄人的實(shí)體,設(shè)置當(dāng)前登錄時(shí)間以及積分更新后的值。
6.LoginController調(diào)用LoginService/loginsuccess()方法,進(jìn)行登錄成功后的業(yè)務(wù)處理,首先更新用戶信息,以及創(chuàng)建LoginInfo日志對(duì)象并插入數(shù)據(jù)庫。
7.重定向歡迎頁面welcome.jsp頁面,并返回響應(yīng)。
環(huán)境準(zhǔn)備:
1.表創(chuàng)建
create table TB_USER --用戶表 ( userid VARCHAR2(20), username VARCHAR2(20), credits NUMBER, password VARCHAR2(100), last_login_time DATE, last_login_ip VARCHAR2(30) ) create table TB_LOGIN_LOG --用戶登錄日志 ( login_id VARCHAR2(20), login_user_id VARCHAR2(20), ip VARCHAR2(20), login_time DATE ) --插入一條用戶 insert into tb_user (USERID, USERNAME, CREDITS, PASSWORD, LAST_LOGIN_TIME, LAST_LOGIN_IP) values ('zhangsan', '張三', 0, '123456', to_date('06-07-2016 09:10:39', 'dd-mm-yyyy hh34:mi:ss'), '0:0:0:0:0:0:0:1');
2.建立工程
良好的包分類以及分層會(huì)給維護(hù)以及其他開發(fā)帶來的很大的好處,一般企業(yè)項(xiàng)目中包的分類還應(yīng)該按項(xiàng)目模塊分,本文的項(xiàng)目較簡(jiǎn)單,因此分類就簡(jiǎn)單化,同時(shí)對(duì)于Spring 的配置文件一般都會(huì)有文件夾存放,這里我們就不詳細(xì)說明,相信讀者在工作中看到的項(xiàng)目大多數(shù)都是結(jié)構(gòu)良好的。
關(guān)于Spring3.0相關(guān)jar,這里面讀者可以自己去下載。
3.創(chuàng)建實(shí)體類
我們可以認(rèn)為實(shí)體類是貫穿業(yè)務(wù)層、持久層、表現(xiàn)層的一條線,一個(gè)功能模塊往往是圍繞一個(gè)實(shí)體類,業(yè)務(wù)層修改實(shí)體類狀態(tài),持久層將實(shí)體類存儲(chǔ)到數(shù)據(jù)庫,表現(xiàn)層展現(xiàn)實(shí)體類的狀態(tài),可見實(shí)體類的重要性。
public class User { private String userid;//用戶ID private String username;//用戶姓名 private Integer credits;//積分 private String password;//密碼 private Date lastlogintime;//最后登錄時(shí)間 private String loginip;//最后登錄ip } public class LoginInfo { private String loginid;//登錄主鍵 private String loginuserid;//登錄人ID private String loginip;//登錄IP private Date logintime;//登錄時(shí)間 } ......省略get、set方法
4.持久層LoginDao與LoginLogDao
我們先看看關(guān)于操作User的DAO,主要包括3個(gè)方法
1.getUserCount(),返回結(jié)果為×××,如果返回1,則表示用戶、密碼匹配正確,返回0則表示用戶、密碼匹配錯(cuò)誤,實(shí)際中這里存在密碼加密解密功能,這里我們簡(jiǎn)單化。
2.findUserByUsername(),根據(jù)用戶賬號(hào)獲取User實(shí)體。
3.updateUserInfo(),更新用戶最后登錄時(shí)間、 積分以及用戶IP.
import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.stereotype.Repository; import domain.User; @Repository //通過Spring注解定義一個(gè)Dao public class LoginDao { @Autowired//自動(dòng)注入id為JdbcTemplate的bean private JdbcTemplate jdbcTemplate; /** * * @author zangyn * @date 2016-8-19 下午1:54:16 * @Title: getUserCount * @Description: 根據(jù)賬號(hào)、密碼匹配是否存在 * @return int 返回類型 * @throws */ public int getUserCount(String username,String password){ String sql="SELECT COUNT(*) FROM TB_USER U WHERE U.USERID=? AND U.PASSWORD=?"; int count=jdbcTemplate.queryForInt(sql,new Object[]{username,password}); return count; } /** * * @author zangyn * @date 2016-8-19 下午1:54:43 * @Title: findUserByUsername * @Description: 根據(jù)Userid查詢是否存在該User * @return User 返回類型 * @throws */ public User findUserByUsername(String userid){ String sql="SELECT * FROM TB_USER U WHERE U.USERID=?"; final User u=new User(); jdbcTemplate.query(sql, new Object[]{userid}, new RowCallbackHandler() { @Override public void proce***ow(ResultSet rs) throws SQLException { u.setUserid(rs.getString("userid")); u.setUsername(rs.getString("username")); u.setCredits(rs.getInt("credits")); } }); return u; } /** * * @author zangyn * @date 2016-8-19 下午1:55:28 * @Title: updateUserInfo * @Description: 更新用戶相關(guān)信息 * @return void 返回類型 * @throws */ public void updateUserInfo(User user){ String sql="UPDATE TB_USER U SET U.LAST_LOGIN_TIME=?,U.LAST_LOGIN_IP=?,U.CREDITS=? WHERE U.USERID=?"; jdbcTemplate.update(sql, new Object[]{user.getLastlogintime(),user.getLoginip(),user.getCredits(),user.getUserid()}); } }
Spring2.5以后,可以使用注解的方式定義Bean,相比較XML配置,注解配置簡(jiǎn)單太多,所以我們盡量要以注解為主進(jìn)行Bean配置。
這里我們用@Repository定義了Dao bean的配置,使用 @Autowired將容器的Bean注入進(jìn)來。
從上面可以看到關(guān)于數(shù)據(jù)庫操作,我們引入了Spring JdbcTemplate,用過原始JDBC的都知道,在執(zhí)行數(shù)據(jù)庫操作之前都需要經(jīng)過:獲取連接>創(chuàng)建Statement>執(zhí)行數(shù)據(jù)庫操作>獲取結(jié)果>關(guān)閉Statement>關(guān)閉結(jié)果集>關(guān)閉連接,同時(shí)我們還要關(guān)注異常的處理,每次執(zhí)行sql,我們的1/3代碼都重復(fù)的寫以上的代碼,對(duì)于以上樣板式的代碼,Spring JDBC進(jìn)行了薄層的封裝,將樣板式的代碼進(jìn)行了封裝,用戶只需要編寫那些必不可少的代碼。
關(guān)于拼寫SQL注意:在拼寫較長(zhǎng)的sql時(shí),我們經(jīng)常需要換行,由于上下行最終會(huì)轉(zhuǎn)換為一個(gè)sql,這時(shí)候如果在每行的末尾沒有空格,就會(huì)存在連在一起的情況,因此,良好的拼寫SQL方法是在每行開始和結(jié)尾都打一個(gè)空格。
關(guān)于JdbcTemplate各種方法運(yùn)用,我會(huì)在后面一篇詳細(xì)介紹。
LoginLogDao只有一個(gè)存放日志記錄的方法,代碼如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import domain.LoginInfo; @Repository //通過Spring注解定義一個(gè)Dao public class LoginLogDao { @Autowired//自動(dòng)注入id為JdbcTemplate的bean private JdbcTemplate jdbcTemplate; public void insertLoginfo(LoginInfo info){ String sql="INSERT INTO TB_LOGIN_INFO(LOGIN_ID,LOGIN_USER_ID,IP,LOGIN_TIME) VALUES(login_info_seq.nextval,?,?,?)"; Object[] obj=new Object[]{info.getLoginuserid(),info.getLoginip(),info.getLogintime()}; jdbcTemplate.update(sql, obj); } }
5.數(shù)據(jù)源配置以及Spring 加載Dao
在src下創(chuàng)建一個(gè)名為applicationContext.xml的文件,配置文件內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- ①自動(dòng)掃描com.gloryscience.dao包下的所有類,將帶有注解的類 納入spring容器管理--> <context:component-scan base-package="dao"></context:component-scan> <!-- ②定義一個(gè)使用DBCP實(shí)現(xiàn)的數(shù)據(jù)源--> <bean id="dataSourceDBCP" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="gloryseience"/> <property name="password" value="gloryseience"/> </bean> <!-- ③定義Jdbc模板bean--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceDBCP"></property> </bean> </beans>
Spring的<context:component-scan>掃描指定包下的類,這樣@Repository、@Autowired注解才能起作用。
關(guān)于數(shù)據(jù)源配置這里只存在不同的配置源問題,關(guān)于為什么要這么配置,只能說是JDBC規(guī)范要求。
jdbcTemplate這個(gè)bean將dataSource注入到JdbcTemplate,然后JdbcTemplate Bean通過@Autowired注入到LoginLogDao和LoginDao中。
6. 服務(wù)層 LoginService
loginservice接口有三個(gè)方法:isExistUser用于驗(yàn)證賬號(hào)、密碼正確性、findUserByUsername用于根據(jù)用戶賬號(hào)加載User實(shí)體、loginSuccess用于登錄成功進(jìn)行積分變更、日志插入操作,這里存在事務(wù)操作,更新tb_user并插入tb_login_info,但是我們卻沒看到關(guān)于事務(wù)控制的代碼,Spring的一大優(yōu)點(diǎn)就是將事務(wù)從代碼中解放出來,下面我會(huì)講解關(guān)于Spring處理事務(wù)能力。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import dao.LoginDao; import dao.LoginLogDao; import domain.LoginInfo; import domain.User; @Service //將LoginServcie標(biāo)注為一個(gè)服務(wù)層Bean public class LoginService { @Autowired private LoginDao logindao; @Autowired private LoginLogDao loginlogdao; public boolean isExistUser(String userid,String password){ int count=logindao.getUserCount(userid, password); return count>0; } public User findUserByUsername(String userid){ return logindao.findUserByUsername(userid); } public void loginSuccess(User u){ u.setCredits(u.getCredits()+5); LoginInfo info=new LoginInfo(); info.setLoginuserid(u.getUserid()); info.setLogintime(u.getLastlogintime()); info.setLoginip(u.getLoginip()); loginlogdao.insertLoginfo(info); logindao.updateUserInfo(u); } }
7.Spring加載Service
Spring的事務(wù)雖然不用出現(xiàn)在代碼中,但是我們需要告訴Spring哪些業(yè)務(wù)類需要工作于事務(wù)環(huán)境以及事務(wù)的規(guī)則等內(nèi)容,讓Spring根據(jù)這些信息自動(dòng)為目標(biāo)業(yè)務(wù)類添加事務(wù)管理功能。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 自動(dòng)掃描com.gloryscience.dao包下的所有類,將帶有注解的類 納入spring容器管理--> <context:component-scan base-package="dao"></context:component-scan> <context:component-scan base-package="service"></context:component-scan> <bean id="dataSourceDBCP" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="gloryseience"/> <property name="password" value="gloryseience"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceDBCP"></property> </bean> <!-- 配置事務(wù)管理器聲--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSourceDBCP"></property> </bean> <!-- 通過AOP配置提供事務(wù)增強(qiáng),讓Service包下所有方法擁有事務(wù) --> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* service..*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
關(guān)于業(yè)務(wù)層和配置已經(jīng)完成,我們先單元測(cè)試一下。
8.單元測(cè)試
Spring 3.0的測(cè)試框架可以和Junit4整合,通過@RunWith可以指定SpringJUnit4Cla***unner測(cè)試運(yùn)行器,該運(yùn)行器是Spring提供的,可以將Spring容器和Junit4測(cè)試框架結(jié)合。@ContextConfiguration也是Spring提供的注解,用于指定Spring配置文件。@Test用于將方法標(biāo)注為測(cè)試方法,
import static org.junit.Assert.*; import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4Cla***unner; import domain.User; import service.LoginService; @RunWith(SpringJUnit4Cla***unner.class)//基于JUnit4的Spring測(cè)試框架 @ContextConfiguration(locations={"classpath:applicationContext.xml"})//啟動(dòng)spring容器 public class TestUserService { @Autowired//注入spring容器bean private LoginService loginservice; @Test public void isExistUser() { boolean a1=loginservice.isExistUser("zhangsan", "123456"); boolean a2=loginservice.isExistUser("zhangsan", "1"); assertTrue(a1); assertTrue(!a2); } @Test public void findUserbyUsername() { User u=loginservice.findUserByUsername("zhangsan"); assertEquals(u.getUserid(), "zhangsan"); } @Test public void loginSuccess(){ User u=new User(); u.setUserid("zhangsan"); u.setCredits(0); u.setLoginip("127.0.0.1"); u.setLastlogintime(new Date()); loginservice.loginSuccess(u); } }
9.配置SpringMVC
業(yè)務(wù)層以及持久層已經(jīng)完成,現(xiàn)在我們需要用SpringMVC將展現(xiàn)層加入個(gè)整個(gè)功能里。首先對(duì)web.xml進(jìn)行配置
<?xml version="1.0" encoding="UTF-8"?> <web-app id="acms" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!-- 從類文件下加載spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 啟動(dòng)spring 的監(jiān)聽器,引用contextConfigLocation的配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>Spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:Spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Spring</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
web容器通過上下文參數(shù)指定Spring配置文件,多個(gè)配置文件可用逗號(hào)分開,然后web容器在啟動(dòng)的時(shí)候會(huì)自動(dòng)啟動(dòng)監(jiān)聽器ContextLoaderListener,該監(jiān)聽器的作用是獲取Spring配置文件并啟動(dòng)Spring容器,注意將log4j.properties放在類路徑下,以便日志引擎生效。
SpringMVC也是通過截獲URL請(qǐng)求,然后進(jìn)行相關(guān)處理。
這里面注意SpringMVC也有個(gè)配置文件,該配置文件的文件與這里定義的Servlet名有一個(gè)契約,即
采用<servlet名>-servlet.xml,在這里Servlet的名稱為Spring,意思是/WEB-INF下必須有個(gè)Spring-servlet.xml的配置文件,這個(gè)配置文件無需通過web.xml的上下文進(jìn)行配置,SpringMVC的Servlet會(huì)自動(dòng)將Spring-servlet.xml與其他配置文件拼裝。
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:Spring-servlet.xml</param-value>
</init-param>
這里如果配置這個(gè)參數(shù)則配置文件就不會(huì)去執(zhí)行上面的契約去查找Spring-servlet,會(huì)根據(jù)我們自己配置的文件查找。
Servlet的URL路徑進(jìn)行定義我們讓所有后綴以.html的URL都能被Spring Servlet截獲,然后轉(zhuǎn)給SpringMVC進(jìn)行處理,請(qǐng)求被SpringMVC接受后,首先根據(jù)URL找到目標(biāo)的處理控制器,并將請(qǐng)求參數(shù)封裝成一個(gè)“命令”對(duì)象一起傳給控制器處理,控制器調(diào)用Spring 的業(yè)務(wù)Bean進(jìn)行處理并返回視圖。
10.控制器類LoginController
LoginController負(fù)責(zé)處理登錄請(qǐng)求,完成登錄業(yè)務(wù),根據(jù)登錄結(jié)果返回不同頁面。
import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import domain.LoginCommand; import domain.User; import service.LoginService; @Controller public class LoginController { @Autowired private LoginService loginservice; @RequestMapping(value="/index.html") public String loginPage(){ return "login"; } @RequestMapping(value="/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){ boolean isValid=loginservice.isExistUser(loginCommand.getUserid(), loginCommand.getPassword()); if(!isValid){ return new ModelAndView("login","error","用戶或密碼錯(cuò)誤"); }else{ User user=loginservice.findUserByUsername(loginCommand.getUserid()); user.setLoginip(request.getRemoteAddr()); user.setLastlogintime(new Date()); request.getSession().setAttribute("user", user); loginservice.loginSuccess(user); return new ModelAndView("welcome"); } } }
@Controller將LoginController標(biāo)注為SpringMVC控制器,處理HTTP請(qǐng)求,一個(gè)控制器包含多個(gè)HTTP請(qǐng)求路徑的處理方法,通過@RequestMapping指定方法映射請(qǐng)求路徑。
請(qǐng)求參數(shù)會(huì)根據(jù)參數(shù)名稱默認(rèn)契約自動(dòng)綁定到響應(yīng)方法的入?yún)⒅?,在loginCheck(HttpServletRequest request,LoginCommand loginCommand),請(qǐng)求參數(shù)會(huì)根據(jù)名稱匹配綁定到loginCommand中。
public class LoginCommand { private String userid;//用戶id private String password;//用戶密碼 省略get/set }
請(qǐng)求方法可以返回ModelAndView或者字符串,SpringMVC會(huì)解析并自動(dòng)轉(zhuǎn)向目標(biāo)響應(yīng)頁面。關(guān)于ModelAndView讀者只需知道它目前代表一種視圖就行,后面會(huì)解釋。
現(xiàn)在需要知道ModelAndView返回的兩種形式,ModelAndView("login","error","用戶或密碼錯(cuò)誤")和ModelAndView("main"),第一個(gè)參數(shù)代表視圖的邏輯名,第二個(gè)以及第三個(gè)代表數(shù)據(jù)模型名稱和數(shù)據(jù)模型對(duì)象,數(shù)據(jù)模型對(duì)象將以數(shù)據(jù)模型名稱為參數(shù)名放置到request屬性中。
SpringMVC的配置文件Spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 掃描controllerd,應(yīng)用spring注釋 --> <context:component-scan base-package="controller" /> <!-- 對(duì)模型視圖解析 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/login/" p:suffix=".jsp" /> </beans>
上面SpringMVC通過配置來解析ModelAndView,Spring有許多解析ModelAndView的方式,這里我們用InternalResourceViewResolver,它通過添加前后綴方式來解析。如ModelAndView("welcome"),將解析為/WEB-INF/login/welcome.jsp
11.JSP頁面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>論壇登錄</title> </head> <c:if test="${not empty error}"> <font color="red"><c:out value="${error}"></c:out></font> </c:if> <form action="<c:url value='/loginCheck.html'/>" method="post"> <input type="text" id="userid" name="userid" placeholder="用戶名" maxlength="40"/> <input type="password"id="password" name="password" placeholder="密碼" maxlength="40"/> <input type="submit" value="登 錄" /> <input type="reset" value="重置" /> </form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>論壇主頁</title> </head> ${user.username},歡迎你進(jìn)入本論壇,你的積分為${user.credits}. </body> </html>
這里我引入c標(biāo)簽,需要引入兩個(gè)jar包。
剩下的可以直接部署了,然后訪問http://localhost:8088/項(xiàng)目部署名稱/,輸入zhangsan、123456即可登錄成功。
名稱欄目:Spring3.0第三講:Spring實(shí)現(xiàn)簡(jiǎn)單的登錄
瀏覽路徑:http://jinyejixie.com/article10/gpssgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、商城網(wǎng)站、品牌網(wǎng)站建設(shè)、網(wǎng)站改版、ChatGPT、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)