SSM學(xué)習(xí)筆記

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í)別的

  1. 如果關(guān)閉會(huì)話府瞄,緩存失效碧磅。
  2. 如果會(huì)話過(guò)程有增刪改操作碘箍,則緩存失效遵馆。
  3. 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

  1. 添加spring依賴
  2. 編寫(xiě)spring的配置文件
  3. 通過(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的配置文件

  1. 注冊(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í)行赶盔。

前置處理與后置處理順序剛好相反胜臊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骗卜,一起剝皮案震驚了整個(gè)濱河市革半,隨后出現(xiàn)的幾起案子擦俐,更是在濱河造成了極大的恐慌培慌,老刑警劉巖蹦浦,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓣戚,死亡現(xiàn)場(chǎng)離奇詭異镐牺,居然都是意外死亡炫掐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)睬涧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卒废,“玉大人,你說(shuō)我怎么就攤上這事宙地∷と希” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵宅粥,是天一觀的道長(zhǎng)参袱。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么抹蚀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任剿牺,我火速辦了婚禮,結(jié)果婚禮上环壤,老公的妹妹穿的比我還像新娘晒来。我一直安慰自己,他們只是感情好郑现,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布湃崩。 她就那樣靜靜地躺著,像睡著了一般接箫。 火紅的嫁衣襯著肌膚如雪攒读。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天辛友,我揣著相機(jī)與錄音薄扁,去河邊找鬼。 笑死废累,一個(gè)胖子當(dāng)著我的面吹牛邓梅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邑滨,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼日缨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了驼修?” 一聲冷哼從身側(cè)響起殿遂,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乙各,沒(méi)想到半個(gè)月后墨礁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耳峦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年恩静,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹲坷。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驶乾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出循签,到底是詐尸還是另有隱情级乐,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布县匠,位于F島的核電站风科,受9級(jí)特大地震影響撒轮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贼穆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一题山、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧故痊,春花似錦顶瞳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至豫领,卻和暖如春抡柿,著一層夾襖步出監(jiān)牢的瞬間舔琅,已是汗流浹背等恐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留备蚓,地道東北人课蔬。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像郊尝,于是被迫代替她去往敵國(guó)和親二跋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容