maven
什么是maven
項(xiàng)目管理工具
pom
mybatis參數(shù)
## 單個(gè)javabean
默認(rèn)通過(guò)書(shū)信值引用治笨。
多個(gè)參數(shù)
Girl queryByNameFlower(@Param("name") String name,@Param("flower") String flower);
<!--SELECT * FROM girl WHERE name = #{param1} AND flower = #{param2}-->
<!--SELECT * FROM girl WHERE name = #{arg0} AND flower = #{arg1}-->
SELECT * FROM girl WHERE name = #{name} AND flower = #{flower}
map
Map<String,Object> map = new HashMap<>();
map.put("name","he");
map.put("flower","flowerLi");
sql語(yǔ)句中直接用名稱取值
多個(gè)javabean
類似于多個(gè)參數(shù),只不過(guò)參數(shù)變成了對(duì)象
一組值的傳入(List集合)
SQL標(biāo)簽
<!--foreach
collection 描述集合
open 以什么拼接符號(hào)開(kāi)頭
close 以什么結(jié)尾
item 一個(gè)數(shù)據(jù)項(xiàng)的代號(hào)
separator item之間的分隔符
index 如需使用標(biāo)號(hào)杈曲,也可使用
-->
<!--使用where標(biāo)簽,使得語(yǔ)法合法,
自動(dòng)消除多余的and,只能處理前置的and扬舒。
if標(biāo)簽里有多個(gè)條件,則用and連接凫佛。
-->
<!--例如:傳入非空值是修改讲坎,否則不修改.
set標(biāo)簽糾正語(yǔ)法,去掉后置的多余逗號(hào)愧薛。
-->
trim標(biāo)簽
<trim prefix="where" suffixOverrides="and">
<if test="city != null">
CITY = #{city} AND
</if>
<if test="country != null">
COUNTRY = #{country} AND
</if>
</trim>
解決字符串拼接問(wèn)題
1.可用sql函數(shù)
select * from address
where
city like concat('%',#{city},'%')
2.bind標(biāo)簽
<bind name="_city" value="'%'+city+'%'"/>
select * from address
where
city like #{_city}
sql標(biāo)簽
<sql id="baseCoulmn">
city,country,state
</sql>
select <include refid="baseCoulmn"/>
from address
cach緩存
默認(rèn)情況下晨炕,一級(jí)緩存是開(kāi)啟的,且無(wú)法關(guān)閉厚满。
一級(jí)緩存是單個(gè)會(huì)話級(jí)別的
- 如果關(guān)閉會(huì)話府瞄,緩存失效碧磅。
- 如果會(huì)話過(guò)程有增刪改操作碘箍,則緩存失效遵馆。
- java中 sqlSession.clearCache();清掉所有緩存
二級(jí)緩存是多個(gè)會(huì)話級(jí)別的
<setting name="cacheEnabled" value="true">
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
多表查詢映射
<resultMap id="rMap" type="javaClass">
<id property="id" column="id"/>
<result property="id" column="id"/>
<association property="\\class" javaType="">
<result property="" column=""/>
</association>
</resultMap>
<!--
collection標(biāo)簽用來(lái)描述集合
ofType是描述集合里的一個(gè)元素的類型
-->
List<Comment> comments;
<collection property="comments"
ofType="self.he.pojo.Comment">
<id property="id" column="cid"/>
<result property="content" column="commentContent"/></collection>
spring
- 添加spring依賴
- 編寫(xiě)spring的配置文件
- 通過(guò)spring應(yīng)用程序上下文獲取對(duì)象
1.依賴
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
2.配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--將對(duì)象的創(chuàng)建-交給spring容器,
在配置文件里聲明需要的對(duì)象丰榴。
class:Java類的全限定名
id: 此對(duì)象的昵稱方便區(qū)分-->
<bean class="self.he.pojo.Girl" id="girl">
</bean>
</beans>
3.java代碼
public class Girl {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public void m1(){
//獲取上下文對(duì)象货邓,spring里面聲明對(duì)象都需要通過(guò)上下文獲取
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//通過(guò)此對(duì)象獲取girl
Girl g = (Girl) ctx.getBean("girl");
System.out.println(g);
}
核心內(nèi)容
- IOC
- AOP
IOC
概念:控制反轉(zhuǎn)。
將對(duì)象的創(chuàng)建交給Spring容器四濒。
值的注入:
-
setter注入(最常用)
必須有setter方法换况,如:name setName()
用property標(biāo)簽注入
<bean class="self.he.pojo.PrettyGirl" id="girl"> <property name="name" value="王妃"/> </bean>
非字面值的注入問(wèn)題:使用ref指向另一個(gè)bean
<bean class="self.he.pojo.Dog" id="dog"> <property name="name" value="汪汪"/> </bean> <bean class="self.he.pojo.PrettyGirl" id="girl"> <property name="dog" ref="dog"/> </bean>
-
String[]
<property name="friends"> <array> <value>鈺子</value> <value>雨子</value> <value>呀子</value> </array> </property>
-
List<>
<property name="nums"> <list> <value>1</value> <value>3</value> <value>4</value> </list> </property>
-
set<>
-
<property name="grils"> <set> <bean class="self.he.pojo.Girl"> <property name="age" value="18"/> <property name="name" value="Li"/> </bean> <bean class="self.he.pojo.Girl"> <property name="age" value="11"/> <property name="name" value="She"/> </bean> </set>
Map<>
<property name="goddessMap"> <map> <entry key="Li"> <bean class="self.he.pojo.Goddess"> <property name="name" value="Li"/> <property name="hair" value="Red"/> </bean> </entry> <entry key="Di"> <bean class="self.he.pojo.Goddess"> <property name="name" value="Di"/> <property name="hair" value="Black"/> </bean> </entry> </map> </property>
-
構(gòu)造器注入
默認(rèn)使用無(wú)參構(gòu)造器
constructor-arg標(biāo)簽
<bean class="self.he.pojo.Cat" id="girl"> <constructor-arg name="name" value="Li"/> <constructor-arg name="color" value="red"/> </bean>
bean標(biāo)簽的探討:
- abstract:抽象
- parent:繼承bean標(biāo)簽
- destory-method: 這個(gè)bean銷毀是執(zhí)行的方法。容器close(),refresh()
- init-method: 初始化時(shí)使用的方法盗蟆。
- scope:指定范圍
- singleton:單例戈二,spring上下文
- prototype:原型
- lazy-init: true使用時(shí)初始化。
- depends-on: 依賴bean喳资,如果bean的使用嚴(yán)重依賴于另一個(gè)bean觉吭。
alias標(biāo)簽:
注入別名
<alias name="dog" alias="gdog"/>
自動(dòng)注入,autowire屬性
byType
byName
constructor:根據(jù)構(gòu)造器的參數(shù)名去匹配bean仆邓。
no
<!--byType 在上下文中鲜滩,根據(jù)類型尋找cat 中的屬性 girl,并以賦值节值,有且只有一個(gè)徙硅,否則報(bào)錯(cuò)--> <bean class="self.he.pojo.Cat" id="cat" autowire="byType"> <property name="name" value="佩奇"/> <property name="color" value="pik"/> </bean> <bean class="self.he.pojo.Girl"> <property name="name" value="Li"/> <property name="age" value="18"/> </bean> <bean class="self.he.pojo.Cat" id="girl"> <constructor-arg name="name" value="Li"/> <constructor-arg name="color" value="red"/>
resource
Xml文件里引入其他properties文件:
<context:property-placeholder location="classPath:xxx.properties"/> <!--用表達(dá)式${}去引用properties的屬性的值,-->
一個(gè)配置文件引入其他配置文件:classPath的根目錄是resource目錄
<import resource="classPath:xxx.xml"/>
常用注解
xml中要激活注解:
<context:component-scan base-package="self.he"/>
- component
- controller
- service
- repository
- autowired自動(dòng)注入
AOP
概念
面向切面編程搞疗。
依賴包:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1 aop是基于代理完成的嗓蘑,所以要激活自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--2 注冊(cè)切面-->
<bean class="self.he.advice.BeforeAdvice" id="beforeAdvice">
</bean>
<!--3 配置切入點(diǎn)等信息-->
<aop:config>
<aop:aspect id="beforeAspect" ref="beforeAdvice">
<!--aop:before 表明前置通知
method:指明使用哪個(gè)方法切
pointcut:切入點(diǎn)
包,類匿乃,方法
-->
<aop:before method="methodBefore" pointcut="execution(* self.he.service.ProviderService.*(..))"></aop:before>
</aop:aspect>
</aop:config>
<bean class="self.he.service.ProviderService"
id="providerService"></bean>
</beans>
execution()表達(dá)式:
例如:execution(* self.he.service.ProviderService.*(..))
測(cè)試
@Test
public void m1(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
//不是spring管理的bean脐往,織入無(wú)效。
ProviderService providerService = new ProviderService();
providerService.add();
ProviderService providerService1 = ctx.getBean("providerService", ProviderService.class);
providerService1.add();
}
返回執(zhí)行:after-returning
<aop:after-returning method="AfterReturn" returning="returning" pointcut="execution(* self.he.service.HelloService.*(..))"/>
注解模式
xml文件
<!--1 自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--2 配置自動(dòng)掃描包-->
<context:component-scan base-package="self"/>
切面:
@Aspect//標(biāo)記為一個(gè)切面
@Component//標(biāo)記為一個(gè)組件扳埂,相當(dāng)于在xml中注冊(cè)一個(gè)bean
public class BeforeAdvice {
@Before("execution(* self.she.service.HelloService.hello(String,String))")
//獲取方法名业簿,參數(shù)
public void before(JoinPoint joinPoint){
System.out.println("before!!!!!"+joinPoint.getSignature().getName()+ Arrays.toString(joinPoint.getArgs()));
}
@Before("execution(* self..*.*(..))")
public void before2(){
System.out.println("before2!!!");
}
}
切點(diǎn):
@Component
public class HelloService {
public void hello(String name,String sex){
System.out.println("hello "+name+"!"+sex+"!!!");
}
public String eat(){
System.out.println("eating!!!!");
return "Li";
}
}
注解方式獲得bean
配置類
@Configuration
@ComponentScan(value = "self.she")
public class SpringConfig {
@Bean("girl")
public Girl creatGirl(){
Girl girl = new Girl();
girl.setName("Li");
return girl;
}
}
測(cè)試:
@Test
public void m1(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Girl girl = ctx.getBean("girl",Girl.class);
System.out.println(girl.getName());
}
springMVC
簡(jiǎn)介
springMVC是一個(gè)web層的框架。
model 模型
view 視圖
controller 控制器
一種設(shè)計(jì)模式阳懂,將責(zé)任進(jìn)行拆分梅尤,不同組件負(fù)責(zé)不同功能。
好處:
- 結(jié)構(gòu)清晰
- 更好維護(hù)
壞處:
- 更加復(fù)雜
入門(mén)體驗(yàn)
1.創(chuàng)建web項(xiàng)目
2.編寫(xiě)web.xml岩调,注冊(cè)一個(gè)特殊的servlet巷燥,前端控制器
3.編寫(xiě)一個(gè)springMVC的配置文件
- 注冊(cè)一個(gè)視圖解析器
4.編寫(xiě)一個(gè)控制器
5.編寫(xiě)一個(gè)結(jié)果頁(yè)面
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注冊(cè)一個(gè)前端控制器-->
<servlet>
<!--這里名字有講究,
如果不修改spring配置文件的默認(rèn)位置号枕,那么springmvc
會(huì)去web-inf下找一個(gè)springmvc-servlet.xml的文件-->
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!--servlet映射配置-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--統(tǒng)一寫(xiě)/-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
pom.xml:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
控制器代碼:
package self.he.controller;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Nullable
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mav = new ModelAndView();
mav.addObject("girl","Li");
mav.setViewName("girl");
return mav;
}
}
視圖代碼:
<%--
Created by IntelliJ IDEA.
User: he
Date: 2019/2/13
Time: 16:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${girl}
</body>
</html>
解釋分析
web.xml
注冊(cè)前端控制器缰揪,目的讓springmvc去處理請(qǐng)求
<!--servlet映射配置-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--統(tǒng)一寫(xiě)/-->
<url-pattern>/</url-pattern>
</servlet-mapping>
url-pattern的寫(xiě)法問(wèn)題:
- /
- /* (永遠(yuǎn)不要這樣寫(xiě),請(qǐng)求helloController時(shí)葱淳,過(guò)去后視圖為girl.jsp钝腺,又將girl.jsp作為請(qǐng)求再去訪問(wèn)controller)
- *.do
springMVC配置文件名
web.xml
默認(rèn)情況下使用dispatcherServlet的名字作為命名空間
[servlet-name]-servlet.xml (WEB-INF)下尋找
[servlet-name]-servlet=namespace
<servlet>
<!--這里名字有講究抛姑,
如果不修改spring配置文件的默認(rèn)位置,那么springmvc
會(huì)去web-inf下找一個(gè)springmvc-servlet.xml的文件-->
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--重新命名配置文件名-->
<init-param>
<param-name>namespace</param-name>
<param-value>mvc</param-value>
</init-param>
</servlet>
配置文件默認(rèn)在WEB-INF下艳狐,但是maven項(xiàng)目要求在resources目錄下定硝。
解決:重新指定上下文位置即可web.xml
<init-param>
<!--上下文配置的位置的指定-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
此時(shí)在類路徑下尋找mvc.xml
視圖解析器
springMVC支持多種視圖技術(shù)
- jsp
- freemaker(模板技術(shù))
內(nèi)部的資源視圖解析器
-
視圖前綴
-
/jsp/ 請(qǐng)求響應(yīng)的資源路徑配置
viewName:girl /jsp/girl
-
-
后綴
- .jsp 此時(shí)前綴+視圖名+后綴 = /jsp/girl.jsp
注解開(kāi)發(fā)模式
基本注解;
- @Controller
- @RequestMapping
開(kāi)發(fā)步驟
1.配置注解掃描包
<!--配置注解掃描包-->
<context:component-scan base-package="self.he.controller"/>
<!--配置一個(gè)視圖解析器
常用內(nèi)部資源視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--1 前綴-->
<property name="prefix" value="/jsp/"/>
<!--2 后綴-->
<property name="suffix" value=".jsp"/>
</bean>
2.在指定類上添加@Controller注解
3.添加@RequestMapping
@Controller//不需要繼承任何類
@RequestMapping("/bye")
public class ByeController {
@RequestMapping("/bye")
public String bye(Model model){
model.addAttribute("model","Li");
// return的是ViewName
//此時(shí)去的/jsp/bye.jsp
return "bye";
}
@RequestMapping("/goodBye")
public String goodBye(Model model){
model.addAttribute("model","Lily");
return "bye";
}
}
list 問(wèn)題
導(dǎo)入依賴
<!--jstl依賴-->
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
controller:
@RequestMapping("/byeBye")
public String byeBye(Model model){
List<People> list = new ArrayList<>();
People p1 = new People();
p1.setName("Li");
p1.setSex("girl");
People p2 = new People();
p2.setName("He");
p2.setSex("boy");
list.add(p1);
list.add(p2);
model.addAttribute("model",list);
return "byeBye";
}
jsp:
<c:forEach items="${model}" var="obj">
<tr>
<td>${obj.name}</td>
<td>${obj.sex}</td>
</tr>
</c:forEach>
轉(zhuǎn)發(fā)與重定向
轉(zhuǎn)發(fā)到頁(yè)面
-
重定向到另一個(gè)頁(yè)面redirect:path
@RequestMapping("redirect") public String redirect(Model model){ model.addAttribute("model","hello"); return "redirect:/jsp/redirect.jsp"; }
轉(zhuǎn)發(fā)到另一個(gè)控制器forward:path
// 模擬請(qǐng)求 @RequestMapping("/request") public String request(WebRequest request){ System.out.println(request.getParameter("girl")); return "forward"; }
@RequestMapping
- @RequestMapping("/m1")
- value 寫(xiě)的是路徑,是一個(gè)數(shù)組的形式毫目,可匹配多個(gè)路徑蔬啡,path與 value對(duì)等
- @RequestMapping(value={"m1","m2"})
- method 指定接收的請(qǐng)求類型,如果沒(méi)寫(xiě)就所有類型都接收
- @RequestMapping(value={"m1","m2"}, method= RequestMethod.GET)
- params 可以指定參數(shù)
- @RequestMapping(value="/m1"镀虐,params={"girl","boy"})
- 可以指定值params={"girl=王妃","boy箱蟆!=愛(ài)卿"}
- header 能夠影響瀏覽器的行為
- consumers 消費(fèi)者,媒體類型刮便,可以限定必須為application/json;chartset=UTF-8
- produces 產(chǎn)生的響應(yīng)的類型
請(qǐng)求路徑的問(wèn)題
Springmvc支持的ant風(fēng)格
@RequestMapping("/Li?")
- 顽腾?任意的字符,斜杠除外
- *表示0-n,任意個(gè)字符都行诺核,斜杠除外
- /** 支持任意層路徑
@GetMapping抄肖,@PostMapping.....
- getMapping 只限定了get請(qǐng)求
- postMapping 只限定了post請(qǐng)求
對(duì)于非get post請(qǐng)求的支持
需要有額外的內(nèi)容添加,要增加一個(gè)過(guò)濾器來(lái)處理窖杀。
過(guò)濾器:
<!--注冊(cè)一個(gè)支持所有http請(qǐng)求類型的過(guò)濾器-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
表單還要添加隱藏參數(shù);
delete
<form action="${ctx}/he/m1" method="post">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="提交"/>
</form>
關(guān)于靜態(tài)資源訪問(wèn)的問(wèn)題
用于在web.xml中設(shè)置了servlet的url匹配方式為/ 漓摩,所以靜態(tài)資源也當(dāng)做一個(gè)后臺(tái)請(qǐng)求。
解決方式:
1.交給默認(rèn)servlet處理入客。不讓DispatcherServlet處理管毙。
在mvc配置文件中加
<!--默認(rèn)servlet處理者,識(shí)別MIME類型-->
<!--默認(rèn)servlet處理者,只加它注解會(huì)失效-->
<mvc:default-servlet-handler/>
<!--重新激活注解模式-->
<mvc:annotation-driven/>
2.通過(guò)映射關(guān)系描述
<mvc:resources mapping="/static/css/*" location="static/css/"/>
3.在web.xml定義映射規(guī)則
@PathVariable
路徑變量桌硫。
@RequestMapping("/add/{name}/{sex}")
public String addPeople(@PathVariable("name") String name,@PathVariable("sex")String sex){
System.out.println(name+":"+sex);
return "forward";
}
@Responsebody
返回?cái)?shù)據(jù)夭咬,一般情況下返回json格式數(shù)據(jù)。
@PutMapping("/put")
@ResponseBody//需要額外的json包的支持
public String putPeople(String name){
System.out.println(name+":");
// Map<String,String> map = new HashMap<>();
// map.put("msg","ok");
return "ok";
}
@RequestBody
json數(shù)據(jù)铆隘,不是通過(guò)form表單傳遞
ajax({
? data:
? } )
@SessionAttributes
用在類上面卓舵,將模型自動(dòng)填充到會(huì)話里去。
@Controller
@RequestMapping("/people2")
@SessionAttributes("people")
public class People2Controller {
@RequestMapping("/login3")
public String login3(@ModelAttribute People people) {
System.out.println(people.getName());
return "redirect:/jsp/login.jsp";
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${sessionScope.people.name}
</body>
</html>
@SessionAttribute
要求當(dāng)前會(huì)話里必須要有某個(gè)對(duì)象膀钠。
public String login3(@SessionAttribute People people) {
System.out.println(people.getName());
return "redirect:/jsp/login.jsp";
}
關(guān)于post請(qǐng)求中文亂碼問(wèn)題
添加過(guò)濾器掏湾,springmvc提供過(guò)濾器。
<!--指定編碼,這段配置要放在所有filter的最前面肿嘲,否則會(huì)不生效-->
<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>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
關(guān)于form表單提交數(shù)據(jù)方式
方式一:通過(guò)屬性名綁定
put people
<form action="${ctx}/people/put" method="post">
<input type="hidden" name="_method" value="put"/>
<input type="text" name="name"/><br>
<input type="password" name="sex"/><br>
<input type="submit" value="提交"/>
</form>
@PutMapping("/put")
@ResponseBody//需要額外的json包的支持
public String putPeople(String name,String sex){
System.out.println(name+":"+sex);
// Map<String,String> map = new HashMap<>();
// map.put("msg","ok");
return "ok";
}
方式二:@RequestParam()
@PutMapping("/put")
@ResponseBody//需要額外的json包的支持
public String putPeople(@RequestParam("name")String name,@RequestParam("sex")String sex){
System.out.println(name+":"+sex);
// Map<String,String> map = new HashMap<>();
// map.put("msg","ok");
return "ok";
}
方式三:直接用pojo形式
@PutMapping("/put")
@ResponseBody//需要額外的json包的支持
public String putPeople(People people){
System.out.println(people.getName()+":"+people.getSex());
return "ok";
}
關(guān)于表單提交date類型數(shù)據(jù)問(wèn)題
put people and date
<form action="${ctx}/people/date" method="post">
<input type="date" name="date"/><br>
<input type="submit" value="提交"/>
</form>
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
@PostMapping("/date")
@ResponseBody//需要額外的json包的支持
public String postPeople(People people){
System.out.println("hhhh");
System.out.println(people.getDate());
return "ok";
}
2.在屬性上添加注解
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
@ModelAttribute可解決頁(yè)面間數(shù)據(jù)交換
使用方式一:
//在controller里任意一個(gè)方法執(zhí)行前執(zhí)行
@ModelAttribute
public People init(){
System.out.println("init........");
People people = new People();
people.setName("Li");
return people;
}
@RequestMapping("/login")
public String login(Model model){
System.out.println(model.containsAttribute("people"));
return "forward";
}
方法二:
@ModelAttribute("people")
public void init(Model model){
System.out.println("init........");
People people = new People();
people.setName("Li");
model.addAttribute("people",people);
}
方法三:
如果請(qǐng)求頁(yè)面?zhèn)髁藀eople則使用請(qǐng)求的值融击,如果沒(méi)有則使用默認(rèn)的。
可用于頁(yè)面間數(shù)據(jù)交換雳窟。
@RequestMapping("/login2")
public String login2(@ModelAttribute People people){
System.out.println(people.getName());
return "login";
}
post people to other page
<form action="${ctx}/people2/login2" method="post">
<input type="text" name="name"/><br>
<input type="password" name="sex"/><br>
<input type="submit" value="提交"/>
</form>
后臺(tái)傳json給前端
1.導(dǎo)入json解析依賴
<!--json依賴-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
2.利用@ResponseBody
@RequestMapping("m1")
@ResponseBody
public People m1(){
People people = new People();
people.setName("Li");
people.setSex("girl");
people.setDate(new Date());
return people;
}
前臺(tái)解析json:
<script>
$(function () {
$("#b").click(function () {
$.ajax({
url:'${ctx}/json/m1',
type:'post',
success:function (data) {
alert(data.name+":"+data.sex)
}
})
})
})
</script>
前臺(tái)ajax給后臺(tái)傳json
注意 contentType:'application/json',不可缺
$("#bb").click(function () {
var obj={
'name':'Li 李',
'sex':'girl'
};
$.ajax({
url:'${ctx}/json/m2',
type:'post',
contentType:'application/json',
data:JSON.stringify(obj),
success:function (data) {
alert(data.name);
}
})
})
后臺(tái)用注解@RequestBody接收
//接收前臺(tái)傳來(lái)的json
@RequestMapping("/m2")
@ResponseBody
public People m1(@RequestBody People people){
System.out.println(people.getName());
People people = new People();
people.setName("Li");
people.setSex("girl");
people.setDate(new Date());
return people;
}
@RestController=@Controller+@ResponseBody
xml解析傳輸
很多第三方開(kāi)發(fā)會(huì)使用xml傳輸數(shù)據(jù)尊浪,例如:微信
1.添加xml依賴
<!--xml依賴-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.8</version>
</dependency>
2.@RequestMapping
@RequestMapping(value = "/m1",produces ={MediaType.APPLICATION_XML_VALUE})
@ResponseBody
public People m1(){
People people = new People();
people.setName("Lily");
people.setSex("girl");
people.setDate(new Date());
return people;
}
文件上傳
1.加入依賴
<!--Apache文件上傳依賴-->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2.在springmvc配置文件中注冊(cè)文件上傳解析器
<!--文件上傳解析器,
id="multipartResolver"只能是這個(gè),源代碼規(guī)定的
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--定義最大文件上傳大小,byte-->
<property name="maxUploadSize" value="1024000"/>
<!--指定上傳的編碼-->
<property name="defaultEncoding" value="UTF-8"/>
<!--單個(gè)文件最大大小-->
<property name="maxUploadSizePerFile" value="200000"/>
</bean>
3.上傳頁(yè)面
<%--
Created by IntelliJ IDEA.
User: he
Date: 2019/2/15
Time: 9:39
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
單文件提交:
<form action="${ctx}/file/upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="file"/><br>
<input type="submit" value="提交">
</form>
<br>
多文件提交:
<form action="${ctx}/file/upload2" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="file"/><br>
文件2:<input type="file" name="file"/><br>
文件3:<input type="file" name="file"/><br>
文件4:<input type="file" name="file"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
4.響應(yīng)控制類
private static String uploadPath = "E:"+ File.separator;
@RequestMapping("/upload")
public String upload(@RequestParam("file")MultipartFile multipartFile, Model model){
//1.傳到哪里去拇涤。2.數(shù)據(jù) 3.傳的細(xì)節(jié)
if (multipartFile != null && !multipartFile.isEmpty()){
//不空再傳
//1.獲得文件名
String originalFilename = multipartFile.getOriginalFilename();
//2.截取文件名前綴
String fileNamePrefix = originalFilename.substring(0,originalFilename.lastIndexOf('.'));
//3.構(gòu)建新文件名 前綴+時(shí)間戳
String newFilePrefix = fileNamePrefix+new Date().getTime();
//4.得到新文件名
String newFileName =newFilePrefix+originalFilename.substring(originalFilename.lastIndexOf('.'));
//5.構(gòu)建文件對(duì)象
File file = new File(uploadPath+newFileName);
//6.寫(xiě)入文件
try {
multipartFile.transferTo(file);
model.addAttribute("fileName",newFileName);
} catch (IOException e) {
e.printStackTrace();
}
}
return "uploadSuc";
}
@RequestMapping("/upload2")
public String upload2(@RequestParam("file") MultipartFile[] multipartFiles,Model model){
List<String> fileNames = new ArrayList<>();
System.out.println(multipartFiles != null && multipartFiles.length >0);
if (multipartFiles != null && multipartFiles.length >0){
for (MultipartFile multipartFile:multipartFiles) {
if (multipartFile != null && !multipartFile.isEmpty()){
//不空再傳
//1.獲得文件名
String originalFilename = multipartFile.getOriginalFilename();
//2.截取文件名前綴
String fileNamePrefix = originalFilename.substring(0,originalFilename.lastIndexOf('.'));
//3.構(gòu)建新文件名 前綴+時(shí)間戳
String newFilePrefix = fileNamePrefix+new Date().getTime();
//4.得到新文件名
String newFileName =newFilePrefix+originalFilename.substring(originalFilename.lastIndexOf('.'));
//5.構(gòu)建文件對(duì)象
File file = new File(uploadPath+newFileName);
//6.寫(xiě)入文件
try {
multipartFile.transferTo(file);
fileNames.add(newFileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
model.addAttribute("fileNames",fileNames);
return "uploadSuc";
}
文件下載
@RequestMapping("/down")
public void fileDown(HttpServletResponse response){
//通過(guò)輸出流寫(xiě)入客戶端
// response.setCharacterEncoding("UTF-8");
//1.獲取下載文件名
String fileName = "哈哈.jpg";
//2.構(gòu)建一個(gè)文件對(duì)象捣作,通過(guò)Paths工具類獲得Path對(duì)象
Path path = Paths.get(uploadPath,fileName);
//3.判斷它是否存在
if(Files.exists(path)){
//存在則下載
//4.設(shè)定response的響應(yīng)類型
//獲取文件后綴
String fileSuffix = fileName.substring(fileName.lastIndexOf('.')+1);
//設(shè)置contentType
response.setContentType("application/"+fileSuffix);
try {
//ISO8859-1編碼
response.addHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes("UTF-8"),"ISO8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(fileSuffix);
//5 通過(guò)Path寫(xiě)出去
try {
Files.copy(path,response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事項(xiàng): //ISO8859-1編碼
response.addHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes("UTF-8"),"ISO8859-1"));
避免中文無(wú)法識(shí)別
攔截器
通過(guò)實(shí)現(xiàn)HandlerInterceptor
- 前置處理
- 后置處理
- 完成處理
案例:
登錄請(qǐng)求攔截,如果session有user工育,不攔截虾宇,沒(méi)有則攔截搓彻,但/user/login不攔截如绸。
1.攔截類
package self.he.interceptors;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import self.he.pojo.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SessionInterceptor implements HandlerInterceptor{
private static final Logger LOGGER = Logger.getLogger(SessionInterceptor.class);
//檢查當(dāng)前會(huì)話是否有User,有則放行旭贬,沒(méi)有則攔截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("SESSION_USER");
if(user == null){
LOGGER.warn("沒(méi)有權(quán)限怔接,請(qǐng)先登錄!");
return false;
}
if(user instanceof User){
//查數(shù)據(jù)庫(kù)檢查
User u = (User)user;
u.setPwd(null);
request.getSession().setAttribute("SESSION_USER",u);
LOGGER.info(u.getName()+"會(huì)話中稀轨。扼脐。");
return true;
}else {
LOGGER.warn("不要搞事,請(qǐng)先登錄奋刽!");
return false;
}
}
}
2.配置攔截器
<!--攔截器配置-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/*"/>
<bean class="self.he.interceptors.MethodTimerInterceptor">
</bean>
</mvc:interceptor>
<mvc:interceptor>
<!-----------------------------------------------
攔截user下的瓦侮,但login除外
-->
<mvc:mapping path="/user/**/*"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class="self.he.interceptors.SessionInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
控制類:
package self.he.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import self.he.pojo.User;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(User user, HttpSession session){
if(user != null&& user.getName()!= null && user.getName().equals("Li")){
//(數(shù)據(jù)庫(kù)檢查)
session.setAttribute("SESSION_USER",user);
return "user";
}
System.out.println("....login...........");
return "redirect:/login.jsp";
}
@RequestMapping("/delete")
public String delete(){
System.out.println("....可以為所欲為了delete...........");
return "user";
}
}
攔截器執(zhí)行順序問(wèn)題
有N個(gè)攔截器,都能攔截同一個(gè)URI時(shí)佣谐,執(zhí)行順序:
在springmvc配置中配置的順序有關(guān)肚吏。配置在前的先執(zhí)行赶盔。
前置處理與后置處理順序剛好相反胜臊。