整理下自己在搭建SpringMVC+Spring+Hibernate+Maven框架時(shí)遇到的問(wèn)題肺孤。
1. classpath路徑解析
- 在搭建框架時(shí)筐咧,我們經(jīng)常要用到
classpath
這個(gè)單詞,比如設(shè)置spring配置文件
<display-name>my app</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spirng-hbm.xml,classpath:spring-dispatcher.xml</param-value>
</context-param>
classpath路徑脆贵,指的就是classes目錄医清,當(dāng)web項(xiàng)目發(fā)布后,java編譯后的class文件以及用到的配置文件都會(huì)被保存到這個(gè)目錄,此目錄在WEB-INF文件夾下卖氨,可以從Tomcat的wtpwebapps
目錄下觀察到会烙。
-
在開(kāi)發(fā)過(guò)程中负懦,可以理解這個(gè)路徑為項(xiàng)目源文件路徑
不使用maven管理項(xiàng)目的話,就是src
目錄下柏腻,如果使用maven纸厉,就是src/main/resource
和src/main/java
目錄。 -
classpath*
相比classpath
多了個(gè)*
號(hào)五嫂,它是指除了直接查找指定目錄颗品,還要查找lib目錄下jar包內(nèi)的配置文件。
2. JSP文件charset和pageEncoding區(qū)別
下面是每個(gè)JSP文件頭都會(huì)標(biāo)注的代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
那么charset
和pageEncoding
區(qū)別是什么贫导?
我們知道JSP其實(shí)就是一個(gè)Servlet抛猫,也就是說(shuō)它是可以被編譯的。
-
pageEncoding
是指當(dāng)前這個(gè).jsp
文件的編碼格式孩灯,是通過(guò)什么編碼來(lái)進(jìn)行保存的闺金。
當(dāng)這個(gè)JSP被解析編譯成.java
文件時(shí),就是通過(guò)此屬性來(lái)讀取JSP文件峰档,這一步如果設(shè)置錯(cuò)誤败匹,就會(huì)在后臺(tái)出現(xiàn)亂碼。 -
charset
是后臺(tái)操作完成讥巡,發(fā)送給瀏覽器(前端)所使用編碼掀亩,瀏覽器通過(guò)此編碼解析響應(yīng)信息,這個(gè)屬性等同于response.setCharacterEncoding()
欢顷。 - 如果沒(méi)有指定
pageEncoding
那么將以charset
設(shè)定值保存JSP頁(yè)面槽棍。
3. 在web.xml通過(guò)過(guò)濾器配置編碼
我們可以在web.xml
文件中進(jìn)行編碼配置,這樣就可以不用重復(fù)的寫(xiě)request/response.setCharacterEncoding()
.抬驴。
配置如下:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
其中encoding
參數(shù)作用是設(shè)置ServletRequest.setCharacterEncoding()
.
而forceEncoding
則是使ServletResponse
的編碼設(shè)置和ServletRequest
一致炼七。
4. EL表達(dá)式被當(dāng)做字符串處理
- 有時(shí)我們會(huì)發(fā)現(xiàn)在JSP中使用EL表達(dá)式時(shí),會(huì)原封不動(dòng)的輸出
${xxxx.xxx}
布持,而不是運(yùn)算后的結(jié)果豌拙。
這是因?yàn)閟ervlet除了2.4以外版本,都默認(rèn)忽視EL表達(dá)式题暖,將其當(dāng)做字符串處理按傅。
在JSP文件中加入<%@ page isELIgnored="false" %>
就可以激活EL表達(dá)式。 - 上面的做法要在每個(gè)JSP文件都進(jìn)行配置胧卤,會(huì)很麻煩唯绍,也可以直接更改
web.xml
中的版本號(hào),進(jìn)行全局設(shè)置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
5. HQL語(yǔ)句操作的是實(shí)體類
當(dāng)我們使用HQL語(yǔ)句時(shí)枝誊,比如:session.createQuery("from Article").list();
推捐,查詢的對(duì)象Article
是項(xiàng)目中的實(shí)體類,而不是數(shù)據(jù)庫(kù)中article
這個(gè)表名侧啼。
6. Hibernate連接數(shù)據(jù)庫(kù)的信息最好單獨(dú)使用文件
在spring中配置連接數(shù)據(jù)庫(kù)所需要的user.name``user.password
,url
等信息時(shí)牛柒,最好將其寫(xiě)成一個(gè).properties
文件,這樣我們?cè)谛薷臅r(shí)就不用動(dòng)配置文件了痊乾。
database.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=
如果url寫(xiě)入xml文件中皮壁,要用&
代替&
,以免歧義解析錯(cuò)誤哪审。
springContext.xml
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
7. 絕對(duì)路徑與相對(duì)路徑
在項(xiàng)目中我們經(jīng)常要引用url
地址蛾魄,比如/app/welcome.png
或者./app/welcome.png
。那么/
前面那個(gè).
有或者沒(méi)有是什么區(qū)別湿滓?
我們假設(shè)有個(gè)app
web項(xiàng)目
- 如果前面有
.
滴须,那么這個(gè)是當(dāng)前位置的相對(duì)路徑,從當(dāng)前文件作為基準(zhǔn)叽奥,開(kāi)始計(jì)算路徑扔水。 - 如果前面沒(méi)有
.
,那么這個(gè)路徑是根目錄的路徑朝氓,這里有個(gè)坑魔市,這個(gè)根目錄不一定是項(xiàng)目根目錄,也有可能是站點(diǎn)的根目錄赵哲。
這是很容易犯的錯(cuò)誤待德,找不到正確路徑,自然就會(huì)造成404枫夺。
所以建議大家在寫(xiě)路徑相關(guān)代碼時(shí)将宪,使用絕對(duì)路徑!
8. 配置視圖解析器
在使用SpringMVC時(shí)橡庞,我們經(jīng)常會(huì)在其配置文件中做如下配置:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
其中InternalResourceViewResolver
是一個(gè)視圖解析器较坛,通過(guò)配置它的屬性"prefix"和"suffix"來(lái)為Java代碼Controller中返回的ModelAndView加上前綴后綴,這樣就會(huì)去指定的路徑下(prefix)自動(dòng)解析視圖毙死,不用我們每次在ModelAndView中添加前綴后綴了燎潮,只需要寫(xiě)視圖名稱(jsp文件名稱)。
9.訪問(wèn)項(xiàng)目靜態(tài)資源
我在寫(xiě)項(xiàng)目試扼倘,無(wú)論怎樣也無(wú)法訪問(wèn)到圖片确封。
代碼片段:![](./image/welcomebgp.png)
,返回404錯(cuò)誤再菊。
經(jīng)過(guò)排查爪喘,原因是我在web.xml
配置SpringMVC的Dispatcher是采用的下面代碼:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern> <!--注意這里-->
</servlet-mapping>
其中<url-pattern>/</url-pattern>
是指定Dispatcher的作用范圍,/
代表接受所有的url請(qǐng)求纠拔。
因此./image/welcomebgp.png
會(huì)被分發(fā)到Controller中秉剑,自然沒(méi)有對(duì)應(yīng)RequestMapping
對(duì)應(yīng),返回404錯(cuò)誤稠诲。
解決方法通常有兩種:
- 將
<url-pattern>/</url-pattern>
改成<url-pattern>*.do</url-pattern>
這樣Dispatcher就只會(huì)攔截.do
結(jié)尾的url請(qǐng)求侦鹏,正常的資源請(qǐng)求會(huì)直接到項(xiàng)目中尋找诡曙。
這樣修改的話,我們的url都要以.do
結(jié)尾略水,才能進(jìn)到Controller中价卤。 - 在dispatcher的配置文件中,加入
<mvc:resources>
聲明渊涝。
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/image/" mapping="/image/**" />
此聲明可以使url能夠訪問(wèn)項(xiàng)目下的靜態(tài)資源慎璧,而不被dispatcher影響。
其中location="/image/"
指定了資源所在位置跨释,在image
文件夾下胸私。mapping="/image/**"
指明了映射路徑,我們?cè)L問(wèn)資源時(shí)鳖谈,就要使用mapping
路徑岁疼。
比如我要訪問(wèn)項(xiàng)目根目錄image/welcome.png
資源,那么url我就要寫(xiě)url:./image/welcome.png
蚯姆。
10.GET請(qǐng)求傳入后臺(tái)亂碼問(wèn)題
在項(xiàng)目中五续,我發(fā)現(xiàn)即使在web.xml
中配置了編碼過(guò)濾器,在使用GET
方式向后臺(tái)傳值時(shí)龄恋,還是會(huì)出現(xiàn)中文亂碼疙驾。
這是因?yàn)椋幋a過(guò)濾器是針對(duì)POST
請(qǐng)求起作用的郭毕,而tomcat
是對(duì)GET
和POST
請(qǐng)求處理方式是不同的它碎。其對(duì)GET
默認(rèn)解碼方式是iso-8859-1
,因此使用其他編碼显押,自然會(huì)出現(xiàn)亂碼問(wèn)題扳肛。
解決方法:更改tomcat
對(duì)GET
默認(rèn)解碼方式。
在tomcat/conf/server.xml
中找到<Connector>
標(biāo)簽乘碑,加上URIEncoding="UTF-8"
即可挖息。
注意:可能你會(huì)發(fā)現(xiàn)這么修改還是不可以,這是因?yàn)?code>eclipse會(huì)使用自己的server.xml
配置文件兽肤,這個(gè)文件在eclipse
項(xiàng)目導(dǎo)航套腹,servers
項(xiàng)目中,打開(kāi)項(xiàng)目资铡,找到配置文件电禀,修改后應(yīng)該就可以了。
<br /><br />