手把手教您搭建一个移动后台服务(Servlet+MySQL+Hibernate),安卓移动端使用(RxJava+Retrofit)

今天是1024程序员节。还记得第一次传智播客搞程序员节的时候,拉我们去参加晚会,哈哈!当时我还在Java基础班,第二天就就业班校招了,所以没去凑热闹,记得看了一会儿直播,哈哈!

不知不觉,距离去北京培训已经两年多了,两年前的今天安排了从Java基础班到就业班的考试,犹记得10月25号第一次踏进中关村软件园的紧张,哈哈。JavaSE考的还是非会场细致的,印象最深的就是我在回答TreeSet自定义排序方式时候的自信(虽然就业之后用得也是非常少)。来一张10月25号Java考试结束之后拍摄的一张照片。满满的回忆。西二旗的味道,哈哈。

下面来进入正题,对于每个安卓前端程序员来说,最大的期望就是一边敲着安卓,一边调试后台,满满的成就感啊。如果你是想搭建一个属于自己的服务,那么可以负责的告诉你,你来对了地方。如果你是想怼公司的Java后台,那么对不起,本篇文章不适合你,因为后台技术用的也是比较陈旧的技术了,但是终归是入门么,哈哈!

目前主流的Java框架(请教了一个Java大神):


来看下实现效果:

首先呢,介绍一下安卓前端的搭建:

当然不用说了,我只想大喊:“Rx大法好!”,响应式开发改变了开发结构,简化了数据请求以及处理方式,实在是难得的好东西,很多公司都已经将其作为公司的主流框架师使用了。

我这边的Rx+Retrofit环境是参照RxJava 与 Retrofit 结合网络请求,你值得拥有搭建的,文章浅显易懂,行之有效,哈哈!作为安卓程序员,我不太想去解释这一块的东西(因为文章里面已经写得很细致了),没用试过的同学面壁思过去吧。。。

下面来进入重点:

后台Servlet+MySQL+Hibernate的搭建,至于这两个名词解释,度娘已经可以解释得十分清楚了,我只解释下他们在我们将要搭建的后台里面起的作用

Servlet:处理逻辑,主要是业务层逻辑 ,比如判断用户是否存在等,数据源头在哪?当然是数据库啦,怎么得到数据的呢,那就得介绍到Hibernate呢,接着往下看

Hibernate:MySQL数据库DAO层的封装,为啥不直接用JDBC+SQL呢?因为“懒”,哈哈。但是这个“懒”是有前提的,就是需要学习Hibernate相关知识,可谓是事半功倍。

下面来介绍下数据库:MySQL,作为“手把手系列”教程,当然要写的细一点啦,MySQL的安装教程:一路下一步,哈哈,只是要注意两个点:

1.语言编码选择最底下的自定义选择,然后找到utf-8,要不然之后你会很崩溃的,哈哈!



2.一定要允许远程访问,这样可以将数据库和服务安装在不同计算机上,然后通过IP+端口号+数据库进行远程访问



接着是Hibernate环境的搭建了,Hibernate作为数据库DAO的封装,主要是完成数据库的增删改查功能:

首先拷贝jar包:


用的是Hibernate3的Final版本,这些最后我都会统一放一起的,有需要的同学私信我要。

下面就是包的引入等操作,接下来就是重中之重了,数据库的创建,这里使用的是SQLyog(这里我是用的是工具,如果老铁们愿意敲sql语句来创建也可以,是在下输了,哈哈):


首先链接到本地数据库,之后再创建数据库:



创建表:



具体的大家根据业务需求去创建吧。

接下来就是Hibernate的本地配置了:


User.hbm.xml是数据库表的映射文件,hibernaye.cfg.xml为Hibernate的配置文件,我给全文粘贴下来:

User.hbm.xml(数据库表和本地JavaBean的映射关系):

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.marsjiang.test.User" table="users">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="username" column="username"></property>
		<property name="userpass" column="userpass"></property>
	</class>
</hibernate-mapping>
hibernaye.cfg.xml(数据库jdbc的相关配置):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.connection.url">jdbc:mysql://192.168.10.19:3306/myretrofittest</property>
		
		<property name="show_sql">true</property>
		<property name="format_sql">true</property>
		<property name="hbm2ddl.auto">update</property>
		<property name="hibernate.connection.autocommit">true</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		
		<mapping resource="com/marsjiang/test/User.hbm.xml" />
		
		
	</session-factory>
</hibernate-configuration>

配置完了之后我们来写Servlet的代码:

首先新建Servlet



这里新建了Servlet之后根据需要,如果是调用POST接口,则在doPost方法里面做相应的逻辑操作,同理,GET接口,则在doGet方法里面写逻辑。

在web.xml文件里面修改一下:

  <servlet-name>UserLoginServlet</servlet-name>
    <url-pattern>/servlet/UserLoginServlet</url-pattern>
  </servlet-mapping>

这样访问的时候完整url为:

http://192.168.10.19:8080/MyLoginTest/servlet/UserLoginServlet

下面问题来了,我们怎样获取到从移动端传来的数据呢?

String name = request.getParameter("username");
String password = request.getParameter("password");


由于我们这里做的是登录验证的操作,所以这里需要进行数据库的查询验证(具体方法如下:):

Configuration configuration = new Configuration().configure();
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		Session session = sessionFactory.openSession();

		String hql = "from UserInfo where username = ? and userpass= ?";
		Query query = session.createQuery(hql);
		query.setString(0, name);
		query.setString(1, password);
		List<UserInfo> list = query.list();
之后我们就可以根据这个list集合进行判断了,如果获取到了,则可以进行数据返回操作,如果没有获取到,则返回错误,数据返回的主要思路是将返回的javabean首先和移动端约定好,之后转换成json字符串返回。

具体的已经封装成了一个工具类,大家自行参阅吧:

package com.marsjiang.util;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsDateJsonBeanProcessor;
import org.apache.commons.lang.StringUtils;



public class CommonUtil {
	//header 常量定义//
	private static final String ENCODING_PREFIX = "encoding";
	private static final String NOCACHE_PREFIX = "no-cache";
	private static final String ENCODING_DEFAULT = "UTF-8"; //
	private static final boolean NOCACHE_DEFAULT = true;

	//content-type 定义 //
	private static final String TEXT = "text/plain";
	private static final String JSON = "application/json";
	private static final String XML = "text/xml";
	private static final String HTML = "text/html";


	// 绕过jsp/freemaker直接输出文本的函数//

	/**
	 * 直接输出内容的简便函数

	 * eg.
	 * render("text/plain", "hello", "encoding:GBK");
	 * render("text/plain", "hello", "no-cache:false");
	 * render("text/plain", "hello", "encoding:GBK", "no-cache:false");
	 * 
	 * @param headers 可变的header数组,目前接受的值为"encoding:":no-cache:",默认值分别为UTF-8和true.
	 */
	public static void render(final HttpServletResponse response,final String contentType, final String content, final String... headers) {
		try {
			//分析headers参数
			String encoding = ENCODING_DEFAULT;
			boolean noCache = NOCACHE_DEFAULT;
			for (String header : headers) {
				String headerName = StringUtils.substringBefore(header, ":");
				String headerValue = StringUtils.substringAfter(header, ":");

				if (StringUtils.equalsIgnoreCase(headerName, ENCODING_PREFIX)) {
					encoding = headerValue;
				} else if (StringUtils.equalsIgnoreCase(headerName, NOCACHE_PREFIX)) {
					noCache = Boolean.parseBoolean(headerValue);
				} else
					throw new IllegalArgumentException(headerName + "不是合法的header类型");
			}

			//设置headers参数
			String fullContentType = contentType + ";charset=" + encoding;
			response.setContentType(fullContentType);
			if (noCache) {
				response.setHeader("Pragma", "No-cache");
				response.setHeader("Cache-Control", "no-cache");
				response.setDateHeader("Expires", 0);
			}

			PrintWriter writer = response.getWriter();
			writer.write(content);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 直接输出文本.
	 * @see #render(String, String, String...)
	 */
	public static void renderText(final HttpServletResponse response,final String text, final String... headers) {
		render(response,TEXT, text, headers);
	}

	/**
	 * 直接输出HTML.
	 * @see #render(String, String, String...)
	 */
	public static void renderHtml(final HttpServletResponse response,final String html, final String... headers) {
		render(response,HTML, html, headers);
	}

	/**
	 * 直接输出XML.
	 * @see #render(String, String, String...)
	 */
	public static void renderXml(final HttpServletResponse response,final String xml, final String... headers) {
		render(response,XML, xml, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param string json字符串
	 * @see #render(String, String, String...)
	 */
	public static void renderJson(final HttpServletResponse response,final String jsonString, final String... headers) {
		render(response,JSON, jsonString, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param map Map对象,将被转化为json字符串
	 * @see #render(String, String, String...)
	 */
	@SuppressWarnings("unchecked")
	public static void renderJson(final HttpServletResponse response,final Map map, final String... headers) {
		String jsonString = JSONObject.fromObject(map).toString();
		render(response,JSON, jsonString, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param object Java对象,将被转化为json字符串
	 * @see #render(String, String, String...)
	 */
	public static void renderJson(final HttpServletResponse response,final Object object, final String... headers) {
		String jsonString = JSONObject.fromObject(object).toString();
		render(response,JSON, jsonString, headers);
	}
	
	/**
	 * 直接输出JSON.
	 * @param response
	 * @param list
	 * @param headers
	 */
	public static void renderJson(final HttpServletResponse response,final List<?> list, final String... headers) {
		String jsonString = JSONArray.fromObject(list).toString();
		render(response,JSON, jsonString, headers);
	}
	
	/**
	 * 直接输出JSON.含有java.sql.date数据类型
	 * @param response
	 * @param object
	 * @param headers
	 */
	public static void renderJsonForSqlDate(final HttpServletResponse response,final Object object, final String... headers) {
		JsDateJsonBeanProcessor beanProcessor = new JsDateJsonBeanProcessor();
 		JsonConfig config = new JsonConfig();
 		config.registerJsonBeanProcessor(java.sql.Date.class, beanProcessor);
 		JSONObject json = JSONObject.fromObject(object, config);
		render(response,JSON, json.toString(), headers);
	}
	
	
	public static void main(String args[]){
		
	}
	
	/**
	 * 直接输出内容与转换
	 * @param rep
	 * @param message
	 * @param URL
	 * @param headers
	 */
	public static void renderScript(final HttpServletResponse rep,final String message,final String... headers){
			PrintWriter printer = null;
			try {
				rep.setContentType("text/html;charset=UTF-8");
				printer = rep.getWriter();
				printer.write("<script language = 'javascript'>");
				printer.write("alert('"+message+"'),");
				printer.write("window.history.go(-1)");
				printer.write("</script>");
			} catch (IOException e) {
				System.err.println(e.getLocalizedMessage());
			} finally {
				if (printer != null) {
					printer.close();
				}
			}
	}
	
	/**
	 * json To List<?>
	 * @param jsonStr
	 * @param objClass
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static List<?> toList(final String jsonStr,Class<?> objClass){
		  JSONArray jsArray = JSONArray.fromObject(jsonStr);
		  List<?> list = JSONArray.toList(jsArray, objClass);
		  return list;
	}
	
	/**
	 * json to object
	 * @param jsonStr
	 * @param objClass
	 * @return
	 */
	public static Object toObject(final String jsonStr,Class<?> objClass){
		JSONObject jsObject = JSONObject.fromObject(jsonStr);
		return JSONObject.toBean(jsObject, objClass);
	}
	
}

嗯,就这样了,需要源码的可以私信我。

青春不在,时光易逝,好好生活吧,希望是享受生活而不是被生活折磨!





  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值