问:
Navigation Drawer ActionBar button not working
I am working on an android project and I'm trying to integrate the new Navigation Drawer using the example from http://developer.android.com/training/implementing-navigation/nav-drawer.html.

Its mostly working except for one thing, the action bar up button doesn't display the menu, but if I swipe my finger over the main activity screen from the edge, then the menu appears, so I know there's nothing wrong with the actual menu, its just the action bar button.

Below is the code

```<code>public class MainActivity extends Activity {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;
    private String[] mPlanetTitles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);

        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList = (ListView)findViewById(R.id.left_drawer);

        MenuItemAdapter menuAdapter = new MenuItemAdapter(this);

        menuAdapter.add(new MenuItem("Hello"));
        menuAdapter.add(new MenuItem("World"));
        menuAdapter.add(new MenuItem("Parsnips"));
        menuAdapter.add(new MenuItem("Turnips"));

        mDrawerList.setAdapter(menuAdapter);

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        mDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                R.drawable.ic_drawer,
                R.string.drawer_open,
                R.string.drawer_closed)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);
        if (savedInstanceState ==  null)
        {
            selectItem(0);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {
        // update the main content by replacing fragments

        android.app.Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
        args.putInt(PlanetFragment.ARGS_PLANET_NUMBER, position);
        fragment.setArguments(args);

        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    public static class PlanetFragment extends android.app.Fragment
    {
        public static final String ARGS_PLANET_NUMBER = "planet_number";

        public PlanetFragment()
        {

        }

        @Override
        public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflator.inflate(R.layout.fragment_planet, container, false);
            int i = getArguments().getInt(ARGS_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];

            //((TextView)rootView.findViewById(R.id.fragment_text_view)).setText(planet);
            getActivity().setTitle("Planet: " + planet);
            return rootView;
        }
    }

    private class MenuItem
    {
        public String menuName;

        public MenuItem(String menuName)
        {
            this.menuName = menuName;
        }
    }

    public class MenuItemAdapter extends ArrayAdapter<MenuItem>
    {
        public MenuItemAdapter (Context context)
        {
            super(context,0);
        }

        public View getView (int position, View convertView, ViewGroup parent)
        {
            convertView = null;
            if (convertView == null)
            {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_menu_item, null);
            }

            /*TextView title = (TextView)convertView.findViewById(R.id.row_title);
            title.setText(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);*/

            EditText title = (EditText)convertView.findViewById(R.id.row_edittext);
            title.setHint(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);

            return convertView;
        }
    }
}
</code>```

Thanks for any help you can provide.

答:
Here i will tell you the SIMPLE AND EASY way to create drawer navigation in android without using of android studio.I have just used an ADT to create navigation drawer.
Here is the code take a look

activity_main.xml

```<code><android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/mainContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
     <TextView
        android:id="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="swipe content"/>
     <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text = "Click to open d"/>
   </RelativeLayout>
   <RelativeLayout
        android:id="@+id/drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity = "start"
        android:background="#FFFFFF">
    <TextView
         android:id="@+id/txt2"
         android:layout_width="200dp"
         android:layout_height="wrap_content"
         android:text="drawer content are here arr"/>
    <Button
         android:id="@+id/bt2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text = "Click to open d"/>
   </RelativeLayout>

</android.support.v4.widget.DrawerLayout>
</code>```

MainActivity.java

```<code>package com.example.drawer1;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private DrawerLayout drawerLayout;
    private View drawerView;
    Button bt1,bt2;
    private DrawerListener myDrawerListner;
    private ActionBarDrawerToggle mDrawerTogle;
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout) findViewById(R.id.dr_layout);
        drawerView = (View) findViewById(R.id.drawer);
        drawerLayout.setDrawerListener(myDrawerListner);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        mDrawerTogle =new ActionBarDrawerToggle(this, drawerLayout,
        R.drawable.ic_drawer,R.string.open_drawer,R.string.close_drawer){
            public void onDrawerOpened(View drawerView) {
            // TODO Auto-generated method stub
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle("SpeakEng");
            }
            public void onDrawerClosed(View view) {
            // TODO Auto-generated method stub
                super.onDrawerClosed(view);
                getActionBar().setTitle("SpeakEng");
            }
        };
        drawerLayout.setDrawerListener(mDrawerTogle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        bt2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.closeDrawer(drawerView);
            }
        });

        bt1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.openDrawer(drawerView);

            }
        });
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        mDrawerTogle.onConfigurationChanged(newConfig);
    }
    public boolean onOptionsItemSelected(MenuItem item){
        if (mDrawerTogle.onOptionsItemSelected(item)){
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState){
        super.onPostCreate(savedInstanceState);
        //Sync the toogle state after onRestoreInstanceState has occured.
        mDrawerTogle.syncState();
    }
   }
</code>```

You can open the drawer 1)by clicking on button,2)pulling from left,3)on clicking drawer icon on action bar.as you want you can open it.I gave you three option.

note: drawerLayout must be root element as shown in code.
  and keep onConfigurationChanged(),onOptionsItemSelected(),onPostCreate().
this three methods are very important to create a navigation drawer.

Best of luck!.

Body:
I am working on an android project and I'm trying to integrate the new Navigation Drawer using the example from http://developer.android.com/training/implementing-navigation/nav-drawer.html.

Its mostly working except for one thing, the action bar up button doesn't display the menu, but if I swipe my finger over the main activity screen from the edge, then the menu appears, so I know there's nothing wrong with the actual menu, its just the action bar button.

Below is the code

public class MainActivity extends Activity {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;
    private String[] mPlanetTitles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);

        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList = (ListView)findViewById(R.id.left_drawer);

        MenuItemAdapter menuAdapter = new MenuItemAdapter(this);

        menuAdapter.add(new MenuItem("Hello"));
        menuAdapter.add(new MenuItem("World"));
        menuAdapter.add(new MenuItem("Parsnips"));
        menuAdapter.add(new MenuItem("Turnips"));

        mDrawerList.setAdapter(menuAdapter);

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        mDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                R.drawable.ic_drawer,
                R.string.drawer_open,
                R.string.drawer_closed)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);
        if (savedInstanceState ==  null)
        {
            selectItem(0);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {
        // update the main content by replacing fragments

        android.app.Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
        args.putInt(PlanetFragment.ARGS_PLANET_NUMBER, position);
        fragment.setArguments(args);

        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    public static class PlanetFragment extends android.app.Fragment
    {
        public static final String ARGS_PLANET_NUMBER = "planet_number";

        public PlanetFragment()
        {

        }

        @Override
        public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflator.inflate(R.layout.fragment_planet, container, false);
            int i = getArguments().getInt(ARGS_PLANET_NUMBER);
            String planet = getResources().getStringArray(R.array.planets_array)[i];

            //((TextView)rootView.findViewById(R.id.fragment_text_view)).setText(planet);
            getActivity().setTitle("Planet: " + planet);
            return rootView;
        }
    }

    private class MenuItem
    {
        public String menuName;

        public MenuItem(String menuName)
        {
            this.menuName = menuName;
        }
    }

    public class MenuItemAdapter extends ArrayAdapter<MenuItem>
    {
        public MenuItemAdapter (Context context)
        {
            super(context,0);
        }

        public View getView (int position, View convertView, ViewGroup parent)
        {
            convertView = null;
            if (convertView == null)
            {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_menu_item, null);
            }

            /*TextView title = (TextView)convertView.findViewById(R.id.row_title);
            title.setText(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);*/

            EditText title = (EditText)convertView.findViewById(R.id.row_edittext);
            title.setHint(getItem(position).menuName);
            title.setVisibility(View.VISIBLE);

            return convertView;
        }
    }
}

Thanks for any help you can provide.

Body:
Here i will tell you the SIMPLE AND EASY way to create drawer navigation in android without using of android studio.I have just used an ADT to create navigation drawer.
Here is the code take a look

activity_main.xml

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/mainContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
     <TextView
        android:id="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="swipe content"/>
     <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text = "Click to open d"/>
   </RelativeLayout>
   <RelativeLayout
        android:id="@+id/drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity = "start"
        android:background="#FFFFFF">
    <TextView
         android:id="@+id/txt2"
         android:layout_width="200dp"
         android:layout_height="wrap_content"
         android:text="drawer content are here arr"/>
    <Button
         android:id="@+id/bt2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text = "Click to open d"/>
   </RelativeLayout>

</android.support.v4.widget.DrawerLayout>

MainActivity.java

package com.example.drawer1;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private DrawerLayout drawerLayout;
    private View drawerView;
    Button bt1,bt2;
    private DrawerListener myDrawerListner;
    private ActionBarDrawerToggle mDrawerTogle;
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout) findViewById(R.id.dr_layout);
        drawerView = (View) findViewById(R.id.drawer);
        drawerLayout.setDrawerListener(myDrawerListner);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        mDrawerTogle =new ActionBarDrawerToggle(this, drawerLayout,
        R.drawable.ic_drawer,R.string.open_drawer,R.string.close_drawer){
            public void onDrawerOpened(View drawerView) {
            // TODO Auto-generated method stub
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle("SpeakEng");
            }
            public void onDrawerClosed(View view) {
            // TODO Auto-generated method stub
                super.onDrawerClosed(view);
                getActionBar().setTitle("SpeakEng");
            }
        };
        drawerLayout.setDrawerListener(mDrawerTogle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        bt2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.closeDrawer(drawerView);
            }
        });

        bt1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                   drawerLayout.openDrawer(drawerView);

            }
        });
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        mDrawerTogle.onConfigurationChanged(newConfig);
    }
    public boolean onOptionsItemSelected(MenuItem item){
        if (mDrawerTogle.onOptionsItemSelected(item)){
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState){
        super.onPostCreate(savedInstanceState);
        //Sync the toogle state after onRestoreInstanceState has occured.
        mDrawerTogle.syncState();
    }
   }

You can open the drawer 1)by clicking on button,2)pulling from left,3)on clicking drawer icon on action bar.as you want you can open it.I gave you three option.

note: drawerLayout must be root element as shown in code.
  and keep onConfigurationChanged(),onOptionsItemSelected(),onPostCreate().
this three methods are very important to create a navigation drawer.

Best of luck!.


来源: stackexchange

问:
Deploy webapp in jetty in OSGI
I've searched a long before posting this question, without finding a satisfying answer, as premise I want say that I would prefer don't using frameworks to do the following task, the only tools I have are Felix, Jetty and a Webapp.

I have a webapp managed with maven which I deploy in jetty outside OSGI env, but now I would like to deploy it in OSGI too, so I'm facing up to with typical OSGI matters and principles, here follows what I understood, please let me know if I'm going wrong:

I can leave maven "war" packaging

With apache.felix maven-bundle-plugin I create OSGI MANIFEST

In OSGI there should be the jetty-bundle started before any "webapp bundle"

The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI
bundles elsewhere

I thank you if you want to add elements, unfortunately I found only articles to quickly transform a standard war in a bundle, but I'm really interested to work in respects of OSGI principles, so I would prefer to be as compliant as possible

答:
Firstly, to answer your higher level OSGi questions:

I can leave maven "war" packaging

Yes, but this then means that you are producing a WAR file, with all the rules that follow. You may therefore end up fighting the maven-war-plugin at some point.

With apache.felix maven-bundle-plugin I create OSGI MANIFEST

I prefer using the bnd-maven-plugin, but both use the same library (bnd) under the covers. Generating the OSGi manifest (rather than writing it by hand) is a very important step toward success.

In OSGI there should be the jetty-bundle started before any "webapp bundle"

In a well written OSGi system there should be absolutely no start up ordering restrictions. Your web application will not be available until Jetty has started, but it should not matter which bundle starts first.

The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI bundles elsewhere

This is up to you. Obviously to remain a valid WAR file the classes must be in WEB-INF/classes. OSGi can cope with this (although you need to set the Bundle-Classpath) but it is not required. If you want to put them in / then go ahead. Embedded JARs are also supported by OSGi, but again, not required. Using / as the class path and referencing libraries using Import-Package is a much more idiomatic use of OSGi.

Servlets in OSGi

There is an OSGi specification which supports web applications. It's called the Web Applications Specification and it is chapter 128 of the OSGi compendium specification. This is one of the ways in which you can publish servlets from inside an OSGi container. There are, however, other ways to use Servlets in OSGi.

If you want to just do everything using a WAR file then skip ahead, as I am about to tell you an alternative, which you may find easier/better.

How to deploy Servlets in OSGi

The best and easiest way to deploy servlets in OSGi is to use the Http Whiteboard (OSGi compendium chapter 140). Registering a servlet is really simple, you simply publish it as an OSGi service with the patterns it should match. For example, when using Declarative Services:

```<code>@Component(property="osgi.http.whiteboard.servlet.pattern=/foo")
public class MyServlet extends HttpServlet implements Servlet {
    ...
}
</code>```

You can also register Filters, Listeners and all sorts of other things. Using Declarative Services like this makes it very easy to interact with other OSGi bundles by injecting services that they provide.

The Apache Felix Http Service is nice, easy to use implementation of this specification which is based on Jetty.

How to deploy a Web Application Bundle

If you really want to deploy as a Web Application Bundle then there are a few things to be aware of.

Edited as per request from the original submitter

The lifecycle of all your servlets is exactly the same as the lifecycle of your bundle, so it's hard to use OSGi services properly. Inside a Web Application Bundle you get no ability to limit the visibility of a servlet if a service it depends on is missing or becomes unavailable. This can lead to you relying on  bundle start order, which sucks!

You have to set extra metadata in your OSGi manifest to ensure that OSGi can cope with the WAR layout, and recognise your bundle for processing.

Bundle-ClassPath: WEB-INF/classes[, WEB-INF/lib/foo.jar]

Web-ContextPath:

Jetty is not (to my knowledge) an implementation of the OSGi Web Applications Specification. You will need an implementation (which could be running on top of Jetty), for example PAX-Web.

The OSGi Web Applications specification only defines support for Servlet 2.5 (anything higher is implementation value add).

Many people view Web Application bundles as a migration path, rather than an end goal. Having a peculiar internal layout (WEB-INF/classes) and typically following a "fat jar" model means that web application bundles often have limited modularity and can be hard to use with other tools. Also their inability to interact well with OSGi services (see point 1) makes them harder to write/maintain than more modular patterns such as the OSGi Http Service Whiteboard. This means some (myself included) see a Web Application bundle as a "first step" in migrating to OSGi, eventually using the Http Service Whiteboard.

Depending on the way that your maven build is set up you may find that it is necessary to use the -wab instruction for bnd. This gets bnd to put your classes into WEB-INF/classes and to set up the Bundle-ClassPath

ContentLicense: CC BY-SA 3.0

Title: Deploy webapp in jetty in OSGI

Body:
Firstly, to answer your higher level OSGi questions:

I can leave maven "war" packaging

Yes, but this then means that you are producing a WAR file, with all the rules that follow. You may therefore end up fighting the maven-war-plugin at some point.

With apache.felix maven-bundle-plugin I create OSGI MANIFEST

I prefer using the bnd-maven-plugin, but both use the same library (bnd) under the covers. Generating the OSGi manifest (rather than writing it by hand) is a very important step toward success.

In OSGI there should be the jetty-bundle started before any "webapp bundle"

In a well written OSGi system there should be absolutely no start up ordering restrictions. Your web application will not be available until Jetty has started, but it should not matter which bundle starts first.

The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI bundles elsewhere

This is up to you. Obviously to remain a valid WAR file the classes must be in WEB-INF/classes. OSGi can cope with this (although you need to set the Bundle-Classpath) but it is not required. If you want to put them in / then go ahead. Embedded JARs are also supported by OSGi, but again, not required. Using / as the class path and referencing libraries using Import-Package is a much more idiomatic use of OSGi.

Servlets in OSGi

There is an OSGi specification which supports web applications. It's called the Web Applications Specification and it is chapter 128 of the OSGi compendium specification. This is one of the ways in which you can publish servlets from inside an OSGi container. There are, however, other ways to use Servlets in OSGi.

If you want to just do everything using a WAR file then skip ahead, as I am about to tell you an alternative, which you may find easier/better.

How to deploy Servlets in OSGi

The best and easiest way to deploy servlets in OSGi is to use the Http Whiteboard (OSGi compendium chapter 140). Registering a servlet is really simple, you simply publish it as an OSGi service with the patterns it should match. For example, when using Declarative Services:

@Component(property="osgi.http.whiteboard.servlet.pattern=/foo")
public class MyServlet extends HttpServlet implements Servlet {
    ...
}

You can also register Filters, Listeners and all sorts of other things. Using Declarative Services like this makes it very easy to interact with other OSGi bundles by injecting services that they provide.

The Apache Felix Http Service is nice, easy to use implementation of this specification which is based on Jetty.

How to deploy a Web Application Bundle

If you really want to deploy as a Web Application Bundle then there are a few things to be aware of.

Edited as per request from the original submitter

The lifecycle of all your servlets is exactly the same as the lifecycle of your bundle, so it's hard to use OSGi services properly. Inside a Web Application Bundle you get no ability to limit the visibility of a servlet if a service it depends on is missing or becomes unavailable. This can lead to you relying on  bundle start order, which sucks!

You have to set extra metadata in your OSGi manifest to ensure that OSGi can cope with the WAR layout, and recognise your bundle for processing.

Bundle-ClassPath: WEB-INF/classes[, WEB-INF/lib/foo.jar]

Web-ContextPath:

Jetty is not (to my knowledge) an implementation of the OSGi Web Applications Specification. You will need an implementation (which could be running on top of Jetty), for example PAX-Web.

The OSGi Web Applications specification only defines support for Servlet 2.5 (anything higher is implementation value add).

Many people view Web Application bundles as a migration path, rather than an end goal. Having a peculiar internal layout (WEB-INF/classes) and typically following a "fat jar" model means that web application bundles often have limited modularity and can be hard to use with other tools. Also their inability to interact well with OSGi services (see point 1) makes them harder to write/maintain than more modular patterns such as the OSGi Http Service Whiteboard. This means some (myself included) see a Web Application bundle as a "first step" in migrating to OSGi, eventually using the Http Service Whiteboard.

Depending on the way that your maven build is set up you may find that it is necessary to use the -wab instruction for bnd. This gets bnd to put your classes into WEB-INF/classes and to set up the Bundle-ClassPath


问:
Can't Access Net TCP service From WCF Test Client
I'm trying to run two WCF services from within IIS one is a web service and one is a Net TCP Binding Service.

Here is a simulcrum of my Web.config (I've anonymized the service name):

```<code><?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="ServerService">
        <endpoint address="ServerService"
                  binding="netTcpBinding"
                  bindingConfiguration=""
                  name="NetTcpEndPoint"
                  contract="IServerService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8523/"/>
            <add baseAddress="htt://localhost:8523/"/>
          </baseAddresses>
        </host>
      </service>

      <service name="MyWebService">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration=""
                  name="AACCWSEndPoint"
                  contract="IMyWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8523/IMyWebService"/>
          </baseAddresses>
        </host>
      </service>

    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>
</code>```

When I run this in the IDE it opens a page running on port 51953 and I can get the WSDL for the webservice by browsing to http://localhost:51953/WebService.svc?wsdl (Note the port is different).
I can't seem to get the WSDL by changing to port to what I've specified in the webconfig file (8523).

When I point the WcfTestClient app at "net.tcp://localhost:8523/ServerService and it gives me an error saying that it can't access the meta data, which as far as I can see I've configured (the second end point in the service).

What am I doing wrong here?

UPDATE:

I've tried changing the port number on the project properties to 8523 as suggested that didn't seem to work, I've also tried changint the address of the mex endpoint to "ServerService\mex" the test client spent some time churning but then it threw the following error:

Error: Cannot obtain Metadata from
  net.tcp://localhost:8523/ServerService If this is a Windows (R)
  Communication Foundation service to which you have access, please
  check that you have enabled metadata publishing at the specified
  address.  For help enabling metadata publishing, please refer to the
  MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: net.tcp://localhost:8523/ServerService     Metadata
  contains a reference that cannot be resolved:
  'net.tcp://localhost:8523/ServerService'.    You have tried to create
  a channel to a service that does not support .Net Framing. It is
  possible that you are encountering an HTTP endpoint.    Expected
  record type 'PreambleAck', found '72'.

I'm going to keep digging but I'd appreciate any help.

UPDATE 2:

I've changed the mex endpoint to a mexTcpBinding:
Here is the service tag:

```<code>    <endpoint address="ServerServiceWS"
              binding="wsHttpBinding"
              bindingConfiguration=""
              name="WSEndPoint"
              contract="IServerService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex"
              binding="mexTcpBinding"
              contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8523/"/>
        <add baseAddress="http://localhost:8523/"/>
      </baseAddresses>
    </host>
  </service>
</code>```

Still no luck. Just to be sure I am entering the correct url into the tester the Url I am using is:

```<code>net.tcp://localhost:8523/ServerService
</code>```

I've also Tried:

```<code>net.tcp://localhost:8523/mex
</code>```

and

```<code>net.tcp://localhost:8523/
</code>```

All of which give me some variation of the following error:

Error: Cannot obtain Metadata from
  net.tcp://localhost:8523/ServerService If this is a Windows (R)
  Communication Foundation service to which you have access, please
  check that you have enabled metadata publishing at the specified
  address.  For help enabling metadata publishing, please refer to the
  MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: net.tcp://localhost:8523/ServerService    Metadata
  contains a reference that cannot be resolved:
  'net.tcp://localhost:8523/ServerService'.    You have tried to create
  a channel to a service that does not support .Net Framing. It is
  possible that you are encountering an HTTP endpoint.    Expected
  record type 'PreambleAck', found '72'.

UPDATE 3

FWIW I think there might be a bigger problem with my WEb.config Here is what it currently looks like:

```<code><?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="ServerService">
        <endpoint address=""
                  binding="netTcpBinding"
                  bindingConfiguration="DefaultBindingConfig"
                  name="NetTcpEndPoint"
                  contract="IServerService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
                  binding="mexTcpBinding"
                  contract="IMetadataExchange"
                  bindingConfiguration="mexBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8523/"/>
          </baseAddresses>
        </host>
      </service>

      <service name="MyWebService">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration=""
                  name="MyWSEndPoint"
                  contract="IMyWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"
                  bindingConfiguration="mexHttpBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8523/MyWebService"/>
          </baseAddresses>
        </host>
      </service>

    </services>
    <bindings>
      <netTcpBinding>
        <binding name="DefaultBindingConfig"
                 maxConnections="5"
                 portSharingEnabled="true" >
        </binding>
        <binding name="mexBinding"
                 portSharingEnabled="true">
          <security mode="None"></security>
        </binding>
      </netTcpBinding>
      <mexTcpBinding>
        <binding name="mexTcpBinding"/>
      </mexTcpBinding>
      <mexHttpBinding>
        <binding name="mexHttpBinding"/>
      </mexHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServerServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="MexBehaviour">
          <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>
</code>```

I can browse to the Webservice and that allows me to get the WSDL using ?wsdl but if I put the Adddress http://localhost:8523/MyWebService into the WCF tester it throws an error too.

Error: Cannot obtain Metadata from http://localhost:8523/MyWebService
  If this is a Windows (R) Communication Foundation service to which you
  have access, please check that you have enabled metadata publishing at
  the specified address.  For help enabling metadata publishing, please
  refer to the MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: http://localhost:8523/MyWebService    Metadata contains
  a reference that cannot be resolved:
  'http://localhost:8523/MyWebService'.    An error occurred while
  receiving the HTTP response to http://localhost:8523/MyWebService.
  This could be due to the service endpoint binding not using the HTTP
  protocol. This could also be due to an HTTP request context being
  aborted by the server (possibly due to the service shutting down). See
  server logs for more details.    The underlying connection was closed:
  An unexpected error occurred on a receive.    Unable to read data from
  the transport connection: An existing connection was forcibly closed
  by the remote host.    An existing connection was forcibly closed by
  the remote hostHTTP GET Error    URI:
  http://localhost:8523/MyWebService    There was an error downloading
  'http://localhost:8523/MyWebService'.    The request failed with HTTP
  status 404: Not Found.

I think the issue is either something to do with paths or I'm just putting the wrong URL into the test application. Either that or I've still not configured the meta data correctly.

答:
just try to keep this  as it is, and changing your service inside and paste it inside your config file, it should work perfectly.
to test the net.tcp you can use SvcUtil.exe </p>

```<code>       <system.serviceModel>
<services>
  <service name="MyWCFServices.HelloWorldService">
    <endpoint
         binding="netTcpBinding"
         bindingConfiguration="ultra"
         contract="MyWCFServices.IHelloWorldService"/>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"  />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8086/HelloWorldService.svc" />
        <add baseAddress="http://localhost:8081/HelloWorldService.svc" />
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <netTcpBinding>
    <binding name="ultra"
         maxBufferPoolSize="2147483647"
         maxBufferSize="2147483647"
         maxReceivedMessageSize="2147483647"
         portSharingEnabled="false"
         transactionFlow="false"
         listenBacklog="2147483647" >
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport protectionLevel="None" clientCredentialType="None"/>
      </security>
      <reliableSession enabled="false"/>
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</code>```

Body:
I'm trying to run two WCF services from within IIS one is a web service and one is a Net TCP Binding Service.

Here is a simulcrum of my Web.config (I've anonymized the service name):

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="ServerService">
        <endpoint address="ServerService"
                  binding="netTcpBinding"
                  bindingConfiguration=""
                  name="NetTcpEndPoint"
                  contract="IServerService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8523/"/>
            <add baseAddress="htt://localhost:8523/"/>
          </baseAddresses>
        </host>
      </service>

      <service name="MyWebService">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration=""
                  name="AACCWSEndPoint"
                  contract="IMyWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8523/IMyWebService"/>
          </baseAddresses>
        </host>
      </service>

    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

When I run this in the IDE it opens a page running on port 51953 and I can get the WSDL for the webservice by browsing to http://localhost:51953/WebService.svc?wsdl (Note the port is different).
I can't seem to get the WSDL by changing to port to what I've specified in the webconfig file (8523).

When I point the WcfTestClient app at "net.tcp://localhost:8523/ServerService and it gives me an error saying that it can't access the meta data, which as far as I can see I've configured (the second end point in the service).

What am I doing wrong here?

UPDATE:

I've tried changing the port number on the project properties to 8523 as suggested that didn't seem to work, I've also tried changint the address of the mex endpoint to "ServerService\mex" the test client spent some time churning but then it threw the following error:

Error: Cannot obtain Metadata from
  net.tcp://localhost:8523/ServerService If this is a Windows (R)
  Communication Foundation service to which you have access, please
  check that you have enabled metadata publishing at the specified
  address.  For help enabling metadata publishing, please refer to the
  MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: net.tcp://localhost:8523/ServerService     Metadata
  contains a reference that cannot be resolved:
  'net.tcp://localhost:8523/ServerService'.    You have tried to create
  a channel to a service that does not support .Net Framing. It is
  possible that you are encountering an HTTP endpoint.    Expected
  record type 'PreambleAck', found '72'.

I'm going to keep digging but I'd appreciate any help.

UPDATE 2:

I've changed the mex endpoint to a mexTcpBinding:
Here is the service tag:

    <endpoint address="ServerServiceWS"
              binding="wsHttpBinding"
              bindingConfiguration=""
              name="WSEndPoint"
              contract="IServerService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex"
              binding="mexTcpBinding"
              contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8523/"/>
        <add baseAddress="http://localhost:8523/"/>
      </baseAddresses>
    </host>
  </service>

Still no luck. Just to be sure I am entering the correct url into the tester the Url I am using is:

net.tcp://localhost:8523/ServerService

I've also Tried:

net.tcp://localhost:8523/mex

and

net.tcp://localhost:8523/

All of which give me some variation of the following error:

Error: Cannot obtain Metadata from
  net.tcp://localhost:8523/ServerService If this is a Windows (R)
  Communication Foundation service to which you have access, please
  check that you have enabled metadata publishing at the specified
  address.  For help enabling metadata publishing, please refer to the
  MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: net.tcp://localhost:8523/ServerService    Metadata
  contains a reference that cannot be resolved:
  'net.tcp://localhost:8523/ServerService'.    You have tried to create
  a channel to a service that does not support .Net Framing. It is
  possible that you are encountering an HTTP endpoint.    Expected
  record type 'PreambleAck', found '72'.

UPDATE 3

FWIW I think there might be a bigger problem with my WEb.config Here is what it currently looks like:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="ServerService">
        <endpoint address=""
                  binding="netTcpBinding"
                  bindingConfiguration="DefaultBindingConfig"
                  name="NetTcpEndPoint"
                  contract="IServerService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
                  binding="mexTcpBinding"
                  contract="IMetadataExchange"
                  bindingConfiguration="mexBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8523/"/>
          </baseAddresses>
        </host>
      </service>

      <service name="MyWebService">
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration=""
                  name="MyWSEndPoint"
                  contract="IMyWebService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange"
                  bindingConfiguration="mexHttpBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8523/MyWebService"/>
          </baseAddresses>
        </host>
      </service>

    </services>
    <bindings>
      <netTcpBinding>
        <binding name="DefaultBindingConfig"
                 maxConnections="5"
                 portSharingEnabled="true" >
        </binding>
        <binding name="mexBinding"
                 portSharingEnabled="true">
          <security mode="None"></security>
        </binding>
      </netTcpBinding>
      <mexTcpBinding>
        <binding name="mexTcpBinding"/>
      </mexTcpBinding>
      <mexHttpBinding>
        <binding name="mexHttpBinding"/>
      </mexHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServerServiceBehaviour">

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
        <behavior name="MexBehaviour">
          <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

I can browse to the Webservice and that allows me to get the WSDL using ?wsdl but if I put the Adddress http://localhost:8523/MyWebService into the WCF tester it throws an error too.

Error: Cannot obtain Metadata from http://localhost:8523/MyWebService
  If this is a Windows (R) Communication Foundation service to which you
  have access, please check that you have enabled metadata publishing at
  the specified address.  For help enabling metadata publishing, please
  refer to the MSDN documentation at
  http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
  Error    URI: http://localhost:8523/MyWebService    Metadata contains
  a reference that cannot be resolved:
  'http://localhost:8523/MyWebService'.    An error occurred while
  receiving the HTTP response to http://localhost:8523/MyWebService.
  This could be due to the service endpoint binding not using the HTTP
  protocol. This could also be due to an HTTP request context being
  aborted by the server (possibly due to the service shutting down). See
  server logs for more details.    The underlying connection was closed:
  An unexpected error occurred on a receive.    Unable to read data from
  the transport connection: An existing connection was forcibly closed
  by the remote host.    An existing connection was forcibly closed by
  the remote hostHTTP GET Error    URI:
  http://localhost:8523/MyWebService    There was an error downloading
  'http://localhost:8523/MyWebService'.    The request failed with HTTP
  status 404: Not Found.

I think the issue is either something to do with paths or I'm just putting the wrong URL into the test application. Either that or I've still not configured the meta data correctly.

Body:
just try to keep this  as it is, and changing your service inside and paste it inside your config file, it should work perfectly.
to test the net.tcp you can use SvcUtil.exe

       <system.serviceModel>
<services>
  <service name="MyWCFServices.HelloWorldService">
    <endpoint
         binding="netTcpBinding"
         bindingConfiguration="ultra"
         contract="MyWCFServices.IHelloWorldService"/>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"  />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8086/HelloWorldService.svc" />
        <add baseAddress="http://localhost:8081/HelloWorldService.svc" />
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <netTcpBinding>
    <binding name="ultra"
         maxBufferPoolSize="2147483647"
         maxBufferSize="2147483647"
         maxReceivedMessageSize="2147483647"
         portSharingEnabled="false"
         transactionFlow="false"
         listenBacklog="2147483647" >
      <security mode="None">
        <message clientCredentialType="None"/>
        <transport protectionLevel="None" clientCredentialType="None"/>
      </security>
      <reliableSession enabled="false"/>
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>


问:
If condition wrongly working
The Following PHP if condition statement is processing wrong and is not working.

File $fname has text values: "990,1000" with a comma in between:

```<code>$myfile = fopen($fname, "r") or die("<script
type='text/javascript'>window.location.href =
'http://www.autorekrooter.com/activation.html';</script>");
$dt=fread($myfile,filesize($fname));
//File fname has values: "990, 1000"
fclose($myfile);
$myArray = explode(',', $dt);
//Now checking if Limit expired or not?
echo "<br>myArray[0] values is: " . $myArray[0] . " myArray[1] value is: " .
$myArray[1];
if ($myArray[0]>=$myArray[1]){
echo "<script>alert('You can't proceed further');</script>";
//echo "<script type='text/javascript'>window.location.href = 'register.html';</script>";
exit();
}
else{
echo "<script type='text/javascript'>window.location.href =
'gui.php';</script>";
echo "You can proceed";
exit();
}
</code>```

When I run the above in a php file the if statement always takes value of myArray[0] >= myArray[1] as true and show the reigster.html whereas in the $fname file it is 990,1000 myArray[0]=990 and myArray[1]=1000 so myArray[0] should not be greater than myArray[1] and the else statement should run but the opposite is happening.

Any suggestions as to why this is not working?

Many Thanks in advance for your answers.

答:
Try this one </p>

```<code>$myArray = array_map('intval', explode(',', $dt));
</code>```

Title: If condition wrongly working

Body:
The Following PHP if condition statement is processing wrong and is not working.

File $fname has text values: "990,1000" with a comma in between:

$myfile = fopen($fname, "r") or die("");
$dt=fread($myfile,filesize($fname));
//File fname has values: "990, 1000"
fclose($myfile);
$myArray = explode(',', $dt);
//Now checking if Limit expired or not?
echo "
myArray[0] values is: " . $myArray[0] . " myArray[1] value is: " .
$myArray[1];
if ($myArray[0]>=$myArray[1]){
echo "";
//echo "";
exit();
}
else{
echo "";
echo "You can proceed";
exit();
}

When I run the above in a php file the if statement always takes value of myArray[0] >= myArray[1] as true and show the reigster.html whereas in the $fname file it is 990,1000 myArray[0]=990 and myArray[1]=1000 so myArray[0] should not be greater than myArray[1] and the else statement should run but the opposite is happening.

Any suggestions as to why this is not working?

Many Thanks in advance for your answers.

Body:
Try this one

$myArray = array_map('intval', explode(',', $dt));


问:
Interacting with iFrame elements before its hidden
I am trying to figure out how to capture the hide event (display:none;) inside an iframe. I have three iframes, and only one at a time is visible, the other two iFrames are hidden. I am using jQuery show(), hide() methods to hide and show different iframes :

```<code>$('#currentFrame').hide();
$('#newIframe').show();
</code>```

I have embedded wistia videos inside these iframes and when one iframe is switched to another I want to pause the current video. hence I want to capture the hide event.

Inside the iFrame I tried this but it doesn't get triggered

$(document).blur( function () {
    var video = Wistia.api("video1");
    video.pause();
});

答:
use the following example, it uses the postMessage function

https://robertnyman.com/html5/postMessage/postMessage.html

Body:
I am trying to figure out how to capture the hide event (display:none;) inside an iframe. I have three iframes, and only one at a time is visible, the other two iFrames are hidden. I am using jQuery show(), hide() methods to hide and show different iframes :

$('#currentFrame').hide();
$('#newIframe').show();

I have embedded wistia videos inside these iframes and when one iframe is switched to another I want to pause the current video. hence I want to capture the hide event.

Inside the iFrame I tried this but it doesn't get triggered

$(document).blur( function () {
    var video = Wistia.api("video1");
    video.pause();
});


问:
Dynamically create Bootstrap Carousel with ng-repeat and base64 Images
I am trying to dynamically fill an Bootstrap Carousel with Base64 Images. The Base64 string seems to be correct, because I validated it with the following converter, but the carousel doesn't render the image.

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {
  $scope.imgBase64 = [" data:image/png;base64,[encoded data, 13864 characters]"];
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div ng-app="myApp" ng-controller="myCtrl">
  <div id="myCarousel" class="carousel slide" data-ride="carousel">
    <!-- Indicators -->
    <ol class="carousel-indicators">
      <li ng-repeat="x in imgBase64 track by $index" data-target="#myCarousel" data-slide-to="{{$index}}" class="{$index==0:'active'}"></li>
    </ol>

    <!-- Wrapper for slides -->
    <div class="carousel-inner">
      <div class="item active">
        <img ng-src="x" alt="Los Angeles" ng-repeat="x in imgBase64 track by $index" class="{$index==0:'active'}">
      </div>
    </div>

    <!-- Left and right controls -->

      <span class="glyphicon glyphicon-chevron-left"></span>
      <span class="sr-only">Previous</span>

      <span class="glyphicon glyphicon-chevron-right"></span>
      <span class="sr-only">Next</span>

  </div>
</div></code>```

答:
User have to create image from base64.

```<code>var image = new Image();
image.src = "data:image/png;base64..."
$scope.imgBase64 = image.src;
</code>```

Body:
I am trying to dynamically fill an Bootstrap Carousel with Base64 Images. The Base64 string seems to be correct, because I validated it with the following converter, but the carousel doesn't render the image.

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {
  $scope.imgBase64 = [" data:image/png;base64,[encoded data, 13864 characters]"];
});

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

      Previous

      Next

Body:
User have to create image from base64.

var image = new Image();
image.src = "data:image/png;base64..."
$scope.imgBase64 = image.src;


问:
Average of grouped rows in Sql Server
I have an Sql Server Table.. it's something like this:

```
Id ...... Column1 ...... Column2
````````````````````````````````
1 ........ 1 ............. 34
2 ........ 1 ............. 44
3 ........ 2 ............. 45
4 ........ 2 ............. 36
5 ........ 2 ............. 23
6 ........ 3 ............. 68
7 ........ 3 ............. 26
```

So, I need to select the average of Column2,but group with column1 before doing that.

I mean, if I say Avg(Column2) it just returns a single row with the average of all rows.

What I need is, first i need to group them by column so:

Average of column2 where column1 = 1

Average of column2 where column1 = 2

Average of column2 where column1 = 3

So I want 3 rows returned with the averages of respective values of column1. I am lost at doing this, any hints / help please?

ps: I tried several related questions, and none of them helped / I couldn't understand.

答:
This following Query will help for Calculate the average value of a ROW:

```<code> select Avg(A.Tamil + A.English + A.Maths + A.Science + A.Social_Science)/5 As
 Average
 from MarkTable A, MarkTable B, MarkTable C
 where A.RollNo='14UCA002'
</code>```

This might helpful...

ContentLicense: CC BY-SA 2.5

Title: Average of grouped rows in Sql Server

Body:
I have an Sql Server Table.. it's something like this:

Id ...... Column1 ...... Column2
````````````````````````````````
1 ........ 1 ............. 34
2 ........ 1 ............. 44
3 ........ 2 ............. 45
4 ........ 2 ............. 36
5 ........ 2 ............. 23
6 ........ 3 ............. 68
7 ........ 3 ............. 26

So, I need to select the average of Column2,but group with column1 before doing that.

I mean, if I say Avg(Column2) it just returns a single row with the average of all rows.

What I need is, first i need to group them by column so:

Average of column2 where column1 = 1

Average of column2 where column1 = 2

Average of column2 where column1 = 3

So I want 3 rows returned with the averages of respective values of column1. I am lost at doing this, any hints / help please?

ps: I tried several related questions, and none of them helped / I couldn't understand.

Body:
This following Query will help for Calculate the average value of a ROW:

 select Avg(A.Tamil + A.English + A.Maths + A.Science + A.Social_Science)/5 As
 Average
 from MarkTable A, MarkTable B, MarkTable C
 where A.RollNo='14UCA002'

This might helpful...


问:
RTMFP successful connection ratio or percentage; AKA Adobe Cirrus, Stratus, LCCS
Do you have actual experience with users establishing Adobe Flash RTMFP P2P connections in the real world?

I've heard a couple of people say only 50% succeed, but that sounds suspiciously low and the people saying that are probably all repeating the same rumor. My own very limited tests with various friends & colleagues work 100% of the time, as long as they have Flash Player 10, but that's obviously not right either.

Do you have some data from a largish test or deployment of home/corporate users?

答:
Adobe Cirrus works on any NAT network which means almost 100% of the current ISP set-top-boxes and most of internets home users.

In corporate secured environnements, RTMFP may not work because it implies unrestricted UDP traffic or custom PROXY servers setups.

More technical infos here :
http://www.adobe.com/devnet/flashplayer/articles/rtmfp_cirrus_app.html

ChatRoulette used RTMFP and proved its reliability


问:
How to share photo to Facebook within iOS app, when Facebook app is not installed on the phone?
Im using FBSDKShareKit (4.22.1), i'm trying to share photo with the following code:

```<code>let photo = FBSDKSharePhoto()
photo1.imageURL = URL(string: "sample url")
photo.isUserGenerated = false
let photoContent = FBSDKSharePhotoContent()
photoContent.photos = [photo]
FBSDKShareDialog.show(from: self, with: photoContent, delegate: nil)
</code>```

but it only works when the native Facebook app is installed on the phone.
I also tried to show the content with Share Button instead of Share Dialog like:

```<code>var shareButton = FBSDKShareButton()
shareButton.shareContent = photoContent
shareButton.center = self.view.center
self.view.addSubview(shareButton)
</code>```

it didn't work, if app was not installed either.

i want the FBSDK i used in my app, opens Safari when Facebook app is not installed, it opens safari by default for FBSDKShareLinkContent, but not working for FBSDKSharePhotoContent.
does anyone know what is the problem?

答:
I have implemented another way to share photos using Graph API. It was very helpful. Here is a link.
Just what you need is to take the permissions from the user to publish_actions
before posting.
Also there is no native facebook app installed. Just got logged in through Browser.

Body:
Im using FBSDKShareKit (4.22.1), i'm trying to share photo with the following code:

let photo = FBSDKSharePhoto()
photo1.imageURL = URL(string: "sample url")
photo.isUserGenerated = false
let photoContent = FBSDKSharePhotoContent()
photoContent.photos = [photo]
FBSDKShareDialog.show(from: self, with: photoContent, delegate: nil)

but it only works when the native Facebook app is installed on the phone.
I also tried to show the content with Share Button instead of Share Dialog like:

var shareButton = FBSDKShareButton()
shareButton.shareContent = photoContent
shareButton.center = self.view.center
self.view.addSubview(shareButton)

it didn't work, if app was not installed either.

i want the FBSDK i used in my app, opens Safari when Facebook app is not installed, it opens safari by default for FBSDKShareLinkContent, but not working for FBSDKSharePhotoContent.
does anyone know what is the problem?

ContentLicense: CC BY-SA 4.0


问:
How do I configure MongoRepository to use the new MongoClient API?
My journey begins with me trying to configure Java driver of MongoDB to use UUID v4 instead of Legacy UUID v3 which is set by default.

I've found this solution here https://groups.google.com/forum/#!msg/mongodb-user/ZJKQpMpCMU4/dW5ATHTcAvgJ which works.

But as he states:

Note that when using the legacy API the codec registry is ignored, so
  this will not use the overridden UUIDCodec

it doesn't work with my MongoRepositoy.

This is my actual configuration:

```<code>@Bean
public MongoDbFactory mongoDbFactory() throws Exception {

    ServerAddress server = new ServerAddress(host,port);

    MongoClientOptions.Builder mcoBuilder = MongoClientOptions.builder();
    CodecRegistry codecRegistry = fromRegistries(fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)),
            MongoClient.getDefaultCodecRegistry());
    mcoBuilder.codecRegistry(codecRegistry).build();
    MongoClientOptions options = mcoBuilder.build();

    MongoClient mongoClient = new MongoClient(server,options);

    return new SimpleMongoDbFactory(mongoClient, mongoDataBase);
}

@Bean
public MongoTemplate mongoTemplate() throws Exception {
    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
    return mongoTemplate;
}
</code>```

If I do:

```<code>mongoClient.getDatabase(mongoDataBase).getCollection("test")
.insertOne(new Document("_id",UUID.randomUUID()));
</code>```

I get:

```<code>{ "_id" : BinData(4,"f0u8ig4TS6KaJGK93xmvNw==") }
</code>```

Otherwise:

```<code>mongoTemplate.getCollection("test")
.insert(new BasicDBObject("_id", UUID.randomUUID()));
</code>```

result on:

```<code>{ "_id" : BinData(3,"mUX4PTPBJo6bIjPufHf0vg==") }
</code>```

I know MongoRepository uses MongoTemplate, although I've set the instance to use MongoClient and not the old Mongo, still not working. Is there any solution?

答:
MongoClient extends Mongo, which has reference to legacy api DB class via getDB(). Although you've registered the new UUID codec with MongoClient which can only be used when you use getDatabase() to get MongoDatabase which spring mongo template current version doesn't and uses getDB(). So your changes to registry are never used.

Spring MongoDB 2.0.0 versions has been updated to use new java driver api. So  your changes should work as expected against 2.0.0 version.

http://docs.spring.io/spring-data/data-mongo/docs/2.0.0.M4/reference/html/

Body:
My journey begins with me trying to configure Java driver of MongoDB to use UUID v4 instead of Legacy UUID v3 which is set by default.

I've found this solution here https://groups.google.com/forum/#!msg/mongodb-user/ZJKQpMpCMU4/dW5ATHTcAvgJ which works.

But as he states:

Note that when using the legacy API the codec registry is ignored, so
  this will not use the overridden UUIDCodec

it doesn't work with my MongoRepositoy.

This is my actual configuration:

@Bean
public MongoDbFactory mongoDbFactory() throws Exception {

    ServerAddress server = new ServerAddress(host,port);

    MongoClientOptions.Builder mcoBuilder = MongoClientOptions.builder();
    CodecRegistry codecRegistry = fromRegistries(fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)),
            MongoClient.getDefaultCodecRegistry());
    mcoBuilder.codecRegistry(codecRegistry).build();
    MongoClientOptions options = mcoBuilder.build();

    MongoClient mongoClient = new MongoClient(server,options);

    return new SimpleMongoDbFactory(mongoClient, mongoDataBase);
}

@Bean
public MongoTemplate mongoTemplate() throws Exception {
    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
    return mongoTemplate;
}

If I do:

mongoClient.getDatabase(mongoDataBase).getCollection("test")
.insertOne(new Document("_id",UUID.randomUUID()));

I get:

{ "_id" : BinData(4,"f0u8ig4TS6KaJGK93xmvNw==") }

Otherwise:

mongoTemplate.getCollection("test")
.insert(new BasicDBObject("_id", UUID.randomUUID()));

result on:

{ "_id" : BinData(3,"mUX4PTPBJo6bIjPufHf0vg==") }

I know MongoRepository uses MongoTemplate, although I've set the instance to use MongoClient and not the old Mongo, still not working. Is there any solution?


问:
Exporting data from mysql to ms excel using vb.net
I am working with exporting the data from mysql to ms excel using vb.net. I can export the data, but the problem here is that the data seems to be redundant. Below is my code:

```<code>    Dim unit(8) As String
    unit(0) = "RHQ"
    unit(1) = "RPSB"
    unit(2) = "ADN"
    unit(3) = "ADS"
    unit(4) = "BCPO"
    unit(5) = "DIPPO"
    unit(6) = "SDN"
    unit(7) = "SDS"

    Dim dataSet As New DataSet
    Dim datatableMain As New System.Data.DataTable()
    Dim dataAdapter As OdbcDataAdapter

    Dim dc As System.Data.DataColumn
    Dim dr As System.Data.DataRow
    Dim colIndex As Integer = 0
    Dim rowIndex As Integer = 0

    'create objects to interface to Excel
    Dim xls As New Excel.Application
    Dim book As Excel.Workbook
    Dim sheet As Excel.Worksheet

    'Export the listview to an Excel spreadsheet
    SaveFileDialog1.Title = "Save Excel File"
    SaveFileDialog1.Filter = "Excel files (*.xls)|*.xls|Excel Files (*.xlsx)|*.xslx"
    SaveFileDialog1.ShowDialog()
    'exit if no file selected
    If SaveFileDialog1.FileName = "" Then
        Exit Sub
    End If

    'create a workbook and get reference to first worksheet
    xls.Workbooks.Add()
    book = xls.ActiveWorkbook
    sheet = book.ActiveSheet

    For Each element As String In unit

        If element <> "" Then
            colIndex = 0
            'Get Number of Applicant
            connect_db()
            cmd = New OdbcCommand
            cmd.Connection = con
            cmd.CommandText = "SELECT COUNT(*) FROM personnel WHERE p_unit='" & element & "' AND p_rank='" & account_type & "'"
            rs = cmd.ExecuteReader()
            rs.Read()
            applicant = rs(0).ToString()
            con.Close()
            MessageBox.Show(element)
            'Generate Qouta
            Dim rnk As String = ""
            connect_db()
            cmd = New OdbcCommand
            cmd.Connection = con
            If account_type = "PO1" Then
                rnk = "PO1-PO2"
            ElseIf account_type = "PO2" Then
                rnk = "PO2-PO3"
            ElseIf account_type = "PO3" Then
                rnk = "PO3-SPO1"
            ElseIf account_type = "SPO1" Then
                rnk = "SPO1-SPO2"
            ElseIf account_type = "SPO2" Then
                rnk = "SPO2-SPO3"
            ElseIf account_type = "SPO3" Then
                rnk = "SPO3-SPO4"
            End If
            cmd.CommandText = "SELECT p_qouta, p_promotable, p_rank, rec_date FROM promotion_qouta WHERE p_rank = '" & rnk & "' AND rec_date = '" & reckon_date & "'"
            rs = cmd.ExecuteReader()
            rs.Read()
            quota = rs(0).ToString()
            promotable = rs(1).ToString()
            dist = Val(applicant) * Val(quota)
            dist = Val(dist) / Val(promotable)
            dist = Math.Round(Val(dist))
            con.Close()

            'Fill data
            connect_db()
            cmd.Dispose()
            cmd = New OdbcCommand
            cmd.Connection = con
            cmd.CommandText = "SELECT rec_no, badge_no, p_rank, f_name, m_name, l_name, qualifier, point, p_unit FROM personnel WHERE rec_date = '" & reckon_date & "' AND p_rank = '" & account_type & "' AND p_unit='" & element & "' ORDER BY point DESC LIMIT 0," & dist & ""
            dataAdapter = New OdbcDataAdapter
            dataAdapter.SelectCommand = cmd

            'Fill data to datatable

            dataAdapter.Fill(datatableMain)
            con.Close()

            'step through rows and columns and copy data to worksheet
            'Export the Columns to excel file

            rowIndex = rowIndex + 2
            sheet.Cells(rowIndex, 1) = element
            sheet.Range("A" & rowIndex).Font.Bold = True
            sheet.Range("A" & rowIndex).VerticalAlignment = ContentAlignment.TopCenter
            sheet.Range("A" & rowIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
            sheet.Range(sheet.Cells(rowIndex, 1), sheet.Cells(rowIndex, 9)).Merge()
            rowIndex = rowIndex + 1

            For Each dc In datatableMain.Columns
                colIndex = colIndex + 1
                sheet.Cells(rowIndex, colIndex) = dc.ColumnName
            Next

            'Export the rows to excel file
            For Each dr In datatableMain.Rows
                rowIndex = rowIndex + 1
                colIndex = 0
                For Each dc In datatableMain.Columns
                    colIndex = colIndex + 1
                    sheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
                Next

            Next

        End If
    Next
    'save the workbook and clean up
    book.SaveAs(SaveFileDialog1.FileName)
    xls.Workbooks.Close()
    xls.Quit()
    releaseObject(sheet)
    releaseObject(book)
    releaseObject(xls)

    MessageBox.Show("Export Successful!", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
</code>```

This is the output:
Output

答:
Perhaps should you re-think your nest for loops: you got exactly what you programmed.

```<code>for each table
   write the header
   write datas
next table
</code>```

If I understood your question properly, you should write something like:

```<code>Write the header
for each table
    write datas
next table
</code>```

Body:
I am working with exporting the data from mysql to ms excel using vb.net. I can export the data, but the problem here is that the data seems to be redundant. Below is my code:

    Dim unit(8) As String
    unit(0) = "RHQ"
    unit(1) = "RPSB"
    unit(2) = "ADN"
    unit(3) = "ADS"
    unit(4) = "BCPO"
    unit(5) = "DIPPO"
    unit(6) = "SDN"
    unit(7) = "SDS"

    Dim dataSet As New DataSet
    Dim datatableMain As New System.Data.DataTable()
    Dim dataAdapter As OdbcDataAdapter

    Dim dc As System.Data.DataColumn
    Dim dr As System.Data.DataRow
    Dim colIndex As Integer = 0
    Dim rowIndex As Integer = 0

    'create objects to interface to Excel
    Dim xls As New Excel.Application
    Dim book As Excel.Workbook
    Dim sheet As Excel.Worksheet

    'Export the listview to an Excel spreadsheet
    SaveFileDialog1.Title = "Save Excel File"
    SaveFileDialog1.Filter = "Excel files (*.xls)|*.xls|Excel Files (*.xlsx)|*.xslx"
    SaveFileDialog1.ShowDialog()
    'exit if no file selected
    If SaveFileDialog1.FileName = "" Then
        Exit Sub
    End If

    'create a workbook and get reference to first worksheet
    xls.Workbooks.Add()
    book = xls.ActiveWorkbook
    sheet = book.ActiveSheet

    For Each element As String In unit

        If element <> "" Then
            colIndex = 0
            'Get Number of Applicant
            connect_db()
            cmd = New OdbcCommand
            cmd.Connection = con
            cmd.CommandText = "SELECT COUNT(*) FROM personnel WHERE p_unit='" & element & "' AND p_rank='" & account_type & "'"
            rs = cmd.ExecuteReader()
            rs.Read()
            applicant = rs(0).ToString()
            con.Close()
            MessageBox.Show(element)
            'Generate Qouta
            Dim rnk As String = ""
            connect_db()
            cmd = New OdbcCommand
            cmd.Connection = con
            If account_type = "PO1" Then
                rnk = "PO1-PO2"
            ElseIf account_type = "PO2" Then
                rnk = "PO2-PO3"
            ElseIf account_type = "PO3" Then
                rnk = "PO3-SPO1"
            ElseIf account_type = "SPO1" Then
                rnk = "SPO1-SPO2"
            ElseIf account_type = "SPO2" Then
                rnk = "SPO2-SPO3"
            ElseIf account_type = "SPO3" Then
                rnk = "SPO3-SPO4"
            End If
            cmd.CommandText = "SELECT p_qouta, p_promotable, p_rank, rec_date FROM promotion_qouta WHERE p_rank = '" & rnk & "' AND rec_date = '" & reckon_date & "'"
            rs = cmd.ExecuteReader()
            rs.Read()
            quota = rs(0).ToString()
            promotable = rs(1).ToString()
            dist = Val(applicant) * Val(quota)
            dist = Val(dist) / Val(promotable)
            dist = Math.Round(Val(dist))
            con.Close()

            'Fill data
            connect_db()
            cmd.Dispose()
            cmd = New OdbcCommand
            cmd.Connection = con
            cmd.CommandText = "SELECT rec_no, badge_no, p_rank, f_name, m_name, l_name, qualifier, point, p_unit FROM personnel WHERE rec_date = '" & reckon_date & "' AND p_rank = '" & account_type & "' AND p_unit='" & element & "' ORDER BY point DESC LIMIT 0," & dist & ""
            dataAdapter = New OdbcDataAdapter
            dataAdapter.SelectCommand = cmd

            'Fill data to datatable

            dataAdapter.Fill(datatableMain)
            con.Close()

            'step through rows and columns and copy data to worksheet
            'Export the Columns to excel file

            rowIndex = rowIndex + 2
            sheet.Cells(rowIndex, 1) = element
            sheet.Range("A" & rowIndex).Font.Bold = True
            sheet.Range("A" & rowIndex).VerticalAlignment = ContentAlignment.TopCenter
            sheet.Range("A" & rowIndex).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow)
            sheet.Range(sheet.Cells(rowIndex, 1), sheet.Cells(rowIndex, 9)).Merge()
            rowIndex = rowIndex + 1

            For Each dc In datatableMain.Columns
                colIndex = colIndex + 1
                sheet.Cells(rowIndex, colIndex) = dc.ColumnName
            Next

            'Export the rows to excel file
            For Each dr In datatableMain.Rows
                rowIndex = rowIndex + 1
                colIndex = 0
                For Each dc In datatableMain.Columns
                    colIndex = colIndex + 1
                    sheet.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
                Next

            Next

        End If
    Next
    'save the workbook and clean up
    book.SaveAs(SaveFileDialog1.FileName)
    xls.Workbooks.Close()
    xls.Quit()
    releaseObject(sheet)
    releaseObject(book)
    releaseObject(xls)

    MessageBox.Show("Export Successful!", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)

This is the output:
Output

Body:
Perhaps should you re-think your nest for loops: you got exactly what you programmed.

for each table
   write the header
   write datas
next table

If I understood your question properly, you should write something like:

Write the header
for each table
    write datas
next table


问:
Image is always NULL on upload form
I'm trying to upload image on user registration via ajax. This is how it's look like the form + some fields for name, password and email which are working good.

```<code><form method="post" class="registerForm" enctype="multipart/form-data" id="login-form">
    <div class="form-group">
        <label><b>Profile Image <span class="required">*</span></b></label>
        <input accept="image/*" type="file" id="picture" name="picture" required>
    </div>
    <div class="clearfix">
        <button type="submit" id="login" class="signupbtn">Sign Up</button>
    </div>
</form>
</code>```

I have found on another thread here on SO that I need to put this on my ajax script

```<code>    var data = $("#login-form").serialize();
    var form = new FormData(document.getElementById('picture'));
    //append files
    var file = document.getElementById('picture').files[0];
    if (file) {
        form.append('picture', file);
    }
</code>```

And this is whole ajax

```<code>function submitForm()
{
    var data = $("#login-form").serialize();
    var form = new FormData(document.getElementById('picture'));
    //append files
    var file = document.getElementById('picture').files[0];
    if (file) {
        form.append('picture', file);
    }
    $.ajax({

        type : 'POST',
        url  : 'registration.php',
        data : data,
        beforeSend: function()
        {
            $("#error").fadeOut();
            $("#login").html('<span class="glyphicon glyphicon-transfer"></span>   sending ...');
        },
        success :  function(data)
        {
            if(data=="registered")
            {
            }
        }
    });
    return false;
}
</code>```

And the server side for the picture part and the query

```<code>if(!empty($_FILES['picture']) && $_FILES['picture']['size']  >0  ){

    $profilePic = $randomString. basename($_FILES['picture']['name']);
    $uploadfile = $uploaddir .$randomString. basename($_FILES['picture']['name']);

    if (move_uploaded_file($_FILES['picture']['tmp_name'], $uploadfile)) {
    } else {
        $error = "error\n";
    }
}else{
    $error ='Please add your Picture!';
}
var_dump($_FILES['picture']);
try
{
    $stmt = $db_con->prepare("SELECT * FROM users WHERE email=:email");
    $stmt->execute(array(":email"=>$email));
    $count = $stmt->rowCount();

    if($count==0){
        $stmt = $db_con->prepare("INSERT INTO users (picture) VALUES (:picture)");
        $stmt->bindParam(":picture",$profilePic);

        if($stmt->execute()) {
            echo "registered";
        }
        else { echo "Query could not execute !"; }
    }
    else{ echo "1"; }
}
catch(PDOException $e){
    echo $e->getMessage();
}
</code>```

I've removed other fields in order keep the code simple as much as possible. All fields got inserted and saved in database except the image name.

What can be the problem? No errors at all. I've got registered on the console and NULL for var_dump($_FILES['picture'])

答:
jQuery processes the data as a string if you don't use proccessData: false. Bellow code will work just fine. Also included some comments in code

```<code>$(document).ready(function (e){
    $("#login-form").on('submit',(function(e){
        e.preventDefault();
        $.ajax({
            url: "registration.php",
            type: "POST",
            data:  new FormData(this), // Data sent to server
            contentType: false, // The content type used when sending data to the server.
            cache: false, // To unable request pages to be cached
            processData:false,  // To send DOMDocument or non processed data file it is set to false
            success: function(data){
                    if(data=="registered"){}
            },
            error: function(){}
        });
    }));
});
</code>```

Title: Image is always NULL on upload form

Body:
I'm trying to upload image on user registration via ajax. This is how it's look like the form + some fields for name, password and email which are working good.

<form method="post" class="registerForm" enctype="multipart/form-data" id="login-form">

        Profile Image *
        <input accept="image/*" type="file" id="picture" name="picture" required>

        <button type="submit" id="login" class="signupbtn">Sign Up</button>

</form>

I have found on another thread here on SO that I need to put this on my ajax script

    var data = $("#login-form").serialize();
    var form = new FormData(document.getElementById('picture'));
    //append files
    var file = document.getElementById('picture').files[0];
    if (file) {
        form.append('picture', file);
    }

And this is whole ajax

function submitForm()
{
    var data = $("#login-form").serialize();
    var form = new FormData(document.getElementById('picture'));
    //append files
    var file = document.getElementById('picture').files[0];
    if (file) {
        form.append('picture', file);
    }
    $.ajax({

        type : 'POST',
        url  : 'registration.php',
        data : data,
        beforeSend: function()
        {
            $("#error").fadeOut();
            $("#login").html('   sending ...');
        },
        success :  function(data)
        {
            if(data=="registered")
            {
            }
        }
    });
    return false;
}

And the server side for the picture part and the query

if(!empty($_FILES['picture']) && $_FILES['picture']['size']  >0  ){

    $profilePic = $randomString. basename($_FILES['picture']['name']);
    $uploadfile = $uploaddir .$randomString. basename($_FILES['picture']['name']);

    if (move_uploaded_file($_FILES['picture']['tmp_name'], $uploadfile)) {
    } else {
        $error = "error\n";
    }
}else{
    $error ='Please add your Picture!';
}
var_dump($_FILES['picture']);
try
{
    $stmt = $db_con->prepare("SELECT * FROM users WHERE email=:email");
    $stmt->execute(array(":email"=>$email));
    $count = $stmt->rowCount();

    if($count==0){
        $stmt = $db_con->prepare("INSERT INTO users (picture) VALUES (:picture)");
        $stmt->bindParam(":picture",$profilePic);

        if($stmt->execute()) {
            echo "registered";
        }
        else { echo "Query could not execute !"; }
    }
    else{ echo "1"; }
}
catch(PDOException $e){
    echo $e->getMessage();
}

I've removed other fields in order keep the code simple as much as possible. All fields got inserted and saved in database except the image name.

What can be the problem? No errors at all. I've got registered on the console and NULL for var_dump($_FILES['picture'])

Body:
jQuery processes the data as a string if you don't use proccessData: false. Bellow code will work just fine. Also included some comments in code

$(document).ready(function (e){
    $("#login-form").on('submit',(function(e){
        e.preventDefault();
        $.ajax({
            url: "registration.php",
            type: "POST",
            data:  new FormData(this), // Data sent to server
            contentType: false, // The content type used when sending data to the server.
            cache: false, // To unable request pages to be cached
            processData:false,  // To send DOMDocument or non processed data file it is set to false
            success: function(data){
                    if(data=="registered"){}
            },
            error: function(){}
        });
    }));
});


问:
Asp.net Core Get Methods Under One Interface
How can I get Method Under One interface like this:

My service classes:

Module A

```<code>public class CollectorA : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}
</code>```

Module B

```<code>public class CollectorB : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}
</code>```

Module C

```<code>public class CollectorC : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}
</code>```

My ICollector interface:

```<code>public interface ICollector
{
    string CollectSomething();
}
</code>```

My IModuleInitializer:

```<code>public interface IModuleInitializer
{
    void Init(IServiceCollection serviceCollection);
}
</code>```

Under Every Service I have ModuleInitializer like this

```<code>public void Init(IServiceCollection serviceCollection)
{
    serviceCollection.AddTransient<ICollector, CollectorA>();
    serviceCollection.AddTransient<ICollector, CollectorB>();
    serviceCollection.AddTransient<ICollector, CollectorC>();
}
</code>```

How can I access for example in win console application this methods over this interface ?

My main class :

```<code>static void Main(string[] args)
{
    //Get String Values each module and show on console ..
}
</code>```

答:
Assuming the following implementation

```<code>pubic class ModuleInitializer : IModuleInitializer{
    public void Init(IServiceCollection serviceCollection) {
        serviceCollection.AddTransient<ICollector, CollectorA>();
        serviceCollection.AddTransient<ICollector, CollectorB>();
        serviceCollection.AddTransient<ICollector, CollectorC>();
    }
}
</code>```

and the other classes in the original question.

After the service provider has been built you can use serviceProvider.GetServices<ICollector>() extension method. Note it is GetServices (plural). It would return IEnumerable<ICollector> containing all the registered implementations.

The following example shows how to use the DI framework

```<code>static void Main(string[] args) {
    var services = new ServiceCollection();
    var moduleInitializer = new ModuleInitializer();
    moduleInitializer.Init(services);
    IServiceProvider serviceProvider = services.BuildServiceProvider();

    //Get String Values each module and show on console ..
    var collectors = serviceProvider.GetServices<ICollector>();
    foreach(ICollector collector in collectors) {
        Console.WriteLine(collector.CollectSomething());
    }
}
</code>```

Body:
How can I get Method Under One interface like this:

My service classes:

Module A

public class CollectorA : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}

Module B

public class CollectorB : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}

Module C

public class CollectorC : ICollector
{
    public string CollectSomething()
    {
        //Do something
    }
}

My ICollector interface:

public interface ICollector
{
    string CollectSomething();
}

My IModuleInitializer:

public interface IModuleInitializer
{
    void Init(IServiceCollection serviceCollection);
}

Under Every Service I have ModuleInitializer like this

public void Init(IServiceCollection serviceCollection)
{
    serviceCollection.AddTransient<ICollector, CollectorA>();
    serviceCollection.AddTransient<ICollector, CollectorB>();
    serviceCollection.AddTransient<ICollector, CollectorC>();
}

How can I access for example in win console application this methods over this interface ?

My main class :

static void Main(string[] args)
{
    //Get String Values each module and show on console ..
}

Body:
Assuming the following implementation

pubic class ModuleInitializer : IModuleInitializer{
    public void Init(IServiceCollection serviceCollection) {
        serviceCollection.AddTransient<ICollector, CollectorA>();
        serviceCollection.AddTransient<ICollector, CollectorB>();
        serviceCollection.AddTransient<ICollector, CollectorC>();
    }
}

and the other classes in the original question.

After the service provider has been built you can use serviceProvider.GetServices<ICollector>() extension method. Note it is GetServices (plural). It would return IEnumerable<ICollector> containing all the registered implementations.

The following example shows how to use the DI framework

static void Main(string[] args) {
    var services = new ServiceCollection();
    var moduleInitializer = new ModuleInitializer();
    moduleInitializer.Init(services);
    IServiceProvider serviceProvider = services.BuildServiceProvider();

    //Get String Values each module and show on console ..
    var collectors = serviceProvider.GetServices<ICollector>();
    foreach(ICollector collector in collectors) {
        Console.WriteLine(collector.CollectSomething());
    }
}