Maven Missing artifact解决之道

前几天没事用maven重构自己的微信公众平台开发的代码,当下载一个Jar包时,遇到一个问题:Missing artifact net.sf.json-lib:json-lib:jar:2.2.3,去仓库看,这个Jar包确实没下载下来,因为自己的maven是半路里出家的(自己完全在网上找的一些乱七八糟的资源自学的),所以不知道咋回事,于是就去网上找解决的办法,也许是没找对地方,死活就是解决不了(为避免误导大家,就不列举这些方法了),问同事怎么办,一同事说应该是你下载的时候的网断了之类的导致资源下载了一半,然后网再连上,就不接着下载了,感觉似乎挺有道理,删了还是不行,那是不是网站被和谐了,采用VPN结果还是不行,最后仔细观察,终于发现了一下端倪: 也就是说 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.3</version> </dependency> 对应多个Jar,maven不知道下载那个Jar,所以就报错了,正确的解决方法是加一个标签:,即变成: <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.3</version> <classifier>jdk13</classifier> </dependency> 就没问题了。

September 3, 2014 · 1 min · 17 words · Bridge Li

反射机制入门

Java程序允许在执行期间获取一个已知名称的类的详细内部构造,这种机制被称为“反射”,反射在struts2、Spring、hibernate等Java常见框架中有着许多经典运用,下面是Java反射机制的入门代码,看了这些代码,相信读者应该对Java的反射机制会有一个入门级的了解,再看那些框架源码时会省力不少。 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.TypeVariable; public class TestReflection { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { String str = "T"; Class c = Class.forName(str); Object o = c.newInstance(); T t = (T) c.newInstance(); t.m(); Method[] methods = c.getMethods(); for (Method method : methods) { if ("m".equals(method.getName())) { method.invoke(o); } if ("getS".equals(method.getName())) { TypeVariable<Method>[] typeParameters = method.getTypeParameters(); Class returnType = method.getReturnType(); } } } } class T { int i; String s; static { System.out.println("T loaded&#8230;"); } public T() { System.out.println("T Constructed&#8230;"); } public String getS() { return s; } public void setI(int i) { this.i = i; } public void m() { System.out.println("m invoked&#8230;"); } }

August 31, 2014 · 1 min · 113 words · Bridge Li

JSP自定义标签

虽然html很好,尤其是html5越来越火,但仍有很多网站是用JSP做的,JSP里面虽然有很多标签,但我们是否可以自己定义自己的呢?当然可以,参考代码如下: 写自己的taglib类,并重写里面的方法 public class DropDownBoxTaglib extends TagSupport { private static final long serialVersionUID = 1L; @Override public int doStartTag() throws JspTagException { return SKIP_BODY; } @Override public int doEndTag() throws JspTagException { HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); RequestTypeService requestTypeService = (RequestTypeService) applicationContext.getBean("requestTypeService"); List<RequestType> requestTypes = requestTypeService.query(); request.setAttribute("REQUESTTYPES", requestTypes); try { pageContext.include("/component/request_type_select.jsp"); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE; } @Override public void release() { super.release(); } } 对应的tld文件 <?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <jsp-version>1.1</jsp-version> <short-name>aug</short-name> <tag> <name>select</name> <tag-class>cn.bridgeli.DropDownBoxTaglib</tag-class> <body-content>empty</body-content> <!&#8211; <attribute> <name>formatKey</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> &#8211;> </tag> </taglib> 具体哪个文件使用该taglib <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% List<RequestType>requestTypes = (List <RequestType>)request.getAttribute("REQUESTTYPES"); %> <select name="requestTypeId" id="requestTypeId" style="width: 608px;"> <option>&#8211;Select a request type Please&#8211;</option> <% for(int i = 0; i< requestTypes.size(); i++) { RequestType requestType = requestTypes.get(i); %> <option value= <%= requestType.getId() %>><%= requestType.getName() %> </option> <% } %> </select>

August 30, 2014 · 1 min · 160 words · Bridge Li

软件分层的一般方法

1. 软件设计的目的:高内聚、低耦合,为了达到这一目的:(1). 模块化; (2). 分层 软件分层依据:(1). 逻辑分层;(2). 物理分层 命名空间:(1). 类:属性和方法;(2). 包:其实就是一个文件夹 包名命名规范:域名倒写+项目名+逻辑或模块,例如:cn.bridgeli.weixin.service DB Web的死四层结构:view、servlet、service、dao servlet向service传递DTO或者VO,service向DAO传递model,dao直接保存数据到数据库 类的命名规范:实体名+包的最后一层,但model除外 例如:UserService、User 2. 哪些代码写到哪一层 (1). 一个表对应一个model类 (2). 一个表对应一个dao(四个方法) Create、update、getById、delete(可能没有,markfordelete,但依然会这么命名),其他方法一般都以:create、update、delete、get(返回一个对象)、save、find或者query(返回一个list,统一用一个就行)等关键字打头 (3). Service由界面操作的都有service,但log没有service层 (4)servlet接受用户请求 在开发中,不能跨层调用,不能调上层,只能调下层或者本层的方法 (5). Util工具包,所有方法全部是static的,只放一些常用工具,例如StringUtil,检验字符串是否为空、一个字符串是否包含另一个字符串;jdbc中的DBUtil,getConn、getPstmt、getRs以及close等方法

August 30, 2014 · 1 min · 30 words · Bridge Li

日志的配置

在系统开发中,尤其是上线后,没有日志那绝对是一件不可想象的事,但日志的配置却很简单,一般配置后只要做少量的修改,几乎可以永远到处都可以用了,下面给出日志配置的一般方法。 注:该配置的Jar包为:log4j、slf4j-api、slf-log4j,即使用slf日志接口,log4j的实现(当然你也可以使用其他的实现,例如hibernate自带的slf的实现)这一目前为止的最佳实践。 log4j.rootCategory=INFO, stdout, logfile, errorLog log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L &#8211; %m%n #log4j.category.org.springframework.beans.factory=info log4j.appender.consoleAppender.layout.ConversionPattern =ProcessDefinitionId=%X{mdcProcessDefinitionID} executionId=%X{mdcExecutionId} mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %m%n" log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender log4j.appender.logfile.file=C:/invoice/log/log.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.DatePattern=&#8217;.&#8217;yyyy-MM-dd #log4j.appender.logfile.layout.ConversionPattern=[%d %6p at %C.%M(%F:%L)] %m%n log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n log4j.appender.logfile.Threshold=INFO log4j.appender.errorLog=org.apache.log4j.DailyRollingFileAppender log4j.appender.errorLog.file=C:/invoice/log/error.log log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout log4j.appender.errorLog.DatePattern=&#8217;.&#8217;yyyy-MM-dd log4j.appender.errorLog.layout.ConversionPattern=[%d %6p at %C.%M(%F:%L)] %m%n log4j.appender.errorLog.Threshold=ERROR # SQL: #log4j.logger.com.ibatis=DEBUG #log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG #log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG #log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG #log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG #log4j.logger.com.ibatis.common.util.StopWatch=DEBUG #log4j.logger.java.sql.Connection=DEBUG #log4j.logger.java.sql.Statement=DEBUG #log4j.logger.java.sql.PreparedStatement=DEBUG #log4j.logger.java.sql.ResultSet=DEBUG 注:这是一最简单的一种配置,还有很多其他的配置项可以灵活配置,例如打印hibernate的SQL语句,而且还可以配置当产生error级别的日志时,自动发送邮件到指定邮箱,具体请参考:http://futeng.iteye.com/blog/2109231

August 29, 2014 · 1 min · 58 words · Bridge Li

简单邮件的解析

昨天讲了邮件的发送(这是一个个人笔记,如果有人要参考的话,估计需要做大量的修改才行,但整体逻辑是不会错),既然有发送,肯定会有邮件的解析,那么今天大桥就再写一个例子程序,关于邮件怎么解析。 @Service("parseMailService") public class ParseMailServiceImpl { private static final Logger LOG = LoggerFactory.getLogger(ParseMailServiceImpl.class); private static final String[] flagOfMailEnds = {"<DIV><BR></DIV>", "From:<", "From: <", "Sent: ", "Kind regards,", "Kind Regards,", "Best regards,", "Best Regards,", "Kind regards,", "Regards,", "Thanks", "&#8212;&#8211; Original Message &#8212;&#8211;", "> &#8212;&#8212;&#8212;&#8212;-", "&#8212;&#8212;&#8212;&#8212;&#8212;"}; private static final String[] flagOfMailStarts = {"Hi,", "</HEAD>"}; private static final String[] regExHtmls = {"<[^>]+>", "<[^>]+"}; @Autowired private MailServerService mailServerService; public void parseMail() throws Exception { LOG.info("==Start parse Mail=="); Session session = mailServerService.getSession(); Store store = session.getStore(“pop3”); store.connect(MAIL_SERVER_HOST, MAIL_ADDRESS, MAIL_SERVER_PASSWORD); Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_WRITE); Message[] messages = folder.getMessages(); int mailNo = Integer.parseInt((String) execution.getVariable(SystemConstant.MAIL_NO)); Message message = messages[mailNo]; Map<String, String> contents = parseMessage(message); message.setFlag(Flags.Flag.DELETED, true); // message.saveChanges(); mailServerService.closeConn(folder, store); LOG.info("==Mail parse success, this mail from: " + contents.get("user") + "=="); } private String splitContentBySpecialCharacter(String context) { // Remove mail bottom for (String flagOfMailEnd : flagOfMailEnds) { int endIndex = context.indexOf(flagOfMailEnd); if (endIndex > -1) { context = context.substring(0, endIndex); } } // Remove mail top for (String flagOfMailStart : flagOfMailStarts) { int startIndex = context.indexOf(flagOfMailStart); if (startIndex > -1) { context = context.substring(startIndex + flagOfMailStart.length()); } } // Filter the HTML tags for (String regExHtml : regExHtmls) { Pattern p_html = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE); Matcher m_html = p_html.matcher(context); context = m_html.replaceAll(""); } context.replaceAll(" ", ""); // Filter "rn" Pattern CRLF1 = Pattern.compile("(rn|r|n|nr){3,}"); Matcher m1 = CRLF1.matcher(context); context = m1.replaceAll(""); Pattern CRLF = Pattern.compile("(rn|r|n|nr)"); Matcher m = CRLF.matcher(context); context = m.replaceAll(" "); return context; } public Map<String, String> parseMessage(Message message) throws MessagingException, IOException { Map<String, String> contents = new HashMap<String, String>(); StringBuffer content = new StringBuffer(300); content = getMailTextContent(message, content); contents.put("comment", splitContentBySpecialCharacter(content.toString())); return contents; } public StringBuffer getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException { boolean isContainTextAttach = part.getContentType().indexOf("name") > 0; if (part.isMimeType("text/*") && !isContainTextAttach) { if (content.length() > 0) { content.setLength(0); } content.append(part.getContent().toString()); } else if (part.isMimeType("message/rfc822")) { getMailTextContent((Part) part.getContent(), content); } else if (part.isMimeType("multipart/*")) { Multipart multipart = (Multipart) part.getContent(); int partCount = multipart.getCount(); for (int i = 0; i < partCount; i++) { BodyPart bodyPart = multipart.getBodyPart(i); getMailTextContent(bodyPart, content); } } return content; } } @Service("mailServerService") public class MailServerServiceImpl implements MailServerService { private static final Logger LOG = LoggerFactory.getLogger(MailServerServiceImpl.class); @Override public Session getSession() { Properties props = System.getProperties(); props.put("mail.smtp.port", 25); Session session = Session.getDefaultInstance(props); return session; } @Override public void closeConn(Folder folder, Store store) { try { if (null != folder) { folder.close(true); } if (null != store) { store.close(); } } catch (MessagingException e) { LOG.error("Close connection fail with mail server", e); } } }

August 29, 2014 · 2 min · 411 words · Bridge Li

如何利用模板发送邮件

目前web应用很多时候都需要像用户发送邮件,尤其是在我们注册的时候,其实这些邮件很多时候内容都是类似的,仅仅是一些有户名等不同,那么我们是否可以利用一个模板呢,模板里面有一些占位符,当我们要发送邮件的时候,仅仅把这些占位符做一替换就行了呢?答案肯定是可以的,请看下面的例子程序: 1. 邮件模板mailTemplate.xml <?xml version="1.0" encoding="UTF-8"?> <email> <ProjectMail> <subject id="ProjectSubject"> <![CDATA[Hello%toUsername%]]></subject> <content id="ProjectMailBody"> <![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <META http-equiv=Content-Type content="text/html; charset=UTF-8"> <META content="MSHTML 6.00.6000.17063" name=GENERATOR> <STYLE> TABLE { MARGIN-LEFT: 20px; } TD { border: 1px solid #CBCBCB; } .dataString { text-align:left; padding-left:3px; } .tableTittle{ background-color: #FF9900; } </STYLE> </HEAD> <BODY bgColor=#ffffff> <DIV> <FONT face=Arial size=2></FONT> </DIV> <DIV> <FONT face=Arial size=2> Hi %name%, </FONT> </DIV> <br> <DIV> <FONT face=Arial size=2> 欢迎注册 </FONT> </DIV> <br> <DIV> <FONT face=Arial size=2> 该邮件是系统自动发出,请不要直接回复,谢谢 </FONT> </DIV> <br> <table width="800" border="1" cellspacing="0" cellpadding="0"> <tr class="tableTittle"> <th width="25%"> <font size="2" face="Arial" class="dataString" > <p align="center"> Name </p> </font> </th> <th width="25%"> <font size="2" face="Arial" class="dataString" > <p align="center"> Date and time </p> </font> </th> </tr> <#listItems></#listItems> </table> <br> <DIV> <FONT face=Arial size=2></FONT> </DIV> <DIV> <FONT face=Arial size=2> Kind regards, </FONT> </DIV> <DIV> <FONT face=Arial size=2> Bridge </FONT> </DIV> ]]> </content> </ProjectMail> </email> Java代码: @Service("mailService") public class MailServiceImpl implements MailService { private static final Logger LOG = LoggerFactory.getLogger(MailServiceImpl.class); private static final String DO_INVOICE_ITMES ="<#listItems></#listItems>"; private static final String NAME = "%name%"; @Override public void sendMail() { List<String> mailCCList = new ArrayList<String>(); String attachmentPath = null; Map<String, String> mail = buildMail(receiverName); String emailContent = mail.get("mailContent"); String subject = mail.get("emailSubject"); toSendMail(receiverMailAddress, mailCCList, emailContent, subject, attachmentPath, attachmentName); } private void toSendMail(String toAddress, List<String> mailCCList, String emailContent, String subject, String attachmentPath, String attachmentName) { Properties props = new Properties(); // Set the attribute of mail server props.put("mail.smtp.host", MAIL_SERVER_HOST)); // Need to be authorized, such ability through validation (must have this one) props.put("mail.smtp.auth", "true"); // Build a session with props objects Session session = Session.getDefaultInstance(props); // Using the session as parameters define the message object MimeMessage message = new MimeMessage(session); Transport transport = null; try { // Load the sender&#8217;s address message.setFrom(new InternetAddress(MAIL_ADDRESS); // Load the recipient address message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress)); if (StringUtil.isNotEmpty(mailCCList)) { InternetAddress[] to_mail = new InternetAddress[mailCCList.size()]; for (int i = 0; i < mailCCList.size(); i++) { to_mail[i] = new InternetAddress(mailCCList.get(i)); } message.addRecipients(Message.RecipientType.CC, to_mail); } // Load the subject message.setSubject(subject); // Add mail each part to the multipart, including the text content // and accessories MimeMultipart multipart = new MimeMultipart(); // Set the HTML content of the message BodyPart contentPart = new MimeBodyPart(); // To set the content and format/encoding of BodyPart contentPart.setContent(emailContent, "text/html;charset=UTF-8"); multipart.setSubType("related"); multipart.addBodyPart(contentPart); // Add attachment if (!StringUtil.isNullOrEmpty(attachmentName)) { contentPart = new MimeBodyPart(); DataSource source = new FileDataSource(attachmentPath); // Add attachment&#8217;s content contentPart.setDataHandler(new DataHandler(source)); // Add attachment&#8217;s title contentPart.setFileName(attachmentName); multipart.addBodyPart(contentPart); } // Add multipart object to the message message.setContent(multipart); // Save the mail message.saveChanges(); transport = session.getTransport("smtp"); // Connect the mail server transport.connect(MAIL_SERVER_HOST, MAIL_SERVER_USERNAME, MAIL_SERVER_PASSWORD); // Send mail transport.sendMessage(message, message.getAllRecipients()); LOG.info("Send mail to: " + toAddress + ",success"); } catch (AddressException e) { LOG.error(e); } catch (NoSuchProviderException e) { LOG.error(e); } catch (MessagingException e) { LOG.error(e); } finally { try { if (null != transport) { transport.close(); } } catch (MessagingException e) { LOG.error(e); } } } private Map<String, String> buildMail(String receiverName) { StringBuilder itemsBuilder = new StringBuilder(); Element emailTemplateRoot = getXMLRootElement("mailTemplate.xml"); String emailSubject = emailTemplateRoot.selectSingleNode("//*[@id=&#8217;ProjectSubject&#8217;]").getText().replace(TOUSERNAME, receiverName.toUpperCase()); StringBuilder content = new StringBuilder(); String mailTemplateContent = emailTemplateRoot.selectSingleNode("//*[@id=&#8217;ProjectMailBody&#8217;]").getText(); mailTemplateContent = mailTemplateContent.replace(NAME, receiverName).replace(DO_INVOICE_ITMES, itemsBuilder.toString()); content.append(mailTemplateContent); Map<String, String> mail = new HashMap<String, String>(); mail.put("emailSubject", emailSubject); mail.put("mailContent", content.toString()); return mail; } private String getColumnDataString(String data) { String columnData = null; columnData = "<td class=&#8217;dataString&#8217;><font size=&#8217;2&#8242; face=&#8217;Arial&#8217;><p align=&#8217;center&#8217;>" + data + "</p></font></td>" + "n"; return columnData; } private Element getXMLRootElement(String emailFile) { SAXReader reader = new SAXReader(); InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(emailFile); Document document = null; try { document = reader.read(inputStream); } catch (DocumentException e) { LOG.error("Get XML Root Element fail, DocumentException", e); } return document.getRootElement(); } } 2015.05.25补记: ...

August 28, 2014 · 5 min · 945 words · Bridge Li

异常处理的一般方法

学习Java的应该都知道,异常处理是其一大特色,使用异常处理的最大优势就是:将问题处理代码和正常执行流程做了区分,使得程序的执行逻辑更加清晰,不再使错误处理代码和正常业务逻辑代码混在一起。Java不仅自己定义了各种各样的异常类来描述一些基本的错误现象,而且还提供了扩展机制,允许程序猿自定义异常类,应用于实际问题处理,Java的异常处理机制可以捕获对应的异常,并进行主动处理,那么既然Java的异常处理机制这么好用,有没有一般性的方法呢? 首先说明,(1). Java的异常分为:Error和Exception,Error类及其子类表示不是不可能恢复但很难处理的情况下的一种严重问题,例如内存溢出(大家可以想想Java是否存在内存溢出现象?),我们不可能指望程序能处理,所以本文所有的方法都是针对Exception。 (2). 异常处理就五个关键字:try、catch、finally、throw、throws,他们的用法也比较简单,本文不再赘述。 好了,下面开讲: 1. Exception分为两类:Exception和RuntimeException,其中Exception必须在系统中处理,而RuntimeException继承与Exception,表示一种设计或实现的问题,如果系统正常运行,此类异常不会出现,例如最常见的NullPointerException,所以一般不强制要求处理。 2. 像ClassNotFoundException这类异常,一般是jar包没有添加,在系统正常运行中肯定不会出现,所以无需抛出,可以直接try catch掉,但别忘了打log。 3. 像SQLException之类的,这类异常偶然也会出现,如:数据库服务没打开、没有网络、SQL语法有误等,但这类异常即使抛到Service层依然无法处理,抛到客户端客户也看不懂,还影响用户体验,所以也不要抛出,一般都是转化为RuntimeException,在转化之前打log。 4. 所以需要我们处理的异常只有ValidationException和BusinessException,这两类异常都是我们自定义的异常,其中ValidationException处理的是验证异常,而BusinessException处理的是业务逻辑异常,这两类异常都需要我们在系统中做出处理,下面会给出ValidationException、BusinessException和自定义转化为RuntimeException的参考方法。 5. Service层是负责业务逻辑处理的一层,所以所有的验证都要放在Service层,而Service层在进行验证和业务逻辑处理的时候,应该抛出这些所遇到的异常,并加入到ValidationException(如用户登录时用户名或密码为空等)或者BusinessException(如用户名或密码不正确等)异常中,然后在上层(servlet或者Action或者、controller)中进行捕获,捕获到之后放到Request中,带到前台进行处理。 6. 千万要记得出现异常一定要打log!!!尤其是当你try catch掉一个异常时。其中ValidationException、BusinessException日志级别为warning或info,其他的据具体情况而定,但MyRuntimeException 可以不打,大家可以想想为什么?(前面有答案) 7. 顺便说一下,关闭资源一定要放在finally里,因为finally的代码无论是否有异常都会被执行,确保打开的资源一定都会被关闭。 在这里顺便回答一些同学的问题: (1)、我在前台已经做了验证,那么是否还需要在后台再做验证? 答:肯定要,原因①、前台验证一般都是用js来做,而js的解析是在客户端,如果有人禁用了浏览器的js,是不是你的验证就不起作用了。(关于如何禁用js,请自己用Google百度一下); ②、不排除有些黑客要黑你,所以他们可以通过一些工具,直接绕过前台,那么你懂得。 (2)、为什么要抽象Service层,为什么不把Service层的功能全放到servlet中来做,简单来说为什么要把验证放到Service层? 答:首先为什么抽象Service层,肯定是为了复用,这个是关于分成模型中要讲的,有机会我会在写一篇博文,专讲分层的一般方法,这里不多说,大家可以试想一下,目前移动端越来越火,而我们的servlet是和web相关,那么我们的Servlet能被App复用吗?如果我们把验证放到servlet中,那么如果在开发一套App,我们是不是所有的验证都要重写一篇?而放在Service层则没有这个问题。 (3)、Java是否存在内存溢出问题? 答:一般是不存在的,因为jvm有GC机制,会很好的管理内存,但有时候当我们短时间内,打开很多资源而没有关闭的时候,是可能会存在内存溢出问题的。 package cn.bridgeli.exceptionhandle.exception; public class BusinessException extends Exception { private static final long serialVersionUID = 1L; private int code; public BusinessException(int code, String message) { super(message); this.code = code; } public int getCode() { return code; } } package cn.bridgeli.exceptionhandle.exception; public class MyRuntimeException extends RuntimeException { private static final long serialVersionUID = 1L; private int code; public MyRuntimeException(int code, String message) { super(message); this.code = code; } public int getCode() { return code; } } package cn.bridgeli.exceptionhandle.exception; import java.util.HashMap; import java.util.Map; public class ValidationException extends Exception { private static final long serialVersionUID = 1L; private Map<String, String> errorFields = new HashMap<String, String>(); public ValidationException() { } public void addErrorFiel(String name, String message) { errorFields.put(name, message); } public String getErrorField(String name) { if (errorFields.containsKey(errorFields)) { return errorFields.get(name); } return ""; } }

August 26, 2014 · 1 min · 161 words · Bridge Li

如何在网络上搭建个人博客

相信有很多程序猿应该都有过自己搭建博客的冲动,但很多时候有一种无从下手的感觉,第一篇博客就写一下,怎么搭建自己的个人博客吧,希望对大家有点帮助。 搭建个人博客主要分以下几步: 1. 购买域名 这个其实很简单,我们只需要在常见的万网、西部数码注册后,只要该域名还未被注册,填一下基本信息,一般都可以了,另外需要说明的是:(1.)、域名是有限资源,如果一个域名被注册了,那么别人就不能注册了,所以想好了域名,大家可以立马去注册,以防被别人抢注,万一被别人抢注,想买回来就很困难了,大家可以搜一下史上最贵的是个域名;(2)、域名注册是有有效期的,如果有效期到了没有续费成功的话,那么这个域名就会被回收,就有了被别人重新注册的风险,所以大家可以试着设置一个自动续费之类的;(3)、经过我的分析,西部数码的域名注册费用会比万网稍稍便宜一些,当然是仅供参考。 2. 购买空间 这个大的分两种:(1)、独立的IP,这个一般会比较贵;(2)、购买空间,没有独立IP,这个相对便宜。一般如果仅仅是搭建一个个人博客的话,购买空间就够了,一般空间提供商会提供一个二级域名供大家调试。 另外购买空间这个分大陆的和非大陆的,大陆的一般比较贵,但访问速度快,而且需要备案,备案这个一般购买域名的地方都会有提供,另外像360也提供免费备案;非大陆的空间一般都比较便宜,也比较稳定,但访问速度会稍慢一些,而且不需要备案,所以也哟哟很多人选择这个,BridgeLi就是选择的这个方案。好了有了域名和空间我们就可以进行接下来第三步了。 3. 准备博客系统 推荐大家使用WordPress,WordPress是目前世界上最流行的博客系统,据说世界上百分之八十的博客,都是WordPress搭建的,可见其影响力,WordPress这么流行的一个原因就是他是开源免费,大家都可以对其进行个性化的开发,而且为了使他更好用,很多牛人对他开发了很对各种各样的插件,大家可以根据自己的具体情况,选用其中部分插件,由此也可见WordPress的可扩展行做的是多么牛,相信这也是其流行的一个原因。 关于WordPress怎么用,BridgeLi在这里就不多说了,因为巨简单,大家可以自己到WordPress官网上下一个看看。 不过需要说明的WordPress是PHP语言写得,所以在搭建博客时,需要我们的系统支持PHP,BridgeLi的空间实在西部数码买的,在预装软件一栏里,选择WordPress就可以了,一键生成,属于傻瓜式,当然大家也可以自己一步一步的去搭建,推荐LAMP。 4. 域名绑定 一切已经就绪,当然下面就是绑定域名啦,如果域名绑定成功的话,我们应该就可以通过我们的域名来访问我们的博客了。因为BridgeLi是在西部数码买的空间,使用的预装的WordPress系统,所以下面先以这个为例进行讲解,选择个人中心–>主机管理,会有一个域名绑定,我们只需要按照步骤一步一步就可以了,需要说明的是,如果你的域名是在西部数码买的,那么应该在添加域名绑定之后应该局可以访问了,但如果您不是在西部数码买的,像BridgeLi就是在万网买的域名,就需要到万网那边,把西部数码提供的二级域名添加到域名解析里面就行了,关于DNS服务器我们可以忽略,关于域名解析,大家眼看自己空间的类型,如果是独立IP,那么肯定就是A,具体大家可以看万网和西部数码的文档,BridgeLi就不在这里一一赘述了。 另外还有一种情况是自己搭建的系统,也就是我们只买了一个域名、一个空间,博客系统是自己传上去的,那么如何进行域名绑定呢?当然域名解析肯定还是要到注册地方的域名解析中去添加,添加完成之后,我们就可以通过:域名+ / + 项目名称就行访问了,我们当然不希望是这样的,直接通过域名访问多好啊,这就需要我们对服务器进行一番设置,因为BridgeLi是对Java开发的,对tomcat比较熟,下面就以tomcat为例进行说明,主要有两步: (1)、打开server.xml文件,在和之间插入如下语句。 <Context path=”” docBase=”” debug=”0″ privileged=”true”> 其中path为空,就是为了去掉访问时的/项目名称,docBase是项目所在的目录,如果是war包,一定要项目名称,如果是源码包(这个应该很少),则一定要详细到webRoot(MyEclipse项目)或者webContent(Eclipse项目) (2)、删除webapps文件夹下的ROOT文件夹就可以了 经过以上四步,我们就在网络上拥有自己的博客了,怎么样,很简单吧?想搭建博客的你,还犹豫什么,马上行动吧!

August 25, 2014 · 1 min · 30 words · Bridge Li