2018-07-23

 







对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。


1他传递什么样的参数,url是什么。

2返回什么样的值,或者说是json,是自己定义好的某个工具类中,




3 返回的值是在那几个表中存在的,对于某些表而言是否需要补齐。

4对于页面的转发而言:

转发和冲顶向的时候,参数的设置

5


Controller对于正常的来说:

因为注解的存在,前期你只要设置好以后是不需要写什么的,

 如果你引入了dubbo的话,有可能需要接受下服务。


   Service

因为这个也是使用注解的存在,如果使用dubbo的话,提供下服务即可。


  Dao一般采取单表进行查询,用逆向工程区实现,



注意下: 对于搜索而言的,搜索中的三圈问题,


在xml中设置参数,编码问题,就好像之前的国税系统一样。


课程计划

第一天

[if !supportLists]1、[endif]SpringMVC介绍

[if !supportLists]2、[endif]入门程序

[if !supportLists]3、[endif]SpringMVC架构讲解

[if !supportLists]a)       [endif]框架结构

[if !supportLists]b)       [endif]组件说明

[if !supportLists]4、[endif]SpringMVC整合MyBatis

[if !supportLists]5、[endif]参数绑定

[if !supportLists]a)       [endif]SpringMVC默认支持的类型

[if !supportLists]b)       [endif]简单数据类型

[if !supportLists]c)       [endif]Pojo类型

[if !supportLists]d)       [endif]Pojo包装类型

[if !supportLists]e)       [endif]自定义参数绑定

[if !supportLists]6、[endif]SpringMVC和Struts2的区别


第二天

[if !supportLists]1、[endif]高级参数绑定

[if !supportLists]a)       [endif]数组类型的参数绑定

[if !supportLists]b)       [endif]List类型的绑定

[if !supportLists]2、[endif]@RequestMapping注解的使用

[if !supportLists]3、[endif]Controller方法返回值

[if !supportLists]4、[endif]SpringMVC中异常处理

[if !supportLists]5、[endif]图片上传处理

[if !supportLists]6、[endif]Json数据交互

[if !supportLists]7、[endif]SpringMVC实现RESTful

8、拦截器



Web-inf

1:  DispatcherServlet和乱码问题


2:  Conf  springmvc.xml

  约束:通常会配的

2.1 视图解析器

2.2 注解的方式,进行扫描

2.3   相当于加载了上面的东西。

自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter


Springmvc和mybatis的整合


常见的接受参数合返回域对象,

他里面是有request和response的api的一般为了解耦,不用罢了。


接受参数:

1:在上面接受参数的时候,用包装类型Integer,因为基础的数据不能为空。

value:参数名字,即入参的请求参数名字,如value=“itemId”表示请求的参数    区中的名字为itemId的参数的值将传入


required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错

TTP Status 400 - Required Integer parameter 'XXXX' is notpresent

defaultValue:默认值,表示如果请求中没有同名参数时的默认值


@RequestParam,   在这里名字可以不一样,第一次访问给默认值

public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id,

       ModelMapmodelMap) {

2:用pojo进行接受。 

用你逆向工程生成的pojo的方式来进行传递数据。这个比较方便,只要名字一样就可以了。


用这种方式的时候,如果存在的日期的话,会爆粗,他只能转化为基本的数据类型, 你要加上一个转换器就可以了。


用这个对象的时候,jsp里面的写法问题,所以才会出现,如果两个类的成员出现了同名的话,那么就要封装到一个大的javaBean里面。

public class QueryVo {

    private Item item;

set/get。。。

}





[if !vml]

[endif]


页面定义如下图:

1:接受数组的形式 String 【】 id, 你可以在pojo中进行定义,

也可以单独搞一个这种参数。

[if !supportLists]1.1. [endif]将表单的数据绑定到List

[if !supportLists]1.1.1. [endif]需求

实现商品数据的批量修改。

[if !supportLists]1.1.2. [endif]开发分析

开发分析

[if !supportLists]1. [endif]在商品列表页面中可以对商品信息进行修改。

[if !supportLists]2. [endif]可以批量提交修改后的商品数据。


[if !supportLists]1.1.3. [endif]定义pojo

List中存放对象,并将定义的List放在包装类QueryVo中


使用包装pojo对象接收,如下图:

[if !vml]

[endif]

[if !supportLists]1.1.4. [endif]Jsp改造

前端页面应该显示的html代码,如下图:

[if !vml]

[endif]


分析发现:name属性必须是list属性名+下标+元素属性。

Jsp做如下改造:

"${itemList }"var="item"varStatus="s">

    "checkbox"name="ids"value="${item.id}"/>


       "hidden"name="itemList[${s.index}].id"value="${item.id }"/>

       "text"name="itemList[${s.index}].name"value="${item.name }"/>


    "text"name="itemList[${s.index}].price"value="${item.price }"/>

    "text"name="itemList[${s.index}].createtime"value=""yyyy-MM-dd HH:mm:ss"/>"/>

    "text"name="itemList[${s.index}].detail"value="${item.detail }"/>


    "${pageContext.request.contextPath

}/itemEdit.action?id=${item.id}">修改



${current} 当前这次迭代的(集合中的)项

${status.first}   判断当前项是否为集合中的第一项,返回值为true或false

${status.last}    判断当前项是否为集合中的最

varStatus属性常用参数总结下:

${status.index}   输出行号,从0开始。

${status.count}   输出行号,从1开始。

${status.后一项,返回值为true或false

begin、end、step分别表示:起始序号,结束序号,跳跃步伐。






不再使用


[if !supportLists]1.2. [endif]自定义参数绑定

[if !supportLists]1.2.1. [endif]需求

在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式。

[if !supportLists]1.2.2. [endif]需求分析

由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。


前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。可以在springmvc处理器适配器上自定义转换器Converter进行参数绑定。


一般使用注解驱动加载处理器适配器,可以在此标签上进行配置。


[if !supportLists]1.2.3. [endif]修改jsp页面

如下图修改itemEdit.jsp页面,显示时间

[if !vml]

[endif]


[if !supportLists]1.2.4. [endif]自定义Converter

//Converter

//S:source,需要转换的源的类型

//T:target,需要转换的目标类型

public class DateConverter implementsConverter {


   @Override

   public Date convert(String source) {

      try {

         // 把字符串转换为日期类型

         SimpleDateFormatsimpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");

         Datedate = simpleDateFormat.parse(source);


         return date;

      }catch (ParseException e) {

         // TODOAuto-generated catch block

         e.printStackTrace();

      }

      // 如果转换异常则返回空

      return null;

   }

}



在进行传递参数的时候:


域对象传递值:Model

ModelMap是Model接口的实现类

model.addAttribute("item", item);


转发或者是重定向的时候传递参数:添加以后,跳转到list。

// 返回的值的时候传递值。

    return "redirect:/itemEdit.action?itemId=" + item.getId();

// 这个就相当于add跳转到list

return "forward: /itemEdit.action";



应该是这样的定义的。

你在*.action一样,

你在浏览器中是要添加 xxx.action的。

你在RequestMapping的时候是不用的。





springmvc与struts2不同

[if !supportLists]1、  [endif]springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。

[if !supportLists]2、 [endif]springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

[if !supportLists]3、  [endif]Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。Jsp视图解析器默认使用jstl。

[if !supportLists]4、  [endif]Springmvc的效率更加的高一点,struts的效率低一点。



[if !supportLists]1.2.5. [endif]常用的注解:

@RequestMapping(value = { "itemList", "itemListAll"},

Method=RequestMethod.POST)


@ResponseBody  使用json的形式进行解析,如果是String的话,直接显示到浏览器中。  可以使用javaBean或者是集合容器,list,map,

你只有定义了这个注解,他才不会转发到视图中,要不然即使是void,他依然是会进行跳转的。  路径加上前后缀。


(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id, ModelMap modelMap)


这个是接受参数的,uri的形式的


图片上传:

[if !supportLists]2.  [endif]上传图片

[if !supportLists]2.1. [endif]配置虚拟目录

在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml中添加:

D:\develop\upload\temp"path="/pic" reloadable="false"/>

访问http://localhost:8080/pic即可访问D:\develop\upload\temp下的图片。

也可以通过eclipse配置,如下图:

[if !vml]

[endif]

[if !vml]

[endif]

复制一张图片到存放图片的文件夹,使用浏览器访问

测试效果,如下图:

[if !vml]

[endif]



[if !supportLists]2.2. [endif]加入jar包

实现图片上传需要加入的jar包,如下图:

[if !vml]

[endif]

把两个jar包放到工程的lib文件夹中



[if !supportLists]2.3. [endif]配置上传解析器

在springmvc.xml中配置文件上传解析器


-->

"multipartResolver"

    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">


    "maxUploadSize"value="5000000"/>


[if !supportLists]2.4. [endif]jsp页面修改

在商品修改页面,打开图片上传功能,如下图:

[if !vml]

[endif]

设置表单可以进行文件上传,如下图:

[if !vml]

[endif]

[if !supportLists]2.5. [endif]图片上传

在更新商品方法中添加图片上传逻辑

/**

 *更新商品

 *

 *@param item

 *@return

 *@throws Exception

 */

@RequestMapping("updateItem")

public String updateItemById(Item item, MultipartFile pictureFile) throws Exception {

    // 图片上传

    // 设置图片名称,不能重复,可以使用uuid

    StringpicName = UUID.randomUUID().toString();


    // 获取文件名

    StringoriName = pictureFile.getOriginalFilename();

    // 获取图片后缀

    StringextName = oriName.substring(oriName.lastIndexOf("."));


    // 开始上传

    pictureFile.transferTo(new File("C:/upload/image/" + picName + extName));


    // 设置图片名到商品中

    item.setPic(picName + extName);

    // ---------------------------------------------

    // 更新商品

    this.itemService.updateItemById(item);


    return "forward:/itemEdit.action";

}


效果,如下图:[if !vml]

[endif]

[if !supportLists]3.  [endif]json数据交互

[if !supportLists]3.1. [endif]@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为java对象并绑定到Controller方法的参数上。


传统的请求参数:

itemEdit.action?id=1&name=zhangsan&age=12

现在的请求参数:

使用POST请求,在请求体里面加入json数据

{

"id": 1,

"name": "测试商品",

"price": 99.9,

"detail": "测试商品描述",

"pic":"123456.jpg"

}


本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象进行绑定

[if !supportLists]3.2. [endif]@ResponseBody

作用:

@ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。你也可以直接返回string对象,那么是向浏览器返回string的值。


本例子应用:

@ResponseBody注解实现将Controller方法返回java对象转换为json响应给客户端。


[if !supportLists]3.3. [endif]请求json,响应json实现:

[if !supportLists]3.3.1. [endif]加入jar包

如果需要springMVC支持json,必须加入json的处理jar

我们使用Jackson这个jar,如下图:

[if !vml]

[endif]

[if !supportLists]3.3.2. [endif]ItemController编写

/**

 *测试json的交互

 *@param item

 *@return

 */

@RequestMapping("testJson")

// @ResponseBody

public @ResponseBody Item testJson(@RequestBody Item item) {

    return item;

}

[if !supportLists]3.3.3. [endif]安装谷歌浏览器测试工具

安装程序在课后资料

参考安装文档,如下图:

[if !vml]

[endif]

[if !supportLists]3.3.4. [endif]测试方法

测试方法,如下图:

[if !vml]

[endif]










[if !supportLists]3.3.5. [endif]测试结果

如下图:

[if !vml]

[endif]


[if !supportLists]3.3.6. [endif]配置json转换器

如果不使用注解驱动

/>,就需要给处理器适配器配置json转换器,参考之前学习的自定义参数绑定。


在springmvc.xml配置文件中,给处理器适配器加入json转换器:


   "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">

      <property name="messageConverters">

     

      "org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">






[if !supportLists]4.  [endif]RESTful支持

[if !supportLists]4.1. [endif]什么是restful?

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。


资源:互联网所有的事物都可以被抽象为资源

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。

     分别对应添加、删除、修改、查询。

传统方式操作资源

http://127.0.0.1/item/queryItem.action?id=1     查询,GET

http://127.0.0.1/item/saveItem.action                新增,POST

http://127.0.0.1/item/updateItem.action           更新,POST

http://127.0.0.1/item/deleteItem.action?id=1    删除,GET或POST

以前都是用?来进行操作的


使用RESTful操作资源,比如说京东,就是这样的风格,

http://127.0.0.1/item/1           查询,GET

http://127.0.0.1/item               新增,POST

http://127.0.0.1/item               更新,PUT

http://127.0.0.1/item/1           删除,DELETE


[if !supportLists]4.2. [endif]需求

RESTful方式实现商品信息查询,返回json数据

[if !supportLists]4.3. [endif]从URL上获取参数

使用RESTful风格开发的接口,根据id查询商品,接口地址是:

http://127.0.0.1/item/1


我们需要从url上获取商品id,步骤如下:

[if !supportLists]1. [endif]使用注解@RequestMapping("item/{id}")声明请求的url

{xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”


[if !supportLists]2. [endif]使用(@PathVariable() Integer id)获取url上的数据 


/**

 *使用RESTful风格开发接口,实现根据id查询商品

 *

 *@param id

 *@return

 */

@RequestMapping("item/{id}")

@ResponseBody

public Item queryItemById(@PathVariable() Integer id) {

    Itemitem = this.itemService.queryItemById(id);

    return item;

}


如果@RequestMapping中表示为"item/{id}",id和形参名称一致,@PathVariable不用指定名称。如果不一致,例如"item/{ItemId}"则需要指定名称@PathVariable("itemId")。


http://127.0.0.1/item/123?id=1

注意两个区别

[if !supportLists]1. [endif]@PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)


[if !supportLists]2. [endif]如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面



[if !supportLists]5.  [endif]拦截器

[if !supportLists]5.1. [endif]定义

       Spring Web MVC的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

[if !supportLists]5.2. [endif]拦截器定义

实现HandlerInterceptor接口,如下:

public class HandlerInterceptor1 implements HandlerInterceptor {

    // controller执行后且视图返回后调用此方法

    // 这里可得到执行controller时的异常信息

    // 这里可记录操作日志

    @Override

    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1,

Object arg2, Exception arg3)

           throws Exception {

       System.out.println("HandlerInterceptor1....afterCompletion");

    }


    // controller执行后但未返回视图前调用此方法

    // 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示

    @Override

    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,

Object arg2, ModelAndView arg3)

           throws Exception {

       System.out.println("HandlerInterceptor1....postHandle");

    }


    // Controller执行前调用此方法

    // 返回true表示继续执行,返回false中止执行

    // 这里可以加入登录校验、权限拦截等

    @Override

    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,

Object arg2) throws Exception {

       System.out.println("HandlerInterceptor1....preHandle");

        // 设置为true,测试使用

       return true;

    }

}

[if !supportLists]5.3. [endif]拦截器配置

上面定义的拦截器再复制一份HandlerInterceptor2,注意新的拦截器修改代码:

System.out.println("HandlerInterceptor2....preHandle");


在springmvc.xml中配置拦截器


   


       "/**"/>


       "cn.itcast.ssm.interceptor.HandlerInterceptor1"/>


   


       "/**"/>


       "cn.itcast.ssm.interceptor.HandlerInterceptor2"/>


 

[if !supportLists]5.4. [endif]正常流程测试

浏览器访问地址

http://127.0.0.1:8080/springmvc-web2/itemList.action

[if !supportLists]5.4.1. [endif]运行流程

控制台打印:

HandlerInterceptor1..preHandle..

HandlerInterceptor2..preHandle..


HandlerInterceptor2..postHandle..

HandlerInterceptor1..postHandle..


HandlerInterceptor2..afterCompletion..

HandlerInterceptor1..afterCompletion..

[if !supportLists]5.5. [endif]中断流程测试

浏览器访问地址

http://127.0.0.1:8080/springmvc-web2/itemList.action


[if !supportLists]5.5.1. [endif]运行流程

HandlerInterceptor1的preHandler方法返回false,HandlerInterceptor2返回true,运行流程如下:


HandlerInterceptor1..preHandle..


从日志看出第一个拦截器的preHandler方法返回false后第一个拦截器只执行了preHandler方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且Controller也不执行了。



HandlerInterceptor1的preHandler方法返回true,HandlerInterceptor2返回false,运行流程如下:


HandlerInterceptor1..preHandle..

HandlerInterceptor2..preHandle..

HandlerInterceptor1..afterCompletion..


从日志看出第二个拦截器的preHandler方法返回false后第一个拦截器的postHandler没有执行,第二个拦截器的postHandler和afterCompletion没有执行,且controller也不执行了。


总结:

preHandle按拦截器定义顺序调用

postHandler按拦截器定义逆序调用

afterCompletion按拦截器定义逆序调用


postHandler在拦截器链内所有拦截器返成功调用

afterCompletion只有preHandle返回true才调用

[if !supportLists]5.6. [endif]拦截器应用

[if !supportLists]5.6.1. [endif]处理流程

[if !supportLists]1、[endif]有一个登录页面,需要写一个Controller访问登录页面

[if !supportLists]2、[endif]登录页面有一提交表单的动作。需要在Controller中处理。

[if !supportLists]a)       [endif]判断用户名密码是否正确(在控制台打印)

[if !supportLists]b)       [endif]如果正确,向session中写入用户信息(写入用户名username)

[if !supportLists]c)       [endif]跳转到商品列表

[if !supportLists]3、[endif]拦截器。

[if !supportLists]a)       [endif]拦截用户请求,判断用户是否登录(登录请求不能拦截)

[if !supportLists]b)       [endif]如果用户已经登录。放行

[if !supportLists]c)       [endif]如果用户未登录,跳转到登录页面。

[if !supportLists]5.6.2. [endif]编写登录jsp

<%@pagelanguage="java"contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

"Content-Type"content="text/html;

charset=UTF-8">

Insert

title here


"${pageContext.request.contextPath }/user/login.action">

用户名:


"text"name="username">


密码:


"password"name="password">


"submit">



[if !supportLists]5.6.3. [endif]用户登陆Controller

@Controller

@RequestMapping("user")

public class UserController {


    /**

     *跳转到登录页面

     *

     *@return

     */

    @RequestMapping("toLogin")

    public String toLogin() {

       return "login";

    }


    /**

     *用户登录

     *

     *@param username

     *@param password

     *@param session

     *@return

     */

    @RequestMapping("login")

    public String login(String username, String password, HttpSession session) {

       // 校验用户登录

       System.out.println(username);

       System.out.println(password);


       // 把用户名放到session中

       session.setAttribute("username", username);


       return "redirect:/item/itemList.action";

    }


}





[if !supportLists]5.6.4. [endif]编写拦截器

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {

    // 从request中获取session

    HttpSessionsession = request.getSession();

    // 从session中获取username

    Objectusername = session.getAttribute("username");

    // 判断username是否为null

    if (username != null) {

       // 如果不为空则放行

       return true;

    }else {

       // 如果为空则跳转到登录页面

       response.sendRedirect(request.getContextPath() + "/user/toLogin.action");

    }


    return false;

}

[if !supportLists]5.6.5. [endif]配置拦截器

只能拦截商品的url,所以需要修改ItemController,让所有的请求都必须以item开头,如下图:

[if !vml]

[endif]


在springmvc.xml配置拦截器


    "/item/**"/>


    "cn.itcast.ssm.interceptor.LoginHandlerInterceptor"/>






[if !supportLists]6.  [endif]Spring入门

[if !supportLists]6.1. [endif]Springmvc是什么

Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出来,如下图:

[if !vml]

[endif]

[if !supportLists]6.2. [endif]Springmvc处理流程

如下图所示:

[if !vml]

[endif]

[if !supportLists]6.2.1. [endif]导入jar包

从课前资料中导入springMVC的jar包,位置如下图:

[if !vml]

[endif]



[if !supportLists]6.2.2. [endif]加入配置文件

创建config资源文件夹,存放配置文件,如下图:

[if !vml]

[endif]


[if !supportLists]6.2.2.1. [endif]创建springmvc.xml

创建SpringMVC的核心配置文件

SpringMVC本身就是Spring的子项目,对Spring兼容性很好,不需要做很多配置。

这里只配置一个Controller扫描就可以了,让Spring对页面控制层Controller进行管理。


创建springmvc.xml

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    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:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

       http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

       http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd">



    "cn.itcast.springmvc.controller"/>



配置文件需要的约束文件,位置如下图:

[if !vml]

[endif]



[if !supportLists]6.2.2.2. [endif]配置前端控制器

配置SpringMVC的前端控制器DispatcherServlet

需要注意的是:


在web.xml中

"1.0"encoding="UTF-8"?>

"http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    id="WebApp_ID"version="2.5">

    springmvc-first

   

       index.html

       index.htm

       index.jsp

       default.html

       default.htm

       default.jsp




   

       springmvc-first

       org.springframework.web.servlet.DispatcherServlet



-->

      

           contextConfigLocation

           classpath:springmvc.xml




   

        springmvc-first


       *.action


[if !supportLists]6.2.2.3. [endif]创建pojo

分析页面,查看页面需要的数据,如下图:

[if !vml]

[endif]

创建商品pojo

public class Item {

    // 商品id

    private int id;

    // 商品名称

    private String name;

    // 商品价格

    private double price;

    // 商品创建时间

    private Date createtime;

    // 商品描述

    private String detail;


创建带参数的构造器

set/get。。。

}


[if !supportLists]6.2.2.4. [endif]创建ItemController

ItemController是一个普通的java类,不需要实现任何接口。

需要在类上添加@Controller注解,把Controller交由Spring管理

在方法上面添加@RequestMapping注解,里面指定请求的url。其中“.action”可以加也可以不加。

@Controller

public class ItemController {


    // @RequestMapping:里面放的是请求的url,和用户请求的url进行匹配

    // action可以写也可以不写

    @RequestMapping("/itemList.action")

    public ModelAndView queryItemList() {

       // 创建页面需要显示的商品数据

       Listlist = new ArrayList<>();

       list.add(new Item(1, "1华为 荣耀8", 2399, new Date(), "质量好!1"));

       list.add(new Item(2, "2华为 荣耀8", 2399, new Date(), "质量好!2"));

       list.add(new Item(3, "3华为 荣耀8", 2399, new Date(), "质量好!3"));

       list.add(new Item(4, "4华为 荣耀8", 2399, new Date(), "质量好!4"));

       list.add(new Item(5, "5华为 荣耀8", 2399, new Date(), "质量好!5"));

       list.add(new Item(6, "6华为 荣耀8", 2399, new Date(), "质量好!6"));


       // 创建ModelAndView,用来存放数据和视图

       ModelAndViewmodelAndView = new ModelAndView();

       // 设置数据到模型中

       modelAndView.addObject("list", list);

       // 设置视图jsp,需要设置视图的物理地址

       modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");


       return modelAndView;

    }

}


[if !supportLists]6.2.3. [endif]启动项目测试

启动项目,浏览器访问地址

http://127.0.0.1:8080/springmvc-first/itemList.action


效果如下图:

[if !vml]

[endif]



为什么可以用呢?我们需要分析一下springMVC的架构图。




[if !supportLists]7.  [endif]Springmvc架构

[if !supportLists]7.1. [endif]框架结构

框架结构如下图:

[if !vml]

[endif]

[if !supportLists]7.2. [endif]架构流程

[if !supportLists]1、[endif]用户发送请求至前端控制器DispatcherServlet

[if !supportLists]2、[endif]DispatcherServlet收到请求调用HandlerMapping处理器映射器。

[if !supportLists]3、[endif]处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

[if !supportLists]4、[endif]DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

[if !supportLists]5、[endif]执行处理器(Controller,也叫后端控制器)。

[if !supportLists]6、[endif]Controller执行完成返回ModelAndView

[if !supportLists]7、[endif]HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet

[if !supportLists]8、[endif]DispatcherServlet将ModelAndView传给ViewReslover视图解析器

[if !supportLists]9、[endif]ViewReslover解析后返回具体View

[if !supportLists]10、           [endif]DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。

[if !supportLists]11、           [endif]DispatcherServlet响应用户

[if !supportLists]7.3. [endif]组件说明

以下组件通常使用框架提供实现:

[if !supportLists]u [endif]DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。

[if !supportLists]u  [endif]HandlerMapping:处理器映射器

HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

[if !supportLists]u [endif]Handler:处理器

Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。

由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。


[if !supportLists]u  [endif]HandlAdapter:处理器适配器

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。


[if !supportLists]u  [endif]ViewResolver:视图解析器

View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

[if !supportLists]u [endif]View:视图

springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。

一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。


说明:在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。

需要用户开发的组件有handler、view


[if !supportLists]7.4. [endif]默认加载的组件

我们没有做任何配置,就可以使用这些组件

因为框架已经默认加载这些组件了,配置文件位置如下图:

[if !vml]

[endif]


# Default implementation

classes for DispatcherServlet's strategy interfaces.

# Used as fallback when no

matching beans are found in the DispatcherServlet context.

# Not meant to be customized by

application developers.


org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver


org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver


org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\

    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping


org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\

    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\

    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\

    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\

    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver


org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator


org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver


org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager


[if !supportLists]7.5. [endif]组件扫描器

使用组件扫描器省去在spring容器配置每个Controller类的繁琐。

使用自动扫描标记@Controller的控制器类,

在springmvc.xml配置文件中配置如下:


"cn.itcast.springmvc.controller"/>


[if !supportLists]7.6. [endif]注解映射器和适配器

[if !supportLists]7.6.1. [endif]配置处理器映射器

注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射。根据@ResquestMapping定义的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。

HandlerMethod对象中封装url对应的方法Method。


在springmvc.xml配置文件中配置如下:


class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>


注解描述:

@RequestMapping:定义请求url到处理器功能方法的映射


[if !supportLists]7.6.2. [endif]配置处理器适配器

注解式处理器适配器,对标记@ResquestMapping的方法进行适配。


从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。


在springmvc.xml配置文件中配置如下:


class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>



[if !supportLists]7.6.3. [endif]注解驱动

直接配置处理器映射器和处理器适配器比较麻烦,可以使用注解驱动来加载。

SpringMVC使用自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter

可以在springmvc.xml配置文件中使用替代注解处理器和适配器的配置。



[if !supportLists]7.7. [endif]视图解析器

视图解析器使用SpringMVC框架默认的InternalResourceViewResolver,这个视图解析器支持JSP视图解析

在springmvc.xml配置文件中配置如下:


prefix="/WEB-INF/jsp/", suffix=".jsp",

viewname="test" ->

       "/WEB-INF/jsp/test.jsp" -->



       class="org.springframework.web.servlet.view.InternalResourceViewResolver">


       "prefix"value="/WEB-INF/jsp/"/>


       "suffix"value=".jsp"/>


逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为ItemList,则最终返回的jsp视图地址:

“WEB-INF/jsp/itemList.jsp”


最终jsp物理地址:前缀+逻辑视图名+后缀


[if !supportLists]8.  [endif]异常处理器

       springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。


[if !supportLists]8.1. [endif]异常处理思路

       系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

       系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:


[if !vml]

[endif]




[if !supportLists]8.2. [endif]自定义异常类

       为了区别不同的异常,通常根据异常类型进行区分,这里我们创建一个自定义系统异常。

如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

public class MyException extends Exception {

    // 异常信息

    private String message;


    public MyException() {

       super();

    }


    public MyException(String message) {

       super();

       this.message = message;

    }


    public String getMessage() {

       return message;

    }


    public void setMessage(String message) {

       this.message = message;

    }


}



[if !supportLists]8.3. [endif]自定义异常处理器

public class CustomHandleException implements HandlerExceptionResolver {


    @Override

    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,

           Exceptionexception) {

       // 定义异常信息

       Stringmsg;


       // 判断异常类型

       if (exception instanceof MyException) {

           // 如果是自定义异常,读取异常信息

           msg = exception.getMessage();

       }else {

           // 如果是运行时异常,则取错误堆栈,从堆栈中获取异常信息

           Writerout = new StringWriter();

           PrintWriters = new PrintWriter(out);

           exception.printStackTrace(s);

           msg = out.toString();


       }


       // 把错误信息发给相关人员,邮件,短信等方式

       // TODO


       // 返回错误页面,给用户友好页面显示错误信息

       ModelAndViewmodelAndView = new ModelAndView();

       modelAndView.addObject("msg", msg);

       modelAndView.setViewName("error");


       return modelAndView;

    }

}



[if !supportLists]8.4. [endif]异常处理器配置

在springmvc.xml中添加:


id="customHandleException"  class="cn.itcast.ssm.exception.CustomHandleException"/>


[if !supportLists]8.5.[endif]错误页面

<%@pagelanguage="java"contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

"Content-Type"content="text/html;

charset=UTF-8">

Insert

title here


   

系统发生异常了!

   

   

异常信息

   

   

${msg }



[if !supportLists]8.6. [endif]异常测试

修改ItemController方法“queryItemList”,抛出异常:

/**

 *查询商品列表

 *

 *@return

 *@throws Exception

 */

@RequestMapping(value = { "itemList", "itemListAll" })

public ModelAndView queryItemList() throws Exception {

    // 自定义异常

    if (true) {

       throw new MyException("自定义异常出现了~");

    }


    // 运行时异常

    int a = 1 / 0;


    // 查询商品数据

    Listlist = this.itemService.queryItemList();

    // 创建ModelAndView,设置逻辑视图名

    ModelAndViewmv = new ModelAndView("itemList");

    // 把商品数据放到模型中

    mv.addObject("itemList", list);


    return mv;

}



[if !supportLists]9.  [endif]整合mybatis

       为了更好的学习 springmvc和mybatis整合开发的方法,需要将springmvc和mybatis进行整合。


整合目标:控制层采用springmvc、持久层使用mybatis实现。

[if !supportLists]9.1. [endif]创建数据库表

sql脚本,位置如下图:

[if !vml]

[endif]


创建数据库表springmvc,导入到数据库中,如下图:

[if !vml]

[endif]


[if !supportLists]9.2. [endif]需要的jar包

[if !supportLists]1.     [endif]spring(包括springmvc)

[if !supportLists]2.     [endif]mybatis

[if !supportLists]3.     [endif]mybatis-spring整合包

[if !supportLists]4.     [endif]数据库驱动

[if !supportLists]5.     [endif]第三方连接池。


jar包位置如下图:

[if !vml]

[endif]


[if !supportLists]9.3. [endif]整合思路

Dao层:

[if !supportLists]1、[endif]SqlMapConfig.xml,空文件即可,但是需要文件头。

[if !supportLists]2、[endif]applicationContext-dao.xml

[if !supportLists]a)       [endif]数据库连接池

[if !supportLists]b)       [endif]SqlSessionFactory对象,需要spring和mybatis整合包下的。

[if !supportLists]c)       [endif]配置mapper文件扫描器。


Service层:

[if !supportLists]1、[endif]applicationContext-service.xml包扫描器,扫描@service注解的类。

[if !supportLists]2、[endif]applicationContext-trans.xml配置事务。


Controller层:

[if !supportLists]1、[endif]Springmvc.xml

[if !supportLists]a)       [endif]包扫描器,扫描@Controller注解的类。

[if !supportLists]b)       [endif]配置注解驱动

[if !supportLists]c)       [endif]配置视图解析器


Web.xml文件:

[if !supportLists]1、[endif]配置spring

[if !supportLists]2、[endif]配置前端控制器。

[if !supportLists]9.4. [endif]创建工程

[if !supportLists]9.5. [endif]加入配置文件

创建资源文件夹config

在其下创建mybatis和spring文件夹,用来存放配置文件,如下图:

[if !vml]

[endif]

[if !supportLists]9.5.1. [endif]sqlMapConfig.xml

使用逆向工程来生成Mapper相关代码,不需要配置别名。

在config/mybatis下创建SqlMapConfig.xml

"1.0"encoding="UTF-8"?>

PUBLIC"-//mybatis.org//DTD Config

3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">



[if !supportLists]9.5.2. [endif]applicationContext-dao.xml

配置数据源、配置SqlSessionFactory、mapper扫描器。

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"

    xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"

    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-4.0.xsd

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd

    http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsd

    http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd">



    "classpath:db.properties"/>



    "dataSource"class="org.apache.commons.dbcp.BasicDataSource"

       destroy-method="close">

       "driverClassName"value="${jdbc.driver}"/>

       "url"value="${jdbc.url}"/>

       "username"value="${jdbc.username}"/>

       "password"value="${jdbc.password}"/>

       "maxActive"value="10"/>

       "maxIdle"value="5"/>




    "sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">


       "dataSource"ref="dataSource"/>


       "configLocation"value="classpath:mybatis/SqlMapConfig.xml"/>




    "org.mybatis.spring.mapper.MapperScannerConfigurer">


       "basePackage"value="cn.itcast.ssm.mapper"/>




[if !supportLists]9.5.3. [endif]db.properties

配置数据库相关信息

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/springmvc?characterEncoding=utf-8

jdbc.username=root

jdbc.password=root


[if !supportLists]9.5.4. [endif]applicationContext-service.xml

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"

    xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"

    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-4.0.xsd

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd

    http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsd

    http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd">



    "cn.itcast.ssm.service"/>



[if !supportLists]9.5.5. [endif]applicationContext-trans.xml

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"

    xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"

    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-4.0.xsd

    http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd

    http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsd

    http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd">



    "transactionManager"

       class="org.springframework.jdbc.datasource.DataSourceTransactionManager">


       "dataSource"ref="dataSource"/>




    "txAdvice"transaction-manager="transactionManager">

      


           "save*"propagation="REQUIRED"/>

           "insert*"propagation="REQUIRED"/>

           "delete*"propagation="REQUIRED"/>

           "update*"propagation="REQUIRED"/>

           "find*"propagation="SUPPORTS"read-only="true"/>

           "get*"propagation="SUPPORTS"read-only="true"/>

           "query*"propagation="SUPPORTS"read-only="true"/>





   

       "txAdvice"

           pointcut="execution(*

cn.itcast.ssm.service.*.*(..))" />




[if !supportLists]9.5.6. [endif]springmvc.xml

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    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:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

       http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">



    "cn.itcast.ssm.controller"/>



   



prefix="/WEB-INF/jsp/", suffix=".jsp",

viewname="test" ->

       "/WEB-INF/jsp/test.jsp" -->



    class="org.springframework.web.servlet.view.InternalResourceViewResolver">


       "prefix"value="/WEB-INF/jsp/"/>


       "suffix"value=".jsp"/>




[if !supportLists]9.5.7. [endif]web.xml

"1.0"encoding="UTF-8"?>

"http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://java.sun.com/xml/ns/javaee"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

    id="WebApp_ID"version="2.5">

    springmvc-web

   

       index.html

       index.htm

       index.jsp

       default.html

       default.htm

       default.jsp




   

       contextConfigLocation

       classpath:spring/applicationContext*.xml




   

       org.springframework.web.context.ContextLoaderListener




   

       springmvc-web

       org.springframework.web.servlet.DispatcherServlet

      

           contextConfigLocation

           classpath:spring/springmvc.xml




   

       springmvc-web


       *.action




[if !supportLists]9.6. [endif]效果

配置完效果如下图:

[if !vml]

[endif]



[if !supportLists]10.            [endif]实现商品列表显示

[if !supportLists]10.1. [endif]需求

实现商品查询列表,从mysql数据库查询商品信息。





[if !supportLists]10.2. [endif]DAO开发

使用逆向工程,生成代码


注意修改逆向工程的配置文件,参考MyBatis第二天

逆向工程生成代码如下图:

[if !vml]

[endif]


[if !supportLists]10.3. [endif]ItemService接口

public interface ItemService {


    /**

     *查询商品列表

     *

     *@return

     */

    ListqueryItemList();


}


[if !supportLists]10.4. [endif]ItemServiceImpl实现类

@Service

public class ItemServiceImpl implements ItemService {


    @Autowired

    private ItemMapper itemMapper;


    @Override

    public List queryItemList() {

       // 从数据库查询商品数据

       Listlist = this.itemMapper.selectByExample(null);


       return list;

    }


}


[if !supportLists]10.5. [endif]ItemController

@Controller

public class ItemController {


    @Autowired

    private ItemService itemService;


    /**

     *显示商品列表

     *

     *@return

     */

    @RequestMapping("/itemList")

    public ModelAndView queryItemList() {

       // 获取商品数据

       Listlist = this.itemService.queryItemList();


       ModelAndViewmodelAndView = new ModelAndView();

       // 把商品数据放到模型中

       modelAndView.addObject("itemList", list);

       // 设置逻辑视图

       modelAndView.setViewName("itemList");


       return modelAndView;

    }


}


[if !supportLists]10.6. [endif]测试

访问url:

http://127.0.0.1:8080/springmvc-web/itemList.action


效果如下图:

[if !vml]

[endif]


[if !supportLists]11.            [endif]参数绑定

[if !supportLists]11.1. [endif]默认支持的参数类型

[if !supportLists]11.1.1. [endif]需求

打开商品编辑页面,展示商品信息。

[if !supportLists]11.1.2. [endif]需求分析

编辑商品信息,首先要显示商品详情

需要根据商品id查询商品信息,然后展示到页面。

请求的url:/itemEdit.action

参数:id(商品id)

响应结果:商品编辑页面,展示商品详细信息。

[if !supportLists]11.1.3. [endif]ItemService接口

编写ItemService接口如下图:

[if !vml]

[endif]


[if !supportLists]11.1.4. [endif]ItemServiceImpl实现类

@Override

public Item queryItemById(int id) {

    Itemitem = this.itemMapper.selectByPrimaryKey(id);


    return item;

}


[if !supportLists]11.1.5. [endif]ItemController

页面点击修改按钮,发起请求

http://127.0.0.1:8080/springmvc-web/itemEdit.action?id=1


需要从请求的参数中把请求的id取出来。

Id包含在Request对象中。可以从Request对象中取id。


想获得Request对象只需要在Controller方法的形参中添加一个参数即可。Springmvc框架会自动把Request对象传递给方法。


代码实现

/**

 *根据id查询商品

 *

 *@param request

 *@return

 */

@RequestMapping("/itemEdit")

public ModelAndView queryItemById(HttpServletRequest request) {

    // 从request中获取请求参数

    StringstrId = request.getParameter("id");

    Integerid = Integer.valueOf(strId);


    // 根据id查询商品数据

    Itemitem = this.itemService.queryItemById(id);


    // 把结果传递给页面

    ModelAndViewmodelAndView = new ModelAndView();

    // 把商品数据放在模型中

    modelAndView.addObject("item", item);

    // 设置逻辑视图

    modelAndView.setViewName("itemEdit");


    return modelAndView;

}


[if !supportLists]11.1.6. [endif]解决post乱码问题

提交发现,保存成功,但是保存的是乱码

在web.xml中加入:


   

       encoding

       org.springframework.web.filter.CharacterEncodingFilter


      

           encoding

           UTF-8



   

       encoding

       /*


以上可以解决post请求乱码问题。


对于get请求中文参数出现乱码解决方法有两个:

修改tomcat配置文件添加编码与工程编码一致,如下:


另外一种方法对参数进行重新编码:

String userNamenew

String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,345评论 1 45
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • 春日喜雨 春雨如酒醉凡尘,桃红梨白柳色新。 一抹绿色刚破土,杨絮落地碾作肥。
    缘wxh阅读 169评论 4 2
  • 第七章 坍塌与欢乐 阳光透过沾着水气的玻璃,有一些丝丝的柔弱。透过这样的窗看太阳,太阳已再是圆的,就像一滴墨水,滴...
    浪花墨馨阅读 610评论 0 0
  • 文:王人義 木偶的獨白 謝幕了,我走回後台,心像風洞一樣無限的空蕩。 在舞台上,我是明星,漂亮的面孔、如...
    心靈故鄉阅读 882评论 1 3