案例1:水果库存管理系统

文章目录

一.fruit

1.controller

调用fruitService中的基本业务,实现封装的业务功能

1.1update()

private String update(Integer fid, String fname, Integer price, Integer fcount, String remark){
    //更新数据库
    fruitService.updateFruit(new Fruit(fid,fname,price,fcount,remark));
    //渲染页面,执行跳转
    return "redirect:fruit.do";
}

1.2edit():发报机–>edit()–>edit.html–>update()–>主界面

private String edit(Integer fid, HttpServletRequest req){
    if(fid != null){
        Fruit fruit = fruitService.getFruitByFid(fid);
        req.setAttribute("fruit", fruit);
        return "edit";
    }
    return "error";
}

1.3delete()

private String delete(Integer fid){
    if(fid != null){
        //删除数据库记录
        fruitService.deleteFruit(fid);
        //客户端重定向语句
        return "redirect:fruit.do";
    }
    return "error";
}

1.4index()

private String index(String oper, String keyword,Integer pageNo, HttpServletRequest req){
    //获取会话
    HttpSession session = req.getSession();
    if(pageNo == null){
        pageNo = 1;
    }
    //判断是否为查询操作
    if(StringUtil.isNotEmpty(oper) && "search".equals(oper)){//搜索操作
        //获取关键词
        if(StringUtil.isEmpty(keyword)){
            keyword = "";
        }
        //将关键词保存到session
        session.setAttribute("keyword",keyword);
    }else{//显示全部列表
        //获取session关键词
        Object keyObj = session.getAttribute("keyword");
        if(keyObj == null){
            keyword = "";
        }else{
            keyword = (String)keyObj;
        }
        //设置关键词
        session.setAttribute("keyword", keyword);
    }
    //保存当前页码到session作用域
    session.setAttribute("pageNo",pageNo);
    keyword = (String)session.getAttribute("keyword");
    //保存总页码到session作用域
    int pageCount = fruitService.getPageCount(keyword);
    session.setAttribute("pageCount",pageCount);
    //从数据库读取fruitList
    List<Fruit> fruitList = fruitService.getFruitList(keyword, pageNo);
    //保存到session作用域
    session.setAttribute("fruitList", fruitList);
    //此处的视图名称为 index
    //thymleaf会将 逻辑视图名称 对应到 物理视图名称 上去
    //逻辑视图名称:index
    //物理视图名称:view-prefix + 逻辑视图名称 + view-suffix
    //super.processTemplate("index", request, response);
    return "index";
}

1.5add():发报机–>add.html–>add()–>主界面

private String add(String fname, Integer price, Integer fcount, String remark){
    //更新数据库
    fruitService.addFruit(new Fruit(0,fname,price,fcount,remark));
    //返回客户端重定向语句
    return "redirect:fruit.do";
}

2.dao:DAO(DataAccessobjects)

2.1FruitDAO

需要实现与数据库交互的基本功能:增删改查(总列表,单条记录,总数目)

public interface FruitDAO {
    //获取指定页码的库存列表信息,每页显示5条
    List<Fruit> getFruitList(String keyword, Integer pageNo);
    //根据水果id获取库存信息
    Fruit getFruitByFid(Integer fid);
    //修改制定的库存记录
    Boolean updateFruit(Fruit fruit);
    //根据fid删除库存记录
    Boolean delFruitById(Integer fid);
    //添加新库存
    Boolean addFruit(Fruit fruit);
    //查询总记录条数的方法
    int getFruitCount(String keyword);
}

2.2impl.FruitDAOImpl

2.2.1继承:BaseDAO<Fruit>类 和 FruitDAO接口
2.2.2实现:重写实现FruitDAO中的方法

3.pojo

3.1Fruit基本类,对应一张表

  • 1.类的属性与表的列分别对应。
  • 2.类的属性体现类之间的关系。

4.service业务层

4.1FruitService抽象类

public interface FruitService {
    //获取指定页面的库存信息
    List<Fruit> getFruitList(String keyword, Integer pageNo);
    //添加库存记录
    void addFruit(Fruit fruit);
    //根据id查看库存信息
    Fruit getFruitByFid(Integer fid);
    //删除指定库存信息
    void deleteFruit(Integer fid);
    //获取总页数
    Integer getPageCount(String keyword);
    //修改特定库存记录
    void updateFruit(Fruit fruit);
}

4.2FruitServiceImpl实现类

调用fruitDAO中的方法实现相应的功能

二.myssm

1.basedao数据库交互包

1.1BaseDAO数据库通用语句执行

构造器:

public BaseDAO() {
    //getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
    //那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
    //因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
    //所以getGenericSuperclass()获取到的是BaseDAO的Class
    Type genericType = getClass().getGenericSuperclass();
    //ParameterizedType 参数化类型
    Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
    //获取到的<T>中的T的真实的类型
    Type actualType = actualTypeArguments[0];
    try {
        entityClass = Class.forName(actualType.getTypeName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        throw new DAOException("BaseDAO 构造方法出错了,可能的原因是没有指定<>中的类型");
    }
}
  1. 获取连接:getConn()调用ConnUtil类中的获取连接方法,保证只有一个连接(为了方便事务管理中的回滚)

  2. ~~关闭资源:close()~~取消该方法,方便事务管理

  3. 给预处理命令设置参数:setParams(PreparedStatement psmt , Object... params)

  4. 执行更新数据库executeUpdate(String sql , Object... params)

  5. 执行查询,返回一条记录:load(String sql , Object... params)

    //通过rs可以获取结果集的元数据
    //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
     ResultSetMetaData rsmd = rs.getMetaData();
    //获取结果集的列数
    int columnCount = rsmd.getColumnCount();
    if(rs.next()){
        for(int i = 0 ; i<columnCount;i++){
            String columnName = rsmd.getColumnName(i+1);        //fid   fname   price
            Object columnValue = rs.getObject(i+1);     		//33    苹果      5
            setValue(entity,columnName,columnValue);
        }
    }
    
  6. 执行查询,返回多条记录:executeQuery(String sql , Object... params)

  7. 执行复杂查询,统计统计结果:Object[] executeComplexQuery(String sql , Object... params)

  8. 通过反射技术给property属性赋值:setValue(Object obj, String property, Object propertyValue)

1.2ConnUtil数据库连接工具类

  1. 创建连接:createConnection)()
  2. 获取连接:getConnection()从本地线程获取连接.若连接不存在,则创建连接并保存到本地线程.
  3. 断开连接:closeConn()从本地线程获取连接,若连接存在,则关闭连接.

1.3DAOException异常类型

定义一个DAOException异常

2.filters过滤器的实现类包

包括初始化、过滤、销毁三个方法。

需要使用注解或者配置文件设置过滤对象:

//1.注解:
@WebFilter("*.do")
<!--2.xml文件-->
<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.clucky.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.1CharacterEncodingFilter设置编码

  1. 注解:拦截*.do结尾的请求

@WebFilter(urlPatterns = {“*.do”}, initParams = {@WebInitParam(name = “encoding”, value = “utf-8”)})


2. 初始化: 读取注解或者配置文件中的初始化参数设置编码*(可能是过滤器的初始化)*

 ```java
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
     String encodingStr = filterConfig.getInitParameter("encoding");
     if(StringUtil.isNotEmpty(encodingStr)){
         encoding = encodingStr;
     }
 }
  1. 过滤前后的语句: 设置编码

    ((HttpServletRequest)servletRequest).setCharacterEncoding(encoding);

2.2OpenSessionInViewFilter事务管理(执行提交与回滚)

  1. 开启事务–>执行service–>执行完成提交事务
    但是若事务执行异常–>回滚

  2.  try{
         TransactionManager.beginTrans();
         System.out.println("开启事务...");
         filterChain.doFilter(servletRequest, servletResponse);
         TransactionManager.commit();
         System.out.println("提交事务...");
     } catch (Exception e) {
         e.printStackTrace();
         try {
             TransactionManager.rollback();
             System.out.println("回滚事务...");
         } catch (Exception e1) {
             e1.printStackTrace();
             System.out.println("回滚异常");
         }
     }
    
  3. 需要TransactionManage的工具类进行管理事务的开启、提交、和回滚。

3.ioc(Inversion of Control)控制反转or依赖注入(DI)

3.1BeanFactory抽象类

3.2ClassPathXmlApplicationContext实现类

3.2.1初始化:即构造器
  1. 利用applicationContext.fxml文件建立类与类之间的关系

    <?xml version="1.0" encoding="utf-8"?>
    <beans>
        <!-- 建立fruit和对应类的映关系,方便初始化的时候调用 -->
        <bean id="fruitDAO" class="com.atlff.fruit.dao.impl.FruitDAOImpl"></bean>
        
        <bean id="fruitService" class="com.atlff.fruit.service.impl.FruitServiceImpl">
            <!-- 表示属性:name是属性名,ref表示引用其他bean的id -->
            <property name="fruitDAO" ref="fruitDAO"></property>
        </bean>
        
        <bean id="fruit" class="com.atlff.fruit.controllers.FruitController">
            <property name="fruitService" ref="fruitService"></property>
        </bean>
    </beans>
    
  2. 获取配置文件的输入流,建立创建Document对象

    InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
    //1.创建DocumentBuilderFactory对象
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    //2.创建DocumentBuilder对象
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    //3.创建Document对象
    Document document = documentBuilder.parse(inputStream);
    
  3. 获取Bean结点,创建相应的对象,放置到beanMap容器中

//4.获取所有bean结点
NodeList beanNodeList = document.getDocumentElement().getElementsByTagName("bean");
for (int i = 0; i < beanNodeList.getLength(); i++) {
    Node beanNode = beanNodeList.item(i);
    if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
        Element beanElement = (Element) beanNode;
        String beanId = beanElement.getAttribute("id");//获取id属性
        String className = beanElement.getAttribute("class");//获取class属性(返回字符串)
        //利用反射得到bean对象
        Class<?> beanClass = Class.forName(className);
        Object beanObj = beanClass.newInstance();
        //将bean对象保存到Map容器
        beanMap.put(beanId, beanObj);
    }
}
  1. 构建Bean结点之间的依赖关系
//5.组装bean之间的依赖关系
for (int i = 0; i < beanNodeList.getLength(); i++) {//遍历beanNodeList链表
    Node beanNode = beanNodeList.item(i);
    if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
        Element beanElement = (Element) beanNode;
        String beanId = beanElement.getAttribute("id");
        NodeList beanChildNodeList = beanElement.getChildNodes();//获取bean元素的子结点
        for(int j = 0; j < beanChildNodeList.getLength(); j++){
            Node beanChildNode = beanChildNodeList.item(j);
            if(beanChildNode.getNodeType()==Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){
                Element propertyElement = (Element)beanChildNode;
                String propertyName = propertyElement.getAttribute("name");
                String propertyRef = propertyElement.getAttribute("ref");
                //1)找到propertyRef对应的对象
                Object refObj = beanMap.get(propertyRef);
                //2)将refObj设置到当前bean对应的实例的property属性上去
                Object beanObj = beanMap.get(beanId);
                Class<?> beanClazz = beanObj.getClass();
                Field propertyField = beanClazz.getDeclaredField(propertyName);//设置类的属性
                propertyField.setAccessible(true);
                propertyField.set(beanObj,refObj);
            }
        }
    }
}
3.2.2调用getBean
@Override
public Object getBean(String id) {
    return beanMap.get(id);
}

4.listeners监听器

当对象发生时自动执行,类似于触发器。

功能:创建IOC容器并容器保存到session作用域,方便之后调用

注解:@WebListener

接口:ServletContextListener

方法实现:

@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
    //1.获取ServletContext对象
    ServletContext application = servletContextEvent.getServletContext();
    //2.获取上下文的初始化参数
    String path = application.getInitParameter("contextConfigLocation");
    //3.创建IOC容器
    BeanFactory beanFactory = new ClassPathXmlApplicationContext(path);
    //4.将IOC容器保存到application作用域
    application.setAttribute("beanFactory", beanFactory);
}

5.myspringmvc

5.1DispatcherServlet发报机,决定调用哪个组件

5.1.1注解@WebServlet("*.do")用于响应浏览器的"*.do"请求
5.1.2继承:ViewBaseServlet
5.1.3初始化方法:获取beanMap容器
public void init() throws ServletException {
    super.init();
    //优化:可以在ContextListener中初始化给参数赋值
    Object beanFactoryObj = getServletContext().getAttribute("beanFactory");
    if(beanFactoryObj != null){
        beanFactory = (BeanFactory)beanFactoryObj;
    }else{
        throw new RuntimeException("IOC容器获取失败!");
    }
    System.out.println("初始化完成!");
}
5.1.4service方法
  1. 获取servlet的名字,决定调用哪个组件:fruit.do --> fruit

    //获取servlet的名字
    String servletPath = req.getServletPath();
    int lastDot = servletPath.lastIndexOf(".do");
    servletPath = servletPath.substring(1, lastDot);
    //得到servlet名字对应的控制器类
    Object contollerBeanObj = beanFactory.getBean(servletPath);
    
  2. 获取控制器中对应的方法:即操作“业务”

    String operate = req.getParameter("operate");
    if(StringUtil.isEmpty(operate)){
        operate = "index";
    }
    
  3. 利用反射调用contollerBeanObj中的operate方法,并获取参数值,并处理视图

    Method[] declaredMethods = contollerBeanObj.getClass().getDeclaredMethods();
    for(Method method:declaredMethods){
        if(operate.equals(method.getName())){
            //1.统一获取请求参数
            //1.1获取当前方法的参数名称,返回参数数组
            Parameter[] parameters = method.getParameters();
            Object[] parameterValues = new Object[parameters.length];//保存参数的值
            for(int i = 0; i < parameters.length; i++){
                Parameter parameter = parameters[i];
                String parameterName = parameter.getName();
                if("req".equals(parameterName)){
                    parameterValues[i] = req;
                }else if("resp".equals(parameterName)){
                    parameterValues[i] = resp;
                }else if("session".equals(parameterName)){
                    parameterValues[i] = req.getSession();
                }else{
                    //从请求中获取参数值
                    String parameterValue = req.getParameter(parameterName);
                    String typeName = parameter.getType().getName();
    
                    Object parameterObj = parameterValue;
    				//设置参数值的类型
                    if(parameterObj != null && "java.lang.Integer".equals(typeName)){
                        parameterObj = Integer.parseInt(parameterValue);
                    }
                    parameterValues[i] = parameterObj;
                }
            }
            //2,controller组件中的方法调用
            method.setAccessible(true);
            Object returnObj = (String)method.invoke(contollerBeanObj, parameterValues);
            //3,视图处理
            String methodReturnStr = (String) returnObj;
            if(methodReturnStr.startsWith("redirect:")){ //比如:redirect:fruit.do
                String redirectStr = methodReturnStr.substring("redirect:".length());
                resp.sendRedirect(redirectStr);
            }else{//比如:edit index
                super.processTemplate(methodReturnStr,req,resp);
            }
        }
    }
    

5.2DispatcherServletException异常类型

抛出发报机异常

5.3ViewBaseServlet模板:用于设置渲染

5.3.1继承:HttpServlet
5.3.1设置web.xml配置文件:前缀和后缀
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 在上下文参数中配置视图前缀和视图后缀 -->
    <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>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>applicationContext</param-value>
    </context-param>
</web-app>
5.3.3重写init()方法,初始化模板引擎
@Override
public void init() throws ServletException {
    // 1.获取ServletContext对象
    ServletContext servletContext = this.getServletContext();
    // 2.创建Thymeleaf解析器对象
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
    // 3.给解析器对象设置参数
    // ①HTML是默认模式,明确设置是为了代码更容易理解
    templateResolver.setTemplateMode(TemplateMode.HTML);
    // ②设置前缀
    String viewPrefix = servletContext.getInitParameter("view-prefix");//获取xml文件中对应的字符串
    templateResolver.setPrefix(viewPrefix);
    // ③设置后缀
    String viewSuffix = servletContext.getInitParameter("view-suffix");
    templateResolver.setSuffix(viewSuffix);
    // ④设置缓存过期时间(毫秒)
    templateResolver.setCacheTTLMs(60000L);
    // ⑤设置是否缓存
    templateResolver.setCacheable(true);
    // ⑥设置服务器端编码方式
    templateResolver.setCharacterEncoding("utf-8");
    // 4.创建模板引擎对象
    templateEngine = new TemplateEngine();
    // 5.给模板引擎对象设置模板解析器
    templateEngine.setTemplateResolver(templateResolver);
}
5.3.4处理模板processTemplate()
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // 1.设置响应体内容类型和字符集
    resp.setContentType("text/html;charset=UTF-8");
    // 2.创建WebContext对象
    WebContext webContext = new WebContext(req, resp, getServletContext());
    // 3.处理模板数据
    templateEngine.process(templateName, webContext, resp.getWriter());
}

6.trans

6.1事务管理类TransactionManage

  1. 通过ConnUtil中的获取的Connection进行设置

  2. 分别设置开启事务、提交事务、回滚事务

    //开启事务
    public static void beginTrans() throws SQLException {
        ConnUtil.getConnection().setAutoCommit(false);
    }
    //提交事务
    public static void commit() throws SQLException {
        Connection conn = ConnUtil.getConnection();
        conn.commit();
        ConnUtil.closeConn();
    }
    //回滚事务
    public static void rollback() throws SQLException {
        Connection conn = ConnUtil.getConnection();
        conn.rollback();
        ConnUtil.closeConn();
    }
    

7.util工具包

7.1StringUtil判断字符串是否为空

三.WEB类

1.页面index.html

  1. 渲染页面

    <!-- 若列表为空,显示空页面 -->
    <tr th:if="${#lists.isEmpty(session.fruitList)}">
        <td colspan="4">对不起!库存为空</td>
    </tr>
    <!-- 若列表有数据,遍历数据显示 -->
    <tr th:unless="${#lists.isEmpty(session.fruitList)}" th:each="fruit : ${session.fruitList}">
        <td><a  th:text="${fruit.fname}" th:href="@{/fruit.do(fid=${fruit.fid},operate='edit')}">苹果</a></td>
        <td th:text="${fruit.price}">5</td>
        <td th:text="${fruit.fcount}">20</td>
        <!-- <td ><img src="imgs/del.jpg" class="delImg" th:οnclick="'delFruit(' + ${fruit.fid} + ')'"/></td> 拼接字符串方法-->
        <td ><img src="imgs/del.jpg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"/></td>
    </tr>
    
  2. 查询表单

    <form th:action="@{fruit.do}" method="post" style="float:left">
        <input type="hidden" name="oper" value="search"/>
        请输入查询关键字:<input type="text" name="keyword" th:value="${session.keyword}"/>
        <input type="submit" value="查询" class="btn">
    </form>
    
  3. 编辑表单

    <td><a  th:text="${fruit.fname}" th:href="@{/fruit.do(fid=${fruit.fid},operate='edit')}">苹果</a></td>
    
  4. 添加表单: 跳转到add.html页面

    <a th:href="@{/add.html}" style="margin-bottomt: 4px; float:right">添加新库存记录</a>
    
  5. 页面跳转

    <input type="button" value="首  页" class="btn" th:onclick="|page(1)|" th:disabled="${session.pageNo == 1}"/>
    <input type="button" value="上一页" class="btn" th:onclick="|page(${session.pageNo - 1})|" th:disabled="${session.pageNo == 1}"/>
    <input type="button" value="下一页" class="btn" th:onclick="|page(${session.pageNo + 1})|" th:disabled="${session.pageNo == session.pageCount}"/>
    <input type="button" value="尾  页" class="btn" th:onclick="|page(${session.pageCount})|" th:disabled="${session.pageNo == session.pageCount}"/>
    

2.页面eidt.html

  1. 渲染表单

  2. 提交表单

    <form th:action="@{/fruit.do}" method="post"  th:object="${fruit}">
        <input type="hidden" name="operate" value="update">
        <table id="tbl_fruit">
            <!--隐藏域,不显示但发送表单-->
            <input type="hidden" name="fid" th:value="*{fid}">
            <tr>
                <th class="w20">名称:</th>
                <td><input type="text" name="fname" th:value="*{fname}"></td>
            </tr>
            <tr>
                <th class="w20">单价:</th>
                <td><input type="text" name="price" th:value="*{price}"></td>
            </tr>
            <tr>
                <th class="w20">库存:</th>
                <td><input type="text" name="fcount" th:value="*{fcount}"></td>
            </tr>
            <tr>
                <th class="w20">备注:</th>
                <td><input type="text" name="remark"  th:value="*{remark}"></td>
            </tr>
            <tr>
                <th class="w20" colspan="2"><input type="submit" value="修改"></th>
            </tr>
        </table>
    </form>
    

3.页面add.html

  1. 提交表单

    <form action="fruit.do" method="post">
        <input type="hidden" name="operate" value="add">
        <table id="tbl_fruit">
            <tr>
                <th class="w20">名称:</th>
                <td><input type="text" name="fname"></td>
            </tr>
            <tr>
                <th class="w20">单价:</th>
                <td><input type="text" name="price"></td>
            </tr>
            <tr>
                <th class="w20">库存:</th>
                <td><input type="text" name="fcount"></td>
            </tr>
            <tr>
                <th class="w20">备注:</th>
                <td><input type="text" name="remark"></td>
            </tr>
            <tr>
                <th class="w20" colspan="2"><input type="submit" value="添加"></th>
            </tr>
        </table>
    </form>
    

4.web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 在上下文参数中配置视图前缀和视图后缀 -->
    <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>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>applicationContext</param-value>
    </context-param>
</web-app>

  

## 4.`web.xml`文件

```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
       version="3.1">
  <!-- 在上下文参数中配置视图前缀和视图后缀 -->
  <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>

  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>applicationContext</param-value>
  </context-param>
</web-app>
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值