zoukankan      html  css  js  c++  java
  • 用注解实现SpringMvc

    在第一次完成spirngmvc代码的基础上:

    开始时代码

    index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <body>
    <h2>Hello World!</h2>
    <%--href="some"时是到发布的项目目录下找:访问网址是http://localhost/springmvc/some
    href="/some"是直接到服务器下找:访问网址是http://localhost/some--%>
        <a href="some.do">请求</a>
    
    </body>
    </html>

    web.xml

    <!--中央调度器-->
      <servlet>
        <servlet-name>springmvc</servlet-name>
        <!--写的那个servlet-->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:springmvc.xml</param-value>
          </init-param>
      </servlet>
    <servlet-mapping>
      <servlet-name>springmvc</servlet-name>
      <!--servlet的映射路径 :是jsp通过这个路径请求后,再通过springmvc找servlet-class是谁-->
        <!--写”/“会把所有的静态请求都交给中央调度器,所以如果ggg.html也会给handler,会发生找不到404的错误,不建议使用-->
        <!--如果写”/*“的话,会把所有的请求都交给中央调度器,包括动态index.jsp,所以不能使用-->
        <!--用*.do或者*.go可以解决这个问题:1.让提交请求的路径后面加上.do 例如:<a href="some.do">
        2.在注册的时候也写上"/请求路径.do"
        3.<url-pattern>*.do</url-pattern>
        即所有后缀为.do的请求都可以被中央调度器接收了,不加就不用接收了-->
        <!---->
      <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    springmvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--注册处理器:bean的id必须以"/"开头,因为id是一个路径-->
    <!--<bean id="/some.do" class="com.abc.handler.SomeHandler"/>-->
    <!--注册组件扫描器-->
        <context:component-scan base-package="com.abc.handler"/>
    <!--一开始只设置注册组件扫描器,和在handler上加一个注解@Controller,运行点击请求报错404。因为请求会通过xml给中央调度器,中央调度器servlet会根据/some,再找SomeHandler,
    但是现在虽然扫描到base-package="com.abc.handler",但是你配置处理器SomeHandler具体的名字(你还没有告诉系统),还有该处理器内方法的名字(一个处理器内可以有好几个名字),
    
    -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>

    SomeHandler.java

    import org.springframework.stereotype.Controller;
    import org.springframework.web.servlet.ModelAndView;
    /*import org.springframework.web.servlet.mvc.Controller;*/
    /*
    
    * @Service:service
    * @Controller:处理器
    * @Respostory:dao
    * 和@Component:功能相同,意义不同
    *
    * */
    //0.
    /*1.用注解不需要实现Controller接口了
     2.用接口时导入的包删掉,改为注解的包
     3.不用接口了,handleRequest方法不用重写了,方法名随意写,返回值类型不变
     4.
     */
    
    @Controller
    public class SomeHandler {
    
        public ModelAndView doFirst(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","helloSpringMvc");
            return mv;
        }
    }

    一开始只设置注册组件扫描器,和在handler上加一个注解@Controller,就运行点击请求报错404。因为请求会通过xml给中央调度器,中央调度器servlet会根据/some,再找SomeHandler,
    但是现在虽然扫描到base-package="com.abc.handler",但是你配置处理器SomeHandler具体的名字(你还没有告诉系统),还有该处理器内方法的名字(一个处理器内可以有好几个名字),

    接着我在SomeHandler处理器内@Controller后面加上("/some.do"),如下

    @Controller("/some.do")
    public class SomeHandler {...

    结果报错:

    HTTP Status 500 – Internal Server Error


    Type 异常报告

    消息 No adapter for handler [com.abc.handler.SomeHandler@3bdc7430]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler

    中央调度器调度的时候需要包含一个的适配器支持这个处理器。这个时候是因为适配器找不到SomeHandler.java类中的方法doFirst(),这个时候适配器适配不了这个handler,因为没有正确的方法响应了

    这个时候应该给出方法的路径,需要在方法上进行配置:

    @RequestMapping("/some.do")   请求映射(根据请求的路径/some.do可以映射到doFirst方法):如果是/some.do的时候就找到doFirst方法了

    修改后代码如下:

    @Controller
    public class SomeHandler {
        //请求映射:如果是/some.do的时候就找到doFirst方法了
    @RequestMapping("/some.do")
        public ModelAndView doFirst(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","helloSpringMvc");
            return mv;
        }
    }
    View Code

    点击,成功访问。

    (为什么不加注解的时候可以找到对应的方法呢,因为那个时候的代码如下:

    public class SomeHandler implements Controller{
    
        @Override
        public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","helloSpringMvc");
            return mv;
        }
    }

    SomeHandler实现了Servlet类中的Controller接口,并用了特定的方法名 handleRequest,而现在两者都没有了)。

    接着又出现下一个问题,如果有两个handler里方法前面都加上了注解@RequestMapping("/some.do"),那么中央调度器会在handler对象里根据/some.do找出两个不同处理器中的两个方法,

    会报错:to { /some.do}: There is already 'someHandler' bean method,加了namespace解决,代码:

    @Controller
    @RequestMapping("/sss")
    public class xxxHandler {
        //此时这个some在这个sss命名空间起作用了
        @RequestMapping("/some.do")
        public ModelAndView aaa(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
    
            return null;
        }
    }
    View Code
    @Controller
    @RequestMapping("/some") //命名空间
    public class SomeHandler {
        //请求映射:如果是/some.do的时候就找到doFirst方法了
        //此时这个some在这个规定的/some命名空间起作用,
    @RequestMapping("/some.do")
        public ModelAndView doFirst(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","helloSpringMvc");
            return mv;
        }
    }
    View Code

    给handler类加一个限制,起一个命名空间,为了避免方法的路径重复。

    另外要把index.jsp里的请求路径修改为:<a href="${pageContext.request.contextPath}/some/some.do">请求</a>,不加会404报错。

    现在改需求:现在是/some.do可以访问dofirst()方法,我想再发个fistdo请求也使用dofirst()方法由它来响应。

    其实@RequestMapping("/some.do"),方法的path里value()是string[]类型,所以可以写成这样实现@RequestMapping({"/some.do","first.do"})

    用注解实现一个方法给多个请求响应,实现多个请求访问一个handler类里的不同响应方法:

    @Controller
    @RequestMapping("/some") //命名空间,相当于该类的代名词为some
    public class SomeHandler {
        //请求映射:如果是/some.do的时候就找到doFirst方法了
        //此时这个some在这个规定的/some命名空间起作用,
    @RequestMapping({"/some.do","first.do"})
        public ModelAndView doFirst(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","helloSpringMvc");
            return mv;
        }
        //一个处理类内可以定义多个处理方法
    @RequestMapping("/doSecond.do")
        public ModelAndView doSecond(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //setViewName:响应视图叫什么名字,这个名字应该写相对于webapp路径下的名称(发布到服务器时项目的根目录)
            mv.setViewName("welcome");
            mv.addObject("message","hello");
            return mv;
        }
    }
    View Code
    
    
    
    
    
    与其战胜敌人一万次,不如战胜自己一次。
  • 相关阅读:
    oracle教程:PLSQL常用方法汇总
    CORBA_TAO的环境配置
    安装使用Sybase ASE 12.5
    Oracle数据库备份命令Exp/Imp
    30个非常流行的提示信息插件(jQuery Tooltip Plugin)
    Spring.NET学习笔记——目录(转)
    JavaScript trim函数大赏 (转)
    使用基于 Informix Dynamic Server 的 Server Studio JE
    接触 CORBA 内幕: IOR、GIOP 和 IIOP
    Oracle数据库SQL
  • 原文地址:https://www.cnblogs.com/hyjh/p/11902332.html
Copyright © 2011-2022 走看看