Issue
I've recently tried to develop a servlet and then connect it to my android app but I can't get it to work properly. This is my login servlet
@WebServlet(name = "login", value = "/auth/login")
public class AuthUser extends HttpServlet {
private Gson gson = new Gson();
public void init() {
Dao.registerDriver();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
String id = request.getParameter("id");
String psw = request.getParameter("psw");
HttpSession s = request.getSession();
PrintWriter out = response.getWriter();
HashMap<String, Object> responseJson = new HashMap<>();
Student student;
if(id != null && psw != null) {
student = FetchFromDB.fetchStudentData(id);
if (student != null && student.getPassword().equals(psw)) {
s.setAttribute("username", student.getNumber());
s.setAttribute("surname", student.getSurname());
s.setAttribute("role", student.getRole());
responseJson.put("id", request.getSession().getId());
responseJson.put("user", student);
responseJson.put("message", "Logged succesfully");
out.print(new Gson().toJson(responseJson));
} else {
responseJson.put("message", "The mail or the username is not correct, please try again");
out.println(new Gson().toJson(responseJson));
}
} else {
responseJson.put("message", "The mail or username value is null, check that out");
}
out.flush();
}
public void destroy() {
}
}
I call this servlet from my login page in my android app as follow:
private void login() throws MalformedURLException {
RequestQueue queue = Volley.newRequestQueue(this);
String username = usernameText.getText().toString();
String psw = passwordText.getText().toString();
String url = Costants.URL + "auth/login?id="+username+"&psw="+psw+"";
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url,
null,
response -> {
Log.d("In onResponse", ""+response);
try {
Log.d("In callServer", "Object returned: " +response.toString());
intent.putExtra("key-username", usernameText.getText().toString());
intent.putExtra("key-role", response.getJSONObject("user").getString("role"));
intent.putExtra("key-surname", response.getJSONObject("user").getString("surname"));
intent.putExtra("key-session-id", response.getString("id"));
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}, error -> {
VolleyLog.d("In onErrorResponse", "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
}
When I click in the login button it works, so it communicates with the servlet and the main activity starts as it should do. BUT when I try to make another call from my MainActivity the session in the servlet won't be recognised and so the user appears as unkown, here's the code of the mainActivity.
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
String usernameOfLoggedUser;
String surnameOfLoggedUser;
String roleOfLoggedUser;
String sessionId;
Bundle extras;
private UserViewModel viewModel;
private BookedLessonsViewModel bookedLessonsViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
extras = getIntent().getExtras();
usernameOfLoggedUser = extras.getString("key-username", "NoValue");
surnameOfLoggedUser = extras.getString("key-surname", "NoValue");
roleOfLoggedUser = extras.getString("key-role", "NoValue");
sessionId = extras.getString("key-session-id", "NoValue");
showWelcomeToast(usernameOfLoggedUser);
setViewModelUser(usernameOfLoggedUser, roleOfLoggedUser, surnameOfLoggedUser);
fetchBookedLessons(usernameOfLoggedUser);
setupUIElements();
}
/**
* Fetch lessons from db and set the model view for the lessons booked
* @param username
*/
private void fetchBookedLessons(String username) {
String url = Costants.URL + "book/bookedLessonsForUser";
ArrayList<BookedLesson> bookedLessons = new ArrayList<>();
CustomRequest jsonCustomReq = new CustomRequest(
Request.Method.GET,
url,
null,
sessionId,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("in onResponse", response.toString());
// int i = 0;
// try {
// JSONArray reservations = response.getJSONArray("reservations");
// while(i < reservations.length()) {
// JSONObject reservation = reservations.getJSONObject(i);
// String idUser = reservation.getString("idUser");
// String idTeacher = reservation.getString("idTeacher");
// String subject = reservation.getString("nameSubject");
// String day = reservation.getString("day");
// String slot = reservation.getString("slot");
// String status =reservation.getString("status");
//
// BookedLesson bookedLesson = new BookedLesson(idUser, idTeacher, slot, subject, day, status);
// bookedLessons.add(bookedLesson);
// i++;
// }
// } catch (JSONException e) {
// e.printStackTrace();
// } finally {
// setViewModelLessons(bookedLessons);
// }
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}
);
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonCustomReq);
}
private void showWelcomeToast(String username) {
Toast toast = Toast.makeText(getApplicationContext(), "You are logged as: " + username, Toast.LENGTH_SHORT*2);
toast.show();
}
@Override
protected void onResume() {
super.onResume();
fetchBookedLessons(usernameOfLoggedUser);
}
private void setupUIElements() {
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
}
/**
* Set the model view for the user so that every fragment has the data for the logged user
* @param usernameOfLoggedUser
* @param roleOfLoggedUser
* @param surnameOfLoggedUser
*/
private void setViewModelUser(String usernameOfLoggedUser, String roleOfLoggedUser, String surnameOfLoggedUser) {
viewModel = new ViewModelProvider(this).get(UserViewModel.class);
viewModel.setUser(usernameOfLoggedUser);
viewModel.setRole(roleOfLoggedUser);
viewModel.setSurname(surnameOfLoggedUser);
viewModel.getUser().observe(this, username -> {
Log.d("In onCreate", "Share data: " + username);
});
}
/**
* Pass the array fetched and set the model view for the lessons
* @param lessons
*/
private void setViewModelLessons(ArrayList<BookedLesson> lessons) {
bookedLessonsViewModel = new ViewModelProvider(this).get(BookedLessonsViewModel.class);
bookedLessonsViewModel.setBookedLessons(lessons);
bookedLessonsViewModel.getBookedLessons().observe(this, bookedLessons -> {
Log.d("In getBookedLessons", "Lessons: " + bookedLessons.size());
});
}
}
But I get this value in return:
-26 13:48:47.053 12225-12225/com.example.bookinglessons D/in onResponse: {"message":"you're not logged"}
If you know what's going on it would be really helpful, thanks in advance.
Solution
I found the solution for this kind of problems. You just need to add these lines in the onCreate of your first Activity (MainActivity in my case).
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
This solved my problems and mantained the session.
Answered By - Allen