0
点赞
收藏
分享

微信扫一扫

基于Javaweb的小项目(类似于qqzone) 9 —— 开发过程中的细节

一葉_code 2022-05-04 阅读 67

1.日期和字符串之前的格式化

(1)Java

//String -> java.util.Date
String datestr1 = "2021-12-19 22:22:22";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
    Date date1 = sdf.parse(datestr1);
} catch (ParseException e) {
    e.printStackTrace();
}

//Date -> String
Date date2 = new Date();
String datestr2 = sdf.format(date2);

(2)Thymeleaf中使用#dates这个公共的内置对象

<td th:text="${#dates.format(topic.topicDate,'yyyy-MM-dd HH:mm:ss')}">2021-09-01 12:30:55</td>

2.系统启动时,我们访问的页面是:http://localhost:8080/qqzone1.0/page.do?operation=page&page=login

3.访问http://localhost:8080/qqzone1.0/page.do?operation=page&page=login这个URL,执行的过程是什么?

答:

  • http://:协议
  • localhost:ServerIP服务器IP地址
  • :8080:port端口号
  • /qqzone1.0:context root
  • /page.do:request.getServletPath()
  • ?operation=page&page=login:query string

1)DispatcherServlet -> urlPattern : *.do 拦截/page.do

2)request.getServletPath() -> /page.do

3)解析处理字符串,将/page.do -> page

4)拿到page这个字符串,然后去IOC容器(BeanFactory)去寻找id=page的那个bean对象 -> PageController.java

5)获取operation的值 -> page,因此得知,应该执行PageController中的page()方法

6)PageController中的page()方法定义如下:

    public String page(String page) {
        return page; // frames/left
    }

7)在querystring?operation=page&page=login中获取请求参数,参数名是page,参数值是login

  • 因此,page方法的参数page值会被赋上"login"
  • 然后return "login",return给谁呢?

8)因为PageControllerpage方法是DispatcherServlet通过反射调用的method.invoke(....);

因此,字符串"login"返回给Dispatcherservlet

9)Dispatcherservlet接收到返回值,然后处理视图

  • 目前处理视图的方式有两种:
    • 1.带有前缀redirect
    • 2.不带前缀
  • 当前,返回"login",不带前缀
  • 那么执行super.processTemplate("login",rewuest,response);

10)此时ViewBaseServlet中的processTemplate方法会执行,效果是:

  • "login"这个字符串前面拼接"/"(其实就是配置文件中view-prefix配置的值);
  • "login"这个字符串后面拼接".html"(其实就是配置文件中view-suffix配置的值)
  • 最后进行服务器转发

4.目前javaweb项目开发的"套路"是这样的:

1)拷贝 myssm

2)新建配置文件 applicationContext.xml或者可以不叫这个名字,在web.xml中指定

3)在web.xml文件中配置:

  • 配置前缀和后缀,这样thymeleaf引擎就可以根据我们返回的字符串进行拼接

    <context-param>
      <param-name>view-prefix</param-name>
      <param-value>/</param-value>
    </context-param>
    <context-param>
      <param-name>view-suffix</param-name>
      <param-value>.html</param-value>
    </context-param>
    
  • 配置监听器要读取的参数,母的是加载IOC容器的配置文件(也就是applicationContext.xml

    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>applicationContext.xml</param-value>
    </context-param>
    

4)开发具体的业务模块

  • 一个具体的业务模块纵向上由几个部分组成:

    • html页面
    • POJO
    • DAO接口和实现类
    • Service接口和实现类
    • Controller 控制器组件
  • 如果html页面有thymeleaf表达式,一定不能直接访问,必须要经过PageController

  • applicationContext.xml中配置DAOServiceController,以及三者之间的依赖关系

  • DAO实现类中,继承BaseDAO,然后实现具体的接口,例如:

    public class UserDAOImpl extends BaseDAO<User> implements UserDAO() {}
    
  • Service是业务控制类,这一层只需要注意一点:

    • 业务逻辑都是封装在service这一层,不要分散在Controller层,也不要出现在DAO层(我们需要保证DAO方法的单精度特性)。
    • 当某一个业务需要使用其他模块的业务功能时,尽量的调用别人的service,而不是深入到其他模块的DAO细节。
  • Controller类的编写规则

    • applicationContext.xml中配置controller

      <bean id="user" class="com.javaweb.qqzone.zone.controller.UserController">
          <property name = "userBasicService" ref = "userBasicService"/>
          <property name = "topicService" ref = "topicService"/>
      </bean>
      

      那么,用户在前端发请求时,对应的servletPath就是/user.do,其中的"user"就是对应的beanid

    • Controller中设计的方法名需要和operation的值一致

      public String login(String loginId, String pwd, HttpSession session){
          return "index";
      }
      

      因此,登录验证的表单如下:

      <form th:action="@{/user.do}" method="get">
           <input type="hidden" name="operation" value="login"/>
      </form>
      
    • 在表单中,组件的name属性和controller中的方法的参数名一致

      <input type="text" name="loginId" />
      
    • 另外,需要注意的是:Controller中的方法的参数不一定都是通过请求参数获取的

       if ("request".equals(parameterName)) {
           parameterValues[i] = request;
       } else if ("response".equals(parameterName)) {
           parameterValues[i] = response;
       } else if ("session".equals(parameterName)){
           parameterValues[i] = request.getSession();
       } else {
           //此处才是从request的请求参数中获取
           request.getParameter("loginId");
       }
      
  • DispatcherServlet中的步骤大致分为:

    • application作用域获取IOC容器
    • 解析ServletPath,在IOC容器中寻找对应的Controller组件
    • 准备operation指定的方法所要求的参数
    • 调用operation指定的方法
    • 接收到执行operation指定的方法的返回值,对返回值进行处理——视图处理
  • 为什么DispatcherServlet能从application作用域获取到IOC容器?

    ContextLoaderListener在容器启动时会执行初始化任务,而它的操作就是:

    • 解析IOC的配置文件,创建一个一个的组件,并完成组件之间依赖关系的注入
    • IOC容器保存到application作用域
举报

相关推荐

0 条评论