首页 > 代码库 > springMVC课程02

springMVC课程02

1、在springmvc中,json数据里面的data参数里面必须用双引号,才能传到后台一json对象,然后才能被@RequestBody转成javabean对象,并且要在外面用单引号括起来(传json整个数据的时候)--在springmvc里面用的多------

如果不加单引号,传递过去的就是一个参数键值对,而不是一个完整的json对象
                        contentType:‘application/json;charset=utf-8‘,
data:‘{"name":"黑妹牙膏","price":"999"}‘,


2、传参数的时候,data参数是一个对象,{},外面如果加双引号或者单引号,会得不到数据(struts2)


一、内容回顾:

线程安全概念:

线程安全:多次访问同一个对象/变量,得到同一个结果
线程不安全:多次访问同一个对象/变量,得到不同结果

1、springmvc是否线程安全

安全,springmvc底层是servlet,是单例

2、i++,++i是否线程安全

成员变量:线程不安全
public class A{
    int i=9;
    i++;
}

3、有了struts2,为什么还需要使用springmvc?

①、底层实现机制:struts2:过滤器    springmvc:servlet
②、运行效率:struts2 :多例运行 很耗资源    springmvc:单例,比struts快
③、参数封装:struts2:基于属性进行封装        springmvc:基于方法进行封装---方法参数是局部变量,方法执行结束,方法变量内存释放。

二、springmvc相关注解

1、@RequestMapping注解的几种使用

         * 1,@RequestMapping("itemsList")
* 2,@RequestMapping("/itemsList")
* 3,@RequestMapping("itemsList.do")    --前提是web.xml里面配置的路径为    *.do
* 4,@RequestMapping(value="http://www.mamicode.com/itemsList")
* 5,@RequestMapping(value="http://www.mamicode.com/itemsList",method=RequestMethod.POST)
* 6,@RequestMapping(value="http://www.mamicode.com/itemsList",method=RequestMethod.GET)
* 7,@RequestMapping(value="http://www.mamicode.com/itemsList",method={RequestMethod.GET,RequestMethod.POST})
              (href,直接通过浏览器发送都是get请求;form表单,ajax指定post,都是post)

2、@RequestParam注解:

       * 功能:
* 1,设置默认值(如果页面传递值为null,自动设置为默认值) @RequestParam(defaultValue="http://www.mamicode.com/2")
* 2,设置别名 (如果页面传递参数名称和方法接受参数名称不一致,设置别名) @RequestParam(value="http://www.mamicode.com/ids")
* 同时设置:
* @RequestParam(defaultValue="http://www.mamicode.com/2",value="http://www.mamicode.com/ids")

3、商品更新

  1. /**
  2. * 需求:根据id更新商品数据
  3. * 请求:/item/updateSubmit
  4. * 参数:item
  5. * 返回值:重定向商品列表
  6. */
  7. @RequestMapping("/item/updateSubmit")
  8. public String updateSubmit(Item item){
  9. itemService.updateItemByID(item);
  10. return "redirect:/itemsList.do";
  11. }
  1. <!-- 商品更新 -->
  2. <update id="updateItemByID" parameterType="item" >
  3. update items set name=#{name},price=#{price},detail=#{detail},pic=#{pic},createtime=#{createtime}
  4. where id=#{id}
  5. </update>


4、窄化请求映射
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
技术分享
 这种情况就会一个路径可以找到两个方法,产生错误
如下:
@RequestMapping放在类名上边,设置请求前缀 
@Controller
@RequestMapping("/item")

方法名上边设置请求映射url:
@RequestMapping放在方法名上边,如下:
@RequestMapping("/queryItem ")

访问地址为:/item/queryItem


5、重定向和转发

    ①、重定向:
        return "redirect:/itemsList.do"    /在下面这种情况不能省略
  1. @RequestMapping("/item/updateSubmit")
  2. public String updateSubmit(Item item){
  3. itemService.updateItemByID(item);
  4. return "redirect:itemsList.do";
  5. }
           这种方式重定向的路径为   /item/itemList.do
           如果两个方法的路径在同一级的话,那么 / 可以去掉(这是下面说的本类重定向)-----不是在同一个类里面也可以,同一级就行
         * 需求:重定向
* 本类重定向:
* 1,return "redirect:list.html"
* 2,return "redirect:/red/list.html"
* 跨类重定向:
* 1,return "redirect:/itemsList.html"    必须要有 /  或者根路径
        ②、转发:
  1. @Controller
  2. @RequestMapping("for")
  3. public class ForwardController {
  4. @RequestMapping("list")
  5. public String list(){
  6. System.out.println("hhhhhh");
  7. return null;
  8. }
  9. /**
  10. * 需求:转发
  11. * 本类转发:
  12. * 语法:
  13. * 1,return "forward:list.html"
  14. * 2,return "forward:/red/list.html"
  15. * 跨类转发:
  16. * 1,return "forward:/itemsList.html"
  17. */
  18. public String forward(){
  19. //return "forward:/red/list.html";
  20. //本类转发:
  21. //子路径
  22. //return "forward:list.html";
  23. //return "forward:/for/list.html";
  24. //跨类转发:
  25. return "forward:/itemsList.do";
  26. }
  27. }


6、json转换注解:

@RequestBody:  请求    把json格式请求参数转换为javabean
@ResponseBody:  响应    把javabean对象自动转换json对象,返回页面
注解支持:1、mvc注解驱动    2、Jackson包支持    3、请求json,返回json都是js操作
需要配置    <mvc:annotation-driven />
①、在springmvc中,json数据里面的data参数里面必须用双引号,并且要在外面用单引号括起来(传json整个数据的时候)--在springmvc里面用的多------

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


②、传参数的时候,data参数是一个对象,{},外面如果加双引号或者单引号,会得不到数据(struts2)
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4. <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script>
  5. <script type="text/javascript">
  6. function reqJson (){
  7. $.ajax({
  8. type:"post",
  9. url:‘${pageContext.request.contextPath}/reqJson.do‘,
  10. contentType:‘application/json;charset=utf-8‘,
  11. data:‘{"name":"黑妹牙膏","price":"999"}‘,
  12. success:function(data){
  13. //返回json对象
  14. alert(data.name);
  15. }
  16. })
  17. }
  18. </script>
  19. <title>Insert title here</title>
  20. </head>
  21. <body>
  22. <button onclick="reqJson();" >请求json,返回json格式的数据</button>
  23. </body>
  24. </html>
  1. @Controller
  2. public class JsonController {
  3. /**
  4. * 需求:跳转传递参数页面
  5. */
  6. @RequestMapping("json")
  7. public String json(){
  8. return "reqJson";
  9. }
  10. /**
  11. * 需求:接受json格式参数,返回json对象
  12. * @requestBody:接受json格式参数,自动把json格式参数自动转换对象
  13. * @responseBody:自动把返回对象转换成json格式返回
  14. */
  15. @RequestMapping("reqJson")
  16. @ResponseBody
  17. public Item reqJson(@RequestBody Item item){
  18. System.out.println(item);
  19. return item;
  20. }
  21. }


7、springmvc的异常处理:

技术分享
 
①、定义一个可预期的异常类
  1. public class CustomException extends Exception {
  2. //定义一个字符串变量,封装自定义异常信息
  3. private String message;
  4. public void setMessage(String message) {
  5. this.message = message;
  6. }
  7. public String getMessage() {
  8. return message;
  9. }
  10. //构造函数,封装异常信息
  11. public CustomException(String message) {
  12. super(message);
  13. this.message=message;
  14. }
  15. }
②、创建异常处理器:
  1. public class ExceptionResolve implements HandlerExceptionResolver {
  2. @Override
  3. public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res,
  4. Object obj, Exception ex) {
  5. CustomException ce=null;
  6. //判断异常信息是否是自定义异常
  7. if (ex instanceof CustomException) {
  8. ce=(CustomException) ex;
  9. }else{
  10. //运行时异常信息
  11. ce = new CustomException("运行时异常,请联系管理员!");
  12. }
  13. ModelAndView mv = new ModelAndView();
  14. //设置异常数据
  15. mv.addObject("ex", ce.getMessage());
  16. mv.setViewName("error/error");
  17. return mv;
  18. }
  19. }
③、在springmvc.xml里面配置异常处理器
<!-- 配置全局异常处理器 -->
    <bean class="com.itcast.utils.ExceptionResolve" ></bean>


8、文件上传

技术分享
 


①、方案:创建一个单独的服务器,单纯存储图片,两台服务器的交互,异步上传
②、需求:上传图片,页面不刷新,图片立马回显,存在另一台服务器,跨服务器
③、技术:ajax            jersy-io(跨服务器)    commons-io、commons-fileupload(上传)
④、文件上传的环境
技术分享技术分享技术分享
 ⑤、springmvc.xml中配置上传文件的解析器
 注意:必须配置 id ,并且为   multipartResolver 
  1. <!-- 上传文件解析器 -->
  2. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
  3. <property name="maxUploadSize" value="10240000" ></property><!-- 单位字节 -->
  4. </bean>
⑥、图片服务器搭建
           创建新的服务器:
技术分享
              修改新的服务器的端口号:
 技术分享
 
           修改服务器权限:
技术分享技术分享
 
 ⑦、ajax异步上传:
             jsp页面:
  1. <form id="itemForm" action="${pageContext.request.contextPath}/item/updateSubmit" method="post" >

  2. <td>
  3. <!-- 图片回显 -->
  4. <img id="imgSize1ImgSrc" src="" height="100" width="100" >
  5. <!-- ajax异步上传函数 -->
  6. <input type="file" id="imgSize1File" name="imgSize1File" class="file" onchange="submitImgSize1Upload" >
  7. <!-- 保存数据库图片地址 -->
  8. <input type="hidden" id="imgSize1" name="pic" value="" reg="^.+$" tip="亲,您忘记上传图片了" >
  9. </td>
  10. </form>
            js代码:
 为了使ajax提交的时候,request域中有文件的流对象,所以需要将表单"异步"提交
 
  1. <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js" ></script>
  2. <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.form.js" ></script>
  3. <script type="text/javascript">
  4. function submitImgSize1Upload(){
  5. var option={
  6. type:‘post‘,
  7. url:‘${pageContext.request.contextPath}/uploadPic.do‘,
  8. dataType:‘text‘,
  9. data:{
  10. fileName:‘imgSize1File‘
  11. },
  12. success:function(data){
  13. //把返回json格式字符串转换json对象
  14. var obj = $.parseJSON(data);
  15. //图片立马回显
  16. $("#imgSize1ImgSrc").attr("src",obj.fullPath);
  17. //图片保存数据地址
  18. $("#imgSize1").val(obj.fullPath);
  19. }
  20. };
  21. //使用ajax异步提交表单
  22. $("#itemForm").ajaxSubmit(option);
  23. }
  24. </script>
也可以直接把dataType改成"json",在success函数中就不用转换了(原本是字符串转换为json对象)

⑧、后台代码:
 新建一个UpLoadController类

* 需求:上传文件:avi,xls,doc,jpg
* 参数:String fileName,HttpServletRequest,PrintWriter
* 返回值:void
  1. public class UploadController {
  2. /**
  3. * 需求:上传文件:avi,xls,doc,jpg
  4. * 参数:String fileName,HttpServletRequest,PrintWriter
  5. * 返回值:void
  6. */
  7. @RequestMapping("/uploadPic")
  8. public void uploadPic(String fileName,HttpServletRequest request,PrintWriter out){
  9. //把request转换多部件对象
  10. MultipartHttpServletRequest mh = (MultipartHttpServletRequest) request;
  11. //获取文件对象
  12. CommonsMultipartFile cm = (CommonsMultipartFile) mh.getFile(fileName);
  13. //获取文件扩展名
  14. //a、获取文件名称
  15. String originalFilename = cm.getOriginalFilename();
  16. //b、截取文件扩展名
  17. String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
  18. //使用uuid生成文件名称
  19. String fName = UUID.randomUUID().toString();
  20. //上传文件 jersey工具
  21. Client create = Client.create();
  22. //制定上传的服务器路径
  23. WebResource resource = create.resource(Constants.IMAGE_ADDR+"upload/"+fName+extName);
  24. //上传
  25. resource.put(String.class, cm.getBytes());
  26. //图片回显,需要图片地址返回给ajax的回调函数
  27. //返回json格式数据
  28. String fullPath = Constants.IMAGE_ADDR+"upload/"+fName+extName;
  29. //构造一个json格式数据
  30. String result="{\"fullPath\":\""+fullPath+"\"}";
  31. //返回
  32. out.print(result);
  33. }
  34. }

⑨、修改保存图片
直接提交就可以了


三、restfull软件设计

restfull是一种软件架构设计风格模式
特点:请求没有参数,没有扩展名
案例:http://geek.csdn.net/news/detail/200288    (restfull风格请求)
优点:简洁,容易被搜索引擎系统收录

springmvc实现restfull风格软件架构

       1、 springmvc URI模板映射

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

url中的{id}会自动映射到参数id上,{name}和参数中的name匹配,可以取别名

        2、servlet拦截目录

  1. <servlet-mapping>
  2. <servlet-name>springmvc</servlet-name>
  3. <url-pattern>/</url-pattern><!-- 拦截所有,包括css,js,images -->
  4. </servlet-mapping>

        3、配置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的结果视图也不行,所以不用

四、拦截器:

1、简单测试:


  1. public class Interceptor1 implements HandlerInterceptor{
  2. @Override
  3. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
  4. System.out.println("这是第一个拦截器的preHandle");
  5. return true;
  6. }
  7. @Override
  8. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
  9. throws Exception {
  10. System.out.println("这是第一个拦截器的postHandle");
  11. }
  12. @Override
  13. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
  14. throws Exception {
  15. System.out.println("这是第一个拦截器的afterCompletion");
  16. }
  17. }
第二个拦截器一样,return false

preHandle:处理器映射器执行之前进行执行,拦截:return false;放行:return true;
postHandle:返回model和view之前执行
afterCompletion:返回model和view之后执行

在springmvc中配置拦截器:
  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <mvc:mapping path="/**"/>
  5. <bean class="com.itcast.interceptor.Interceptor1" ></bean>
  6. </mvc:interceptor>
  7. <mvc:interceptor>
  8. <mvc:mapping path="/**"/>
  9. <bean class="com.itcast.interceptor.Interceptor2" ></bean>
  10. </mvc:interceptor>
  11. </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必须执行


五、拦截器登录案例

  1. public class LoginInterceptor implements HandlerInterceptor{
  2. //判断用户是否登录
  3. @Override
  4. public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception {
  5. //登录页面,登录请求放行
  6. if (req.getRequestURI().contains("login")) {
  7. //放行
  8. return true;
  9. }
  10. Object user = req.getSession().getAttribute("user");
  11. if (user!=null) {
  12. return true;
  13. }
  14. //如果未登录,跳转登录页面
  15. req.getRequestDispatcher("WEB-INF/jsp/login.jsp").forward(req, res);
  16. return false;
  17. }

  1. <mvc:interceptor>
  2. <mvc:mapping path="/**"/>
  3. <bean class="com.itcast.interceptor.LoginInterceptor" ></bean>
  4. </mvc:interceptor>
  1. @Controller
  2. public class LoginController {
  3. @RequestMapping("login")
  4. public String login(String username,String password,HttpSession session){
  5. session.setAttribute("user", username);
  6. return "redirect:/itemsList";
  7. }
  8. }





























<style>p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5000pt } span.10 { font-family: "Times New Roman" } span.15 { font-family: "Times New Roman" } p.MsoFooter { margin: 0pt; margin-bottom: .0001pt; text-align: left; font-family: "Times New Roman"; font-size: 9.0000pt } p.MsoHeader { margin: 0pt; margin-bottom: .0001pt; border-bottom: 1.0000pt solid windowtext; padding: 0pt 0pt 1pt 0pt; text-align: center; font-family: "Times New Roman"; font-size: 9.0000pt } span.msoIns { text-decoration: underline; color: blue } span.msoDel { text-decoration: line-through; color: red } div.Section0 { }</style>

null


springMVC课程02