springMVC課程02

一、在springmvc中,json數據裏面的data參數裏面必須用雙引號,才能傳到後臺一json對象,而後才能被@RequestBody轉成javabean對象,而且要在外面用單引號括起來(傳json整個數據的時候)--在springmvc裏面用的多------

若是不加單引號,傳遞過去的就是一個參數鍵值對,而不是一個完整的json對象
                        contentType:'application/json;charset=utf-8',
data:'{"name":"黑妹牙膏","price":"999"}',


二、傳參數的時候,data參數是一個對象,{},外面若是加雙引號或者單引號,會得不到數據(struts2)


1、內容回顧:

線程安全概念:

線程安全:屢次訪問同一個對象/變量,獲得同一個結果
線程不安全:屢次訪問同一個對象/變量,獲得不一樣結果

一、springmvc是否線程安全

安全,springmvc底層是servlet,是單例

二、i++,++i是否線程安全

成員變量:線程不安全
public class A{
    int i=9;
    i++;
}

三、有了struts2,爲何還須要使用springmvc?

①、底層實現機制:struts2:過濾器    springmvc:servlet
②、運行效率:struts2 :多例運行 很耗資源    springmvc:單例,比struts快
③、參數封裝:struts2:基於屬性進行封裝        springmvc:基於方法進行封裝---方法參數是局部變量,方法執行結束,方法變量內存釋放。

2、springmvc相關注解

一、@RequestMapping註解的幾種使用

         * 1,@RequestMapping("itemsList")
* 2,@RequestMapping("/itemsList")
* 3,@RequestMapping("itemsList.do")    --前提是web.xml裏面配置的路徑爲    *.do
* 4,@RequestMapping(value="itemsList")
* 5,@RequestMapping(value="itemsList",method=RequestMethod.POST)
* 6,@RequestMapping(value="itemsList",method=RequestMethod.GET)
* 7,@RequestMapping(value="itemsList",method={RequestMethod.GET,RequestMethod.POST})
               (href,直接經過瀏覽器發送都是get請求;form表單,ajax指定post,都是post)

二、@RequestParam註解:

       * 功能:
* 1,設置默認值(若是頁面傳遞值爲null,自動設置爲默認值) @RequestParam(defaultValue="2")
* 2,設置別名 (若是頁面傳遞參數名稱和方法接受參數名稱不一致,設置別名) @RequestParam(value="ids")
* 同時設置:
* @RequestParam(defaultValue="2",value="ids")

三、商品更新

   
   
   
   
/** * 需求:根據id更新商品數據 * 請求:/item/updateSubmit * 參數:item * 返回值:重定向商品列表 */ @RequestMapping("/item/updateSubmit") public String updateSubmit(Item item){ itemService.updateItemByID(item); return "redirect:/itemsList.do"; }
    
    
    
    
<!-- 商品更新 --> <update id="updateItemByID" parameterType="item" > update items set name=#{name},price=#{price},detail=#{detail},pic=#{pic},createtime=#{createtime} where id=#{id} </update>


四、窄化請求映射
在class上添加@RequestMapping(url)指定通用請求前綴, 限制此類下的全部方法請求url必須以請求前綴開頭,經過此方法對url進行分類管理。
 這種狀況就會一個路徑能夠找到兩個方法,產生錯誤
以下:
@RequestMapping放在類名上邊,設置請求前綴 
@Controller
@RequestMapping("/item")

方法名上邊設置請求映射url:
@RequestMapping放在方法名上邊,以下:
@RequestMapping("/queryItem ")

訪問地址爲:/item/queryItem


五、重定向和轉發

    ①、重定向:
        return "redirect:/itemsList.do"    /在下面這種狀況不能省略
   
   
   
   
@RequestMapping("/item/updateSubmit") public String updateSubmit(Item item){ itemService.updateItemByID(item); return "redirect:itemsList.do"; }
           這種方式重定向的路徑爲   /item/itemList.do
           若是兩個方法的路徑在同一級的話,那麼 / 能夠去掉(這是下面說的本類重定向)-----不是在同一個類裏面也能夠,同一級就行
         * 需求:重定向
* 本類重定向:
* 1,return "redirect:list.html"
* 2,return "redirect:/red/list.html"
* 跨類重定向:
* 1,return "redirect:/itemsList.html"    必需要有 /  或者根路徑
        ②、轉發:
   
   
   
   
@Controller@RequestMapping("for")public class ForwardController { @RequestMapping("list") public String list(){ System.out.println("hhhhhh"); return null; } /** * 需求:轉發 * 本類轉發: * 語法: * 1,return "forward:list.html" * 2,return "forward:/red/list.html" * 跨類轉發: * 1,return "forward:/itemsList.html" */ public String forward(){ //return "forward:/red/list.html"; //本類轉發: //子路徑 //return "forward:list.html"; //return "forward:/for/list.html"; //跨類轉發: return "forward:/itemsList.do"; }}


六、json轉換註解:

@RequestBody:  請求    把json格式請求參數轉換爲javabean
@ResponseBody:  響應    把javabean對象自動轉換json對象,返回頁面
註解支持:一、mvc註解驅動    二、Jackson包支持    三、請求json,返回json都是js操做
須要配置     <mvc:annotation-driven />
①、在springmvc中,json數據裏面的data參數裏面必須用雙引號,而且要在外面用單引號括起來(傳json整個數據的時候)--在springmvc裏面用的多------

                        contentType:'application/json;charset=utf-8',
data:'{"name":"黑妹牙膏","price":"999"}',


②、傳參數的時候,data參數是一個對象,{},外面若是加雙引號或者單引號,會得不到數據(struts2)
   
   
   
   
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script><script type="text/javascript"> function reqJson (){ $.ajax({ type:"post", url:'${pageContext.request.contextPath}/reqJson.do', contentType:'application/json;charset=utf-8', data:'{"name":"黑妹牙膏","price":"999"}', success:function(data){ //返回json對象 alert(data.name); } }) }</script><title>Insert title here</title></head><body> <button onclick="reqJson();" >請求json,返回json格式的數據</button></body></html>
    
    
    
    
@Controllerpublic class JsonController { /** * 需求:跳轉傳遞參數頁面 */ @RequestMapping("json") public String json(){ return "reqJson"; } /** * 需求:接受json格式參數,返回json對象 * @requestBody:接受json格式參數,自動把json格式參數自動轉換對象 * @responseBody:自動把返回對象轉換成json格式返回 */ @RequestMapping("reqJson") @ResponseBody public Item reqJson(@RequestBody Item item){ System.out.println(item); return item; }}


七、springmvc的異常處理:

 
①、定義一個可預期的異常類
   
   
   
   
public class CustomException extends Exception { //定義一個字符串變量,封裝自定義異常信息 private String message; public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } //構造函數,封裝異常信息 public CustomException(String message) { super(message); this.message=message; }}
②、建立異常處理器:
   
   
   
   
public class ExceptionResolve implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object obj, Exception ex) { CustomException ce=null; //判斷異常信息是不是自定義異常 if (ex instanceof CustomException) { ce=(CustomException) ex; }else{ //運行時異常信息 ce = new CustomException("運行時異常,請聯繫管理員!"); } ModelAndView mv = new ModelAndView(); //設置異常數據 mv.addObject("ex", ce.getMessage()); mv.setViewName("error/error"); return mv; }}
③、在springmvc.xml裏面配置異常處理器
<!-- 配置全局異常處理器 -->
    <bean class="com.itcast.utils.ExceptionResolve" ></bean>


八、文件上傳

 


①、方案:建立一個單獨的服務器,單純存儲圖片,兩臺服務器的交互,異步上傳
②、需求:上傳圖片,頁面不刷新,圖片立馬回顯,存在另外一臺服務器,跨服務器
③、技術:ajax            jersy-io(跨服務器)    commons-io、commons-fileupload(上傳)
④、文件上傳的環境
 ⑤、springmvc.xml中配置上傳文件的解析器
 注意:必須配置 id ,而且爲   multipartResolver  
    
    
    
    
<!-- 上傳文件解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name="maxUploadSize" value="10240000" ></property><!-- 單位字節 --> </bean>
⑥、圖片服務器搭建
           建立新的服務器:
              修改新的服務器的端口號:
 
 
           修改服務器權限:
 
 ⑦、ajax異步上傳:
             jsp頁面:
    
    
    
    

  1. </form>
<form id="itemForm" action="${pageContext.request.contextPath}/item/updateSubmit" method="post" >
<td> <!-- 圖片回顯 --> <img id="imgSize1ImgSrc" src="" height="100" width="100" > <!-- ajax異步上傳函數 --> <input type="file" id="imgSize1File" name="imgSize1File" class="file" onchange="submitImgSize1Upload" > <!-- 保存數據庫圖片地址 --> <input type="hidden" id="imgSize1" name="pic" value="" reg="^.+$" tip="親,您忘記上傳圖片了" > </td>
            js代碼:
 爲了使ajax提交的時候,request域中有文件的流對象,因此須要將表單 "異步"提交
 
    
    
    
    
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script><script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.form.js" ></script><script type="text/javascript"> function submitImgSize1Upload(){ var option={ type:'post', url:'${pageContext.request.contextPath}/uploadPic.do', dataType:'text', data:{ fileName:'imgSize1File' }, success:function(data){ //把返回json格式字符串轉換json對象 var obj = $.parseJSON(data); //圖片立馬回顯 $("#imgSize1ImgSrc").attr("src",obj.fullPath); //圖片保存數據地址 $("#imgSize1").val(obj.fullPath); } }; //使用ajax異步提交表單 $("#itemForm").ajaxSubmit(option); }</script>
也能夠直接把dataType改爲"json",在success函數中就不用轉換了(本來是字符串轉換爲json對象)

⑧、後臺代碼:
 新建一個UpLoadController類

* 需求:上傳文件:avi,xls,doc,jpg
* 參數:String fileName,HttpServletRequest,PrintWriter
* 返回值:void
    
    
    
    
public class UploadController { /** * 需求:上傳文件:avi,xls,doc,jpg * 參數:String fileName,HttpServletRequest,PrintWriter * 返回值:void */ @RequestMapping("/uploadPic") public void uploadPic(String fileName,HttpServletRequest request,PrintWriter out){ //把request轉換多部件對象 MultipartHttpServletRequest mh = (MultipartHttpServletRequest) request; //獲取文件對象 CommonsMultipartFile cm = (CommonsMultipartFile) mh.getFile(fileName); //獲取文件擴展名 //a、獲取文件名稱 String originalFilename = cm.getOriginalFilename(); //b、截取文件擴展名 String extName = originalFilename.substring(originalFilename.lastIndexOf(".")); //使用uuid生成文件名稱 String fName = UUID.randomUUID().toString(); //上傳文件 jersey工具 Client create = Client.create(); //制定上傳的服務器路徑 WebResource resource = create.resource(Constants.IMAGE_ADDR+"upload/"+fName+extName); //上傳 resource.put(String.class, cm.getBytes()); //圖片回顯,須要圖片地址返回給ajax的回調函數 //返回json格式數據 String fullPath = Constants.IMAGE_ADDR+"upload/"+fName+extName; //構造一個json格式數據 String result="{\"fullPath\":\""+fullPath+"\"}"; //返回 out.print(result); }}

⑨、修改保存圖片
直接提交就能夠了


3、restfull軟件設計

restfull是一種軟件架構設計風格模式
特色:請求沒有參數,沒有擴展名
案例:http://geek.csdn.net/news/detail/ 200288    (restfull風格請求)
優勢:簡潔,容易被搜索引擎系統收錄

springmvc實現restfull風格軟件架構

       一、 springmvc URI模板映射

@RequestMapping("list/{ids}/{name}")
public String findAllItems(@Pathvariable("ids") int id, @Pathvariable String name , Model  model ){

url中的{id}會自動映射到參數id上,{name}和參數中的name匹配,能夠取別名

        二、servlet攔截目錄

   
   
   
   
<servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern><!-- 攔截全部,包括css,js,images --> </servlet-mapping>

        三、配置springmvc不攔截靜態資源

    <!-- 放行資源文件 -->
    <!-- 
        <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
        <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
        <mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
     -->
    <!-- 簡單寫法 -->
    <mvc:default-servlet-handler/>

若是不加這個註釋(靜態資源放行),那麼能夠直接用url在瀏覽器的地址欄訪問jsp頁面,可是不能訪問html和image或者css、js文件

/  不攔截jsp能夠在url中直接訪問jsp
/*  攔截jsp不能在url中直接訪問jsp,return的結果視圖也不行,因此不用

4、攔截器:

一、簡單測試:


   
   
   
   
public class Interceptor1 implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("這是第一個攔截器的preHandle"); return true; } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("這是第一個攔截器的postHandle"); } @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("這是第一個攔截器的afterCompletion"); }}
第二個攔截器同樣,return false

preHandle:處理器映射器執行以前進行執行,攔截:return false;放行:return true;
postHandle:返回model和view以前執行
afterCompletion:返回model和view以後執行

在springmvc中配置攔截器:
   
   
   
   
<!-- 配置攔截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.Interceptor1" ></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.Interceptor2" ></bean> </mvc:interceptor> </mvc:interceptors>
按照上面的配置,先運行攔截器1,再運行2

①、若是第一個攔截器return false;第二個是false或者true,那麼都返回:
                       這是第一個攔截器的preHandle
②、若是第一個攔截器return true ;第二個攔截器return false,那麼返回:
這是第一個攔截器的preHandle
這是第二個攔截器的preHandle
這是第一個攔截器的afterCompletion
③、若是第一個和第二個攔截器都return true ,那麼返回:
這是第一個攔截器的preHandle
這是第二個攔截器的preHandle
這是第二個攔截器的postHandle
這是第一個攔截器的postHandle
這是第二個攔截器的afterCompletion
這是第一個攔截器的afterCompletion
注意:若是preHandle攔截器返回true,那麼afterCompletion必須執行


5、攔截器登陸案例

   
   
   
   
public class LoginInterceptor implements HandlerInterceptor{ //判斷用戶是否登陸 @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception { //登陸頁面,登陸請求放行 if (req.getRequestURI().contains("login")) { //放行 return true; } Object user = req.getSession().getAttribute("user"); if (user!=null) { return true; } //若是未登陸,跳轉登陸頁面 req.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(req, res); return false; }

   
   
   
   
<mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.itcast.interceptor.LoginInterceptor" ></bean> </mvc:interceptor>
    
    
    
    
@Controllerpublic class LoginController { @RequestMapping("login") public String login(String username,String password,HttpSession session){ session.setAttribute("user", username); return "redirect:/itemsList"; }}































相關文章
相關標籤/搜索