Popular Posts
ADD ... THEN ... UNTIL ... data: begin of SERIES, N1 type I value 10, N2 type I value 20, N3 type I value 30, N4 type I value 40, ... Join related table and count rows or sum sql server 2005 count rows: SELECT * FROM Table1 LEFT JOIN     (SELECT Level1ID, COUNT(Level2ID) AS Total FROM Table2 GROUP BY Level1ID) AS... Remove file not in list
Stats
Operate form in WebView and get content
class ContentLoader {
    @JavascriptInterface
    public void load(String body) {
        // do something
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView webView = createWebView();

    webView.loadUrl("https://www.somedoamin.com/product.jsp");
    // enable javascript
    webView.getSettings().setJavaScriptEnabled(true);
    // add interface
    webView.addJavascriptInterface(new ContentLoader(), "ContentLoader");
    webView.setWebViewClient(new WebViewClient() {

        int action;

        @Override
        public void onPageFinished(WebView view, String url) {
            switch (action) {
                case 0:
                    // fill field and submit
                    view.loadUrl("javascript:{\n" +
                            "\tdocument.querySelector('input[name=cgi_tel_no]').value='12345678';\n" +
                            "\tdocument.querySelector('input[name=cgi_id_no]').value='abcdef';\n" +
                            "\tsubmitMyForm();\n" +
                            "};");
                case 1:
                    // get content from 'ContentLoader' interface
                    view.loadUrl("javascript:{\n" +
                            "\twindow.ContentLoader.load('<body>'+document.body.innerHTML+'</body>');\t\n" +
                            "};");
                    break;
            }

            action++;
        }
    });
}

WebView createWebView() {
    WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 0;
    params.width = 0;
    params.height = 0;

    LinearLayout layout = new LinearLayout(this);
    layout.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));

    WebView view = new WebView(this);
    view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
    layout.addView(view);

    windowManager.addView(layout, params);

    return view;
}
Gitlab

安裝

線上安裝,支援的 OS 有 Ubuntu、Debian、CentOS、Raspberry PI 2 on Raspbian。直接依照說明即可完成。

建議安裝時也同時下載目前安裝的版本,避免之後有移轉問題需要還原。各版本下載位址為

備份

# 執行備份
gitlab-rake gitlab:backup:create

還原

# 複製備份檔至備份路徑
sudo cp 1493107454_2017_04_25_9.1.0_gitlab_backup.tar /var/opt/gitlab/backups/

# 停止服務
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq

# 開始還原
sudo gitlab-rake gitlab:backup:restore BACKUP=1493107454_2017_04_25_9.1.0

# 啟動系統
sudo gitlab-ctl start

# 檢查還原結果
sudo gitlab-rake gitlab:check SANITIZE=true

由 SVN 移轉

建立 svn 與 git 作者的 mapping 檔(author.txt)

nanashi07 = Bruce <nanashi07@haha.com>

由 svn 簽出為 git 專案

# clone from svn
# with standard layout(trunk/branches/tags), "-s" argument is required
# "author.txt" contains a list that svn accounts mapping to git authors
git svn clone https://10.10.10.162/svn/caml/Caml.Maker --authors-file=author.txt --no-metadata -s Caml.Maker
cd Caml.Maker
# convert tags
git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done
# convert branches
git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done
# add remote repository
git remote add origin http://nanashi07:password@10.10.10.222/caml/Caml.Maker.git
# push to remote
git push origin --all
cd ..

升級

# 停止服務
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl stop nginx

# 備份
sudo gitlab-rake gitlab:backup:create

# 安裝下載的檔案
# Ubuntu/Debian:
sudo dpkg -i gitlab_x.x.x-omnibus.xxx.deb

# CentOS:
sudo rpm -Uvh gitlab-x.x.x_xxx.rpm

# 重新設定與啟動
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
Output a file like url via routing
Prepare a binary output action for file output
[RoutePrefix("images")]
public class ImageController : Controller
{
    // GET: ~/images/profile.png
    // GET: ~/images/1873429732.jpg
    [HttpGet]
    [Route("{name}.{ext}")]
    public ActionResult ReadImage(string name, string ext)
    {
        if (System.IO.File.Exists(Server.MapPath(string.Format("~/uploads/{0}.{1}", name, ext))))
        {
            byte[] data = System.IO.File.ReadAllBytes(Server.MapPath(string.Format("~/uploads/{0}.{1}", name, ext)));
            string contentType = MimeMapping.GetMimeMapping(System.IO.Path.GetFileName(string.Format("{0}.{1}", name, ext)));
            return File(data, contentType);
        }
        else
        {
            return new HttpStatusCodeResult(404);
        }
    }
}

Then try test it, but respone 404 not found.




Add runAllManagedModulesForAllRequests="true" on modules section.


<?xml version="1.0" encoding="utf-8"?>
<configuration>
  ...
  <system.webServer>
    ...
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="ApplicationInsightsWebTracking"/>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
        preCondition="managedHandler"/>
    </modules>
  </system.webServer>
  ...
</configuration>

Then try it again, image rendered success.


Install subversion with apache server on linux (ubuntu)
# 更新 apt package
sudo apt-get update
# 安裝 package
sudo apt-get install subversion apache2 libapache2-svn apache2-utils
# 建立 svn 資料夾
sudo mkdir -p /svn/repos/
# 建立 svn 使用者 (apache)
sudo mkdir -p /svn/users/
# 建立使用者(第一次時有參數-c)
sudo htpasswd -cm /svn/users/svnpasswd nanashi07
# 刪除使用者後再重建(重設密碼)
#sudo htpasswd -D /svn/users/svnpasswd nanashi07
#sudo htpasswd -m /svn/users/svnpasswd nanashi07
# 修改 apache 設定
sudo vi /etc/apache2/mods-enabled/dav_svn.conf
<Location /svn>
  DAV svn
  SVNParentPath /svn/repos/
  AuthType Basic
  AuthName "SVN Repository"
  AuthUserFile /svn/users/svnpasswd
  Require valid-user
</Location>
# 修改 apache 監聽埠
sudo vi /etc/apache2/ports.conf
# 重新啟動 apache
sudo service apache2 restart
# 建立資源庫
sudo svnadmin create /svn/repos/myproject
# 設定資源庫權限
sudo chown -R www-data:www-data /svn/repos/myproject
# 設定資源庫權限
sudo chmod -R g+rws /svn/repos/myproject
Add file to google drive
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SyncDump
{
    class Program
    {
        /// <summary>
        /// 存取權限
        /// </summary>
        static string[] Scopes = { DriveService.Scope.Drive, DriveService.Scope.DriveFile };
        static string ApplicationName = "Drive Uploader";

        static void Main(string[] args)
        {
            // 檢查輸入參數
            if (args.Length < 1)
            {
                Console.WriteLine("No target file argument!");
                return;
            }

            // 要上傳的檔案
            string dumpPath = args[0];
            string dumpName = System.IO.Path.GetFileName(dumpPath);

            // 載入驗證資訊
            GoogleCredential credential;
            using (var stream = new System.IO.FileStream("client_secret.json", System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                credential = GoogleCredential.FromStream(stream);
            }

            // 建立 service
            DriveService service = new DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential.CreateScoped(Scopes),
                ApplicationName = ApplicationName
            });
            
            // 進行上傳
            insertFile(
                service,
                dumpName,
                dumpName,
                System.Configuration.ConfigurationManager.AppSettings["drive.folder.id"],
                "application/oct-stream",
                dumpPath
            );
        }

        /// <summary>
        /// 新增檔案
        /// </summary>
        /// <param name="service">Drive API service instance.</param>
        /// <param name="title">Title of the file to insert, including the extension.</param>
        /// <param name="description">Description of the file to insert.</param>
        /// <param name="parentId">Parent folder's ID.</param>
        /// <param name="mimeType">MIME type of the file to insert.</param>
        /// <param name="filename">Filename of the file to insert.</param><br>  /// <returns>Inserted file metadata, null is returned if an API error occurred.</returns>
        private static File insertFile(DriveService service, string title, string description, string parentId, string mimeType, string filename)
        {
            // 檔案資訊
            File body = new File();
            body.Title = title;
            body.Description = description;
            body.MimeType = mimeType;

            // 設定上傳位置
            if (!string.IsNullOrEmpty(parentId))
            {
                body.Parents = new List<ParentReference>() { new ParentReference() { Id = parentId } };
            }

            // 檔案內容
            byte[] byteArray = System.IO.File.ReadAllBytes(filename);
            System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
            try
            {
                FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, mimeType);
                request.Upload();

                File file = request.ResponseBody;

                Console.WriteLine("{0:yyyy/MM/dd HH:mm:ss} File {1} is uploaded to drive", DateTime.Now, file.Title);

                return file;
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: " + e.Message);
                return null;
            }
        }
    }
}
Compile source via JavaCompiler
import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

/**
 * Created by nanashi07 on 15/12/13.
 */
public class CompileOnFly {

    public static void main(String args[]) throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

        StringWriter writer = new StringWriter();
        PrintWriter out = new PrintWriter(writer);
        out.println("package com.prhythm.output;");
        out.println();
        out.println("public class OutputImpl implements IOutput {");
        out.println();
        out.println("   public void printFor(String message) {");
        out.println("       System.out.printf(\"Print from %s : %s%n\", getClass().getName(), message);");
        out.println("   }");
        out.println();
        out.println("}");
        out.close();
        JavaFileObject file = new TextJavaObject("com.prhythm.output.OutputImpl", writer.toString());

        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);

        boolean success = task.call();
        for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
            System.out.printf("Code: %s%n", diagnostic.getCode());
            System.out.printf("Kind: %s%n", diagnostic.getKind());
            System.out.printf("Position: %s%n", diagnostic.getPosition());
            System.out.printf("StartPosition: %s%n", diagnostic.getStartPosition());
            System.out.printf("EndPosition: %s%n", diagnostic.getEndPosition());
            System.out.printf("Source: %s%n", diagnostic.getSource());
            System.out.printf("Message: %s%n", diagnostic.getMessage(null));
        }

        if (success) {
            try {
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{new File("").toURI().toURL()});
                Class<?> outClass = Class.forName("com.prhythm.output.OutputImpl", true, classLoader);
                Object outInstance = outClass.newInstance();
                outClass.getDeclaredMethod("printFor", new Class[]{String.class}).invoke(outInstance, "Bruce");
            } catch (ClassNotFoundException e) {
                System.err.println("Class not found: " + e);
            } catch (NoSuchMethodException e) {
                System.err.println("No such method: " + e);
            } catch (IllegalAccessException e) {
                System.err.println("Illegal access: " + e);
            } catch (InvocationTargetException e) {
                System.err.println("Invocation target: " + e);
            } catch (InstantiationException e) {
                System.err.println("Initialize instance: " + e);
            }
        }
    }
}

class TextJavaObject extends SimpleJavaFileObject {
    final String code;

    TextJavaObject(String name, String code) {
        super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
        this.code = code;
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        return code;
    }
}

Output:

Print from com.prhythm.output.OutputImpl : Bruce
Annotation processor on Intellij IDEA
Project structure
+ ---- annotation- processor
| + ---- annotation- lib
|   + ---- build.gradle
|   + ---- src
|     + ---- main
|     | + ---- java
|     |   + ---- com
|     |     + ---- prhythm
|     |       + ---- annotations
|     |         + ---- PrintUsage.java
|     |         + ---- PrintUsageProcessor.java
|     | + ---- resources
|         + ---- META-INF
|           + ---- services
|             + ---- javax.annotation.processing.Processor
| + ---- foo
|   + ---- build.gradle
|   + ---- src
|     + ---- main
|       + ---- java
|         + ---- com
|           + ---- prhythm
|             + ---- foo
|               + ---- Bar.java
| + ---- build.gradle
| + ---- settings.gradle

PrintUsage.java
package com.prhythm.annotations;

/**
 * Print usage
 * Created by nanashi07 on 15/12/2.
 */
public @interface PrintUsage {
}

PrintUsageProcessor.java
package com.prhythm.annotations;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.Set;

/**
 * Processor of {@link PrintUsage}
 * Created by nanashi07 on 15/12/2.
 */
@SupportedAnnotationTypes("com.prhythm.annotations.PrintUsage")
public class PrintUsageProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        Messager messager = processingEnv.getMessager();
        for (TypeElement typeElement : annotations) {
            for (Element element : roundEnv.getElementsAnnotatedWith(typeElement)) {
                String msg = String.format("Use %s on %s#%s", typeElement, element.getEnclosingElement(), element);
                messager.printMessage(Diagnostic.Kind.NOTE, msg);
            }
        }
        return true;
    }
}

javax.annotation.processing.Processor
com.prhythm.annotations.PrintUsageProcessor

Bar.java
package com.prhythm.foo;

import com.prhythm.annotations.PrintUsage;

/**
 * Test class
 * Created by nanashi07 on 15/12/2.
 */
public class Bar {

    @PrintUsage
    public void move(String name) {

    }

    @PrintUsage
    public long time() {
        return System.currentTimeMillis();
    }

}

build.gradle (foo)
group 'com.prhythm'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.6

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile project(':annotation-lib')
}

Enable annotation processor on preference




Build with gradle

gradle clean build

result


References:



Type Memo

Note: ==================================================
Note: TypeElement: com.prhythm.annotations.PrintUsage
Note: TypeElement.getClass(): class com.sun.tools.javac.code.Symbol$ClassSymbol
Note: TypeElement.getSimpleName(): PrintUsage
Note: TypeElement.getEnclosedElements(): 
Note: TypeElement.getEnclosingElement(): com.prhythm.annotations
Note: TypeElement.getInterfaces(): java.lang.annotation.Annotation
Note: TypeElement.getNestingKind(): TOP_LEVEL
Note: TypeElement.getQualifiedName(): com.prhythm.annotations.PrintUsage
Note: TypeElement.getSuperclass(): none
Note: TypeElement.getTypeParameters(): 
Note: TypeElement.getAnnotationMirrors(): 
Note: TypeElement.asType(): com.prhythm.annotations.PrintUsage
Note: TypeElement.getKind(): ANNOTATION_TYPE
Note: TypeElement.getModifiers(): [public, abstract]
Note: ----------------------------------------------------------
Note: Element: move(java.lang.String)
Note: Element.getModifiers(): [public]
Note: Element.getClass(): class com.sun.tools.javac.code.Symbol$MethodSymbol
Note: Element.getKind(): METHOD
Note: Element.getAnnotationMirrors(): @com.prhythm.annotations.PrintUsage
Note: Element.getSimpleName(): move
Note: Element.asType(): (java.lang.String)void
Note: Element.getEnclosedElements(): 
Note: Element.getEnclosingElement(): com.prhythm.foo.Bar
Note: ----------------------------------------------------------
Note: Element: time()
Note: Element.getModifiers(): [public]
Note: Element.getClass(): class com.sun.tools.javac.code.Symbol$MethodSymbol
Note: Element.getKind(): METHOD
Note: Element.getAnnotationMirrors(): @com.prhythm.annotations.PrintUsage
Note: Element.getSimpleName(): time
Note: Element.asType(): ()long
Note: Element.getEnclosedElements(): 
Note: Element.getEnclosingElement(): com.prhythm.foo.Bar
Note: ==================================================
Note: TypeElement: com.prhythm.annotations.Mark
Note: TypeElement.getClass(): class com.sun.tools.javac.code.Symbol$ClassSymbol
Note: TypeElement.getSimpleName(): Mark
Note: TypeElement.getEnclosedElements(): value(),names()
Note: TypeElement.getEnclosingElement(): com.prhythm.annotations
Note: TypeElement.getInterfaces(): java.lang.annotation.Annotation
Note: TypeElement.getNestingKind(): TOP_LEVEL
Note: TypeElement.getQualifiedName(): com.prhythm.annotations.Mark
Note: TypeElement.getSuperclass(): none
Note: TypeElement.getTypeParameters(): 
Note: TypeElement.getAnnotationMirrors(): 
Note: TypeElement.asType(): com.prhythm.annotations.Mark
Note: TypeElement.getKind(): ANNOTATION_TYPE
Note: TypeElement.getModifiers(): [public, abstract]
Note: ----------------------------------------------------------
Note: Element: com.prhythm.foo.Yahoo
Note: Element.getModifiers(): [public, abstract]
Note: Element.getClass(): class com.sun.tools.javac.code.Symbol$ClassSymbol
Note: Element.getKind(): INTERFACE
Note: Element.getAnnotationMirrors(): @com.prhythm.annotations.Mark("2323")
Note: Element.getSimpleName(): Yahoo
Note: Element.asType(): com.prhythm.foo.Yahoo
Note: Element.getEnclosedElements(): home(java.lang.String)
Note: Element.getEnclosingElement(): com.prhythm.foo
Note: ----------------------------------------------------------
Note: Element: home(java.lang.String)
Note: Element.getModifiers(): [public, abstract]
Note: Element.getClass(): class com.sun.tools.javac.code.Symbol$MethodSymbol
Note: Element.getKind(): METHOD
Note: Element.getAnnotationMirrors(): @com.prhythm.annotations.Mark("110"),@com.prhythm.core.generic.http.annotation.Get("https://tw.yahoo.com")
Note: Element.getSimpleName(): home
Note: Element.asType(): (java.lang.String)java.lang.String
Note: Element.getEnclosedElements(): 
Note: Element.getEnclosingElement(): com.prhythm.foo.Yahoo
MEMO: Url rewrite on default site of IIS

Application Request Rounting is required. Install using web platform installer.

Enable Application Request Rounting.

Set server proxy setting.

Set Enable proxy checked and Enable disk cache unchecked.

Binding host name on default site. Using www.mvc.com as example.

Rewrite www.mvc.com to http://localhost:8080/mvc

Add rewrite rule on default site.

Add rule using blank rule template.

Set rewrite rule for www.mvc.com

The result of www.mvc.com

Add rewrite rule for other iis site on localhost. First, create a new web site, and add an host reference www.mysite.me.

Set rewrite rule for www.mysite.com

Add host binding of default site

The result of www.mysite.com

Display soap message in axis client

client-config.wsdd : should be placed in the root of classpath

<?xml version="1.0" encoding="UTF-8"?>
<deployment name="defaultClientConfig" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

    <handler name="log" type="java:org.apache.axis.handlers.LogHandler">
        <!-- If true, output SOAP messages in the console ; otherwise, output in a file. -->
        <parameter name="LogHandler.writeToConsole" value="false" />
        <!-- Specifies the name of the output file when LogHandler.writeToConsole is false -->
        <parameter name="LogHandler.fileName" value="axis.log" />
    </handler>

    <globalConfiguration>
        <parameter name="disablePrettyXML" value="false" />
        <requestFlow>
            <handler type="log" />
        </requestFlow>
        <responseFlow>
            <handler type="log" />
        </responseFlow>
    </globalConfiguration>

    <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender" />
    <transport name="local" pivot="java:org.apache.axis.transport.local.LocalSender" />
    <transport name="java" pivot="java:org.apache.axis.transport.java.JavaSender" />
</deployment>
JUnit with Spring : orderly test method

When using junit with spring framework for test, to sort execute order of method, will use FixMethodOrder class. It is a little inconvenience because you need to name your test method in correct way.



Execute test method ordered by method name
package com.prhythm.test;

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Created by nanashi07 on 15/6/20.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/application-context.xml")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OrderedTest {

    @Test
    public void test1() {
        System.out.println("test1 executed");
    }

    @Test
    public void test2() {
        System.out.println("test2 executed");
    }

    @Test
    public void test3() {
        System.out.println("test3 executed");
    }

    @Test
    public void test4() {
        System.out.println("test4 executed");
    }
}
Result:
test1 executed
test2 executed
test3 executed
test4 executed


Now there is an another way to do it.



Create a order annotation for customize order
package org.springframework.test.context.junit4;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by nanashi07 on 15/6/20.
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
    int value();
}
Create a junit runner extends SpringJUnit4ClassRunner
package org.springframework.test.context.junit4;

import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.springframework.test.context.TestContextManager;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class SpringJUnit4ClassOrderedRunner extends SpringJUnit4ClassRunner {

    /**
     * Constructs a new {@code SpringJUnit4ClassRunner} and initializes a
     * {@link TestContextManager} to provide Spring testing functionality to
     * standard JUnit tests.
     *
     * @param clazz the test class to be run
     * @see #createTestContextManager(Class)
     */
    public SpringJUnit4ClassOrderedRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> list = super.computeTestMethods();
        Collections.sort(list, new Comparator<FrameworkMethod>() {
            @Override
            public int compare(FrameworkMethod f1, FrameworkMethod f2) {
                Order o1 = f1.getAnnotation(Order.class);
                Order o2 = f2.getAnnotation(Order.class);

                if (o1 == null || o2 == null)
                    return -1;

                return o1.value() - o2.value();
            }
        });
        return list;
    }
}
Run test as customized order
package com.prhythm.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.Order;
import org.springframework.test.context.junit4.SpringJUnit4ClassOrderedRunner;

/**
 * Created by nanashi07 on 15/6/20.
 */
@RunWith(SpringJUnit4ClassOrderedRunner.class)
@ContextConfiguration("classpath:spring/application-context.xml")
public class OrderedTest {

    @Test
    @Order(value = 4)
    public void test1() {
        System.out.println("test1 executed");
    }

    @Test
    @Order(value = 3)
    public void test2() {
        System.out.println("test2 executed");
    }

    @Test
    @Order(value = 2)
    public void test3() {
        System.out.println("test3 executed");
    }

    @Test
    @Order(value = 1)
    public void test4() {
        System.out.println("test4 executed");
    }
}
Result:
test4 executed
test3 executed
test2 executed
test1 executed