发表于: 2016-04-05 21:34:54

1 2105


【操作步骤】
1.将home.jsp静态页面变成了动态页面。
2.新建Controller类HomeController.java。



【知识总结】
1.了解EL表达式的用法。参考链接:http://blog.csdn.net/qwerasdf123/article/details/4189889

2.了解InternalResourceViewResolver。参考链接:http://www.cnblogs.com/crazy-fox/archive/2012/02/18/2357675.html

3.WEB-INF文件夹的作用:WEB-INF的存在以及其下的lib和classes目录的作用都是jsp规定的,主要是系统运行的配置信息和环境,用来存储服务端配置文件信息和在服务端运行的类文件,它下面的东西不允许客户端直接访问的,这是jsp环境的规定。
  所以为了安全起见,一般会将jsp文件放到WEB-INF文件夹下,对于外部访问来说,WEB-INF下的文件都是不可见的(即不能通过url获得WEB-INF下的任何文件),所以,直接访问jsp是不可能的,这样可以避免客户直接访问到页面

4.总结一下我在转换动态页面时碰到的问题及解决:
    4.1 首先,需要在分发器dispatcher-servlet.xml中配置好viewResolver,一般情况下都会这样配置:
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
    这样配置的意思是使用InternalResourceViewResolver视图解析器来解析InternalResourceView视图类型,要注意的是前缀和后缀,前缀是“/WEB-INF/jsp/”,后缀是“.jsp”,这样的话,如果在Controller类中返回一个“task13-home”的逻辑视图名,就意味着要访问的视图路径是“/WEB-INF/jsp/task13-home.jsp”。
    这里还要注意的是,视图实现类和视图解析器有好多种,根据需要进行选择,在这里,因为我把JSP文件作为视图,所以就应该选则InternalResourceView这一视图实现类,相应的,视图解析器实现类就选择InternalResourceViewResolver。
    4.2 需要注意的是,为了安全起见,一般都把jsp文件放到WEB-INF目录下,这样在地址栏输入jsp文件的路径就会提示NOT FOUND,但是WEB-INF并不会作为一个目录,意思就是说,如果在webapp目录下有一个css文件夹,里面有bootstrap.min.css样式;同时在webapp目录下还有WEB-INF文件夹,WEB-INF文件夹中有一个jsp文件夹,home.jsp文件在jsp中,此时,home.jsp如果想引用bootstrap.min.css样式,采用相对路径“../css/bootstrap.min.css”就可以引用到,而不用写“../../css/bootstrap.min.css”,也就是说WEB-INF可以看做一个虚壳子,而不是一个真正的文件夹,使用相对路径时,可以假装它不存在。
    4.3 这个时候问题来了,当把jsp文件放到WEB-INF文件夹下时,在地址栏中输入home.jsp的路径发现找不到页面了,输入“http://localhost:8080/ITtask_4/jsp/home.jsp”和“http://localhost:8080/ITtask_4/WEB-INF/jsp/home.jsp”都找不到,这可怎么办呢。其实我们根本不用通过这种方式来调用jsp页面,而且也不能够通过这种方式来调用jsp。正确的调用方法是通过Controller类中设置的@RequestMapping来调用,这才是正确的调用REST接口的姿势。刚开始我还没有把jsp文件放到WEB-INF下时,就一直是通过输入jsp文件路径来调用页面,导致的结果就是在页面上死活显示不出我所需要的动态数据,我还在纳闷呢,我明明在Controller类中把所有的方法都配置好了,而且也返回了ModelAndView,路径也都正确,可为啥就是显示不出数据呢。后来灵机一动,才发现不能在地址栏输入路径,而应该是调用REST接口。
    4.4 具体的方法是,先在dispatcher-servlet.xml中配置好viewResolver,然后在Controller类中编写好接口,设置好@RequestMapping,将视图逻辑名正确指向jsp文件,然后就可以在jsp页面利用EL表达式或者C标签调用数据了,最后通过Controller类中的@RequestMapping在地址栏中进行页面获取。jsp调用数据方法示例:<c:out value="${studentCount}" /> 或者 ${studentCount}
    4.5 其实在Controller类中并不是必须要返回ModelAndView这一类型的,SpringMVC提供了四种传输模型数据的途径:
        4.5.1 ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
        4.5.2 @ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中。此时方法体通过返回String类型来直接返回视图逻辑名。
        4.5.3 Map及Model:入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map时,处理方法返回时,Map中的数据会自动添加到模型中。同样返回String类型。
        4.5.4 @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性。
        4.5.5 对于那些返回String、View或者ModelMap等类型的处理方法,SpringMVC会在内部将它们装配成一个ModelAndView对象,它包含了视图逻辑名和模型对象的信息。
        4.5.6 SpringMVC可真牛逼!!

5.关于操作步骤2的原因。为什么要建这个类。
  我的home.jsp页面里面需要两个数据,一个是studentCount,一个是classCount,我在操作步骤1中实现了往home.jsp页面中加入studentCount这一数据,在地址栏输入“http://localhost:8080/ITtask_4/student/findtotalcount”可以调出home.jsp页面,而且能够正常显示studentCount数据,但是由于实现方法是在StudentController类中的,我还想往home.jsp页面中加上classCount数据,就在ClassController类中实现findTotalCount方法,在地址栏输入“http://localhost:8080/ITtask_4/classes/findtotalcount”也可以调出home.jsp页面,但就在这个时候,问题出现了,所调出的页面中,classesCount这个数据正常显示了,但是studentCount数据不见了,这就说明你调用的是哪个接口,程序就执行哪个函数,我调用的是“/classes/findtotalcount”这个接口,当然就只执行了ClassesController类中的findTotalCount方法,没有执行StudentController类中的findTotalCount方法,所以classesCount数据正常显示,但是studentCount数据就显示失败了。
  所以,要重新建立一个HomeController类,在这个类里面把得到两个数据的执行方法都调用。



【出现的问题(已解决)】
1.eclipse提示错误:Syntax error on tokens, delete these tokens。解决办法:出现这种错误的原因是有中文字符或者符号,包括空格。

2.在操作步骤2中,建立HomeController类时,需要引入StudentService类和ClassesService类,刚开始我是这样写的:
    @Autowired
    private ClassesService classesService;
    private StudentService studentService;
  结果在调用studentService的findTotalCount方法时抛异常,而且debug无法进入该方法,直接就跳到catch语句中去了。
  后来我改成了:
    @Autowired
    private ClassesService classesService;
    @Autowired
    private StudentService studentService;
  问题解决。由此可见,每一个注解语句只能控制与它紧邻的一条语句。

3.在知识总结4.2中我说WEB-INF是个虚壳子,在jsp中写相对路径不用考虑WEB-INF的存在,后来我又发现完全不是那么回事。这个可就说来话长了。至少在我还没有写HomeController类之前,把WEB-INF这个文件夹看成一个虚壳子是正确的。
  我在写HomeController类时发现一个问题,就是如果我在类名前加上@RequestMapping("/pages"),在ShowHomePage方法名前加上@RequestMapping("/home"),那么我在地址栏输入“http://localhost:8080/ITtask_4/pages/home”可以获取到home.jsp页面,而且样式、图片一切正常。但是如果我去掉类名前面的@RequestMapping("/pages"),只留下方法名前面的@RequestMapping("/home"),当我在地址栏输入“http://localhost:8080/ITtask_4/home”时,还是可以获取到home.jsp页面,动态数据也能正常显示,但是样式、图片都失效了。这很明显就是路径出了问题。
  我最终的解决办法是把home.jsp页面中的静态资源(包括css、图片、js)的路径全部换成了绝对路径。其实换起来也很方便,我现在home.jsp页面前面加上:
    <%  
    String path = request.getContextPath();  
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
    %>
    <base href="<%=basePath%>">
  然后后面就直接以webapp目录为根目录就可以了。


【出现的问题(未解决)】
1.今天只是把home.jsp这个页面变成了动态页面,但是因为我把所有的jsp页面(包括partner.jsp和profession.jsp这两个页面)都放到了WEB-INF目录下,当我在浏览器中获取到home.jsp页面时,想要跳转页面就会报错,NOT FOUND,原因我清楚,明天想解决办法。
2.明天看Tiles框架。



【疑问】
1.当jsp文件被放到WEB-INF文件夹下时,jsp中引用图片和样式时,应该怎样处理WEB-INF文件夹,采用绝对路径是绝对可以,但是采用相对路径有时候就会出问题,而且这个路径好像还和地址栏中的输入有关,我输入 “http://localhost:8080/ITtask_4/pages/home”就正常,输入“http://localhost:8080/ITtask_4/home”就会出错,这是为什么呢?


返回列表 返回列表
评论

    分享到