Spring MVC + Spring MongoDB + Querydsl 通过maven整合实例

效果图

一共3个页面:注册页,欢迎页,用户列表页

很简单的例子,主要是为了把流程走通,没有各种验证。

注册页:

  

欢迎页:

  

用户列表页:

  

 

源码地址

https://github.com/lemonbar/spring-framework-mongodb

 

参考文档

Spring framework: http://docs.spring.io/spring/docs/4.0.6.RELEASE/spring-framework-reference/htmlsingle/#spring-web

Spring data mongodb: http://docs.spring.io/spring-data/data-mongo/docs/1.5.2.RELEASE/reference/html/

Querydsl: http://www.querydsl.com/static/querydsl/latest/reference/html/index.html

 

代码实现(使用maven构建)

Spring MVC

maven的依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

taglibs和jstl是为jsp中的标签服务的.

web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/root-context.xml</param-value>
    </context-param>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Set Character Encoding-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Set Character Encoding-->

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

注意:关于filter的定义顺序,CharacterEncodingFilter必须放在HiddenHttpMethodFilter之前,否则会有中文乱码的问题。(filter的执行是按照定义顺序执行的)。

CharacterEncodingFilter,是为了中文编码

HiddenHttpMethodFilter,因为html中的form表单只支持GET与POST请求,spring为了支持DELETE, PUT等操作,会在生成页面代码时,会把我们希望的操作添加到一个hidden的_method中,在外层通过post传过去,所以我们需要通过HiddenHttpMethodFilter把真实的操作解析出来。

我们定义的 vs. 真实传输的

<form:form action="xxx" method="put">
</form:form>
<form id="xxx" action="xxx" method="post">
    <input type="hidden" name="_method" value="put"/>
</form>

root-context.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/data/mongo
        http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">

    <context:component-scan base-package="com.lemon.spring"/>
    <!-- 添加注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 允许对静态资源文件的访问 -->
    <mvc:default-servlet-handler/>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

这儿只贴了前半部分和spring mvc相关的,后面的会在mongodb那部分贴出来。

login.jsp

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<html>
<head>
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
    <title></title>
</head>
<body>
<form:form commandName="user" action="signin">
    <table>
        <tr>
            <td>First Name:</td>
            <td><form:input path="firstName"/></td>
        </tr>
        <tr>
            <td>Last Name:</td>
            <td><form:input path="lastName"/></td>
        </tr>
        <tr>
            <td>
                <input type="submit" value="注册"/>
            </td>
            <td>
                <input type="button" value="用户列表" onclick="javascript:location.href='user_list'">
            </td>
        </tr>
    </table>
</form:form>
</body>
</html>

user_list.jsp

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

<html>
<head>
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
    <title>User List</title>
</head>
<body>
<form action="user_list">
    <table>
        <tr>
            <td>查询条件</td>
            <td>
                <input type="text" name="q"/>
            </td>
            <td>
                <input type="submit" value="查询"/>
            </td>
        </tr>
    </table>
</form>
<hr>
<table border="1">
    <tr>
        <td>index</td>
        <td><font>firstName</font></td>
        <td><font>lastName</font></td>
    </tr>
    <c:set var="index" value="1"/>
    <c:forEach var="u" items="${userList}">
        <tr>
            <td>${index}</td>
            <td>${u.firstName}</td>
            <td>${u.lastName}</td>
        </tr>
        <c:set var="index" value="${index+1}"/>
    </c:forEach>
</table>
<hr>
<input type="button" value="首页" onclick="javascript:location.href='login'">
</body>
</html>

greeting.jsp

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<html>
<head>
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
    <title></title>
</head>
<body>
<form:form action="login">
    <table>
        <tr>
            <td colspan="2">
                恭喜您, 用户${firstName}注册成功!
            </td>
        </tr>
        <tr>
            <td>
                <input type="submit" value="首页"/>
            </td>
            <td>
                <input type="button" value="用户列表" onclick="javascript:location.href='user_list'">
            </td>
        </tr>
    </table>
</form:form>
</body>
</html>

LoginController.java

package com.lemon.spring.controller;

import com.lemon.spring.domain.User;
import com.lemon.spring.service.IUserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.List;

@Controller
public class LoginController {

    @Resource
    private IUserService userService;

    @RequestMapping("/login")
    public String login(Model model) {
        User user = userService.initUser();
        model.addAttribute(user);
        return "login";
    }

    @RequestMapping("/signin")
    public String signin(User user,
                         Model model) {
//        userService.saveUser(user);
        userService.insertUser(user);
//        User savedUser = userService.getUserByFirstName(user.getFirstName());
        model.addAttribute("firstName", user.getFirstName());
        return "greeting";
    }

    @RequestMapping("/user_list")
    public String userList(Model model, @RequestParam(required = false, value = "q", defaultValue = "") String q) {
        List<User> userList;
        if (q == "") {
            userList = userService.getUserList();
        } else {
            userList = userService.getUserListByFirstName(q);
        }
        model.addAttribute("userList", userList);
        return "user_list";
    }
}

service和domain

IUserService.java

package com.lemon.spring.service;

import com.lemon.spring.domain.User;

import java.util.List;

public interface IUserService {
    User initUser();
    boolean saveUser(User user);
    List<User> getUserList();
    List<User> getUserListByFirstName(String firstName);
    User getUserByFirstName(String firstName);
    void insertUser(User user);
}

UserService.java

package com.lemon.spring.service.impl;

import com.lemon.spring.domain.QUser;
import com.lemon.spring.domain.User;
import com.lemon.spring.repository.IPersonRepository;
import com.lemon.spring.repository.UserRepository;
import com.lemon.spring.service.IUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserService implements IUserService {

    @Resource
    private UserRepository userRepository;

    @Resource
    private IPersonRepository personRepository;

    @Override
    public User initUser() {
        User user = new User();
        return user;
    }

    @Override
    public boolean saveUser(User user) {
        User u = userRepository.save(user);
        if (u != null) {
            return true;
        }
        return false;
    }

    @Override
    public List<User> getUserList() {
        return userRepository.findAll();
    }

    @Override
    public List<User> getUserListByFirstName(String firstName) {
        QUser user = QUser.user;
        return (List<User>)userRepository.findAll(user.firstName.contains(firstName));
    }

    @Override
    public User getUserByFirstName(String firstName) {
        return userRepository.findByFirstName(firstName).get(0);
    }

    @Override
    public void insertUser(User user) {
        personRepository.insert(user);
    }
}

User.java

@Data
@Entity
public class User {
//    @Id
//    private String id;
    private String firstName;
    private String lastName;
}

maven的pom.xml要引入两个dependency,lombok为自动生成get/set方法使用,hibernate-jpa-2.0-api是为了javax.presistence.Entity.

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.14.4</version>
        </dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

Spring MongoDB

root-context.xml

    <mongo:mongo host="localhost" port="27017">
        <mongo:options/>
    </mongo:mongo>
    <mongo:db-factory dbname="springdb" mongo-ref="mongo"/>

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    </bean>

    <mongo:repositories base-package="com.lemon.spring.repository"/>

其中关于mongodb的定义,按名称应该可以猜的出来,也可以参考官方文档。

maven依赖

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>1.5.2.RELEASE</version>
        </dependency>

UserRepository.java

package com.lemon.spring.repository;

import com.lemon.spring.domain.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import java.util.List;

public interface UserRepository extends MongoRepository<User, String>{
    List<User> findByFirstName(String firstName);
}

UserRepository直接继承MongoRepository,默认已经提供了很多方法,比如save,不需要自己写实现。

如果需要更多的查询,可以按照方法的命名机制来进行定义。

 

当然除了直接继承自MongoRepository外,还可以直接使用context中定义的mongotemplate,来自己定义接口和实现,参考下面两个java文件

IPersonRepository.java

package com.lemon.spring.repository;

import com.lemon.spring.domain.User;

public interface IPersonRepository {
    void insert(User user);
}

PersonRepository.java

package com.lemon.spring.repository.impl;

import com.lemon.spring.domain.User;
import com.lemon.spring.repository.IPersonRepository;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository
public class PersonRepository implements IPersonRepository {

    @Resource
    private MongoOperations mongoTemplate;

    @Override
    public void insert(User user) {
        mongoTemplate.insert(user);
    }
}

Querydsl

Querydsl为我们提供了更多功能的查询,详细介绍请参考官网http://www.querydsl.com/static/querydsl/latest/reference/html/index.html

首先maven中添加依赖

<dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-mongodb</artifactId>
            <version>${querydsl.version}</version>
        </dependency>

        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>

然后修改UserRepository

public interface UserRepository extends MongoRepository<User, String>, QueryDslPredicateExecutor<User> {
    List<User> findByFirstName(String firstName);
}

maven中添加plugin

 <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.0.9</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

根据@Entity来生成类。

posted @ 2014-08-20 15:21  lemon_bar  阅读(4037)  评论(0编辑  收藏  举报