Value set by request.setAttribute() is not available by request.getParameter() [duplicate] - servlets

This question already has answers here:
Value passed with request.setAttribute() is not available by request.getParameter()
(2 answers)
Difference between getAttribute() and getParameter()
(10 answers)
Closed 3 years ago.
I am having an issue where a servlet receives a request parameter forwarded from another servlet as null.
This is part of a Java Web app using JPA and entity manager to manage a Student(id PK) entity Subject(subjectCode PK) entity many to many relationship.
String code = (String) request.getParameter("subCode");
int id = Integer.parseInt((String) request.getParameter("stdToAdd"));
studentFacade.addSubject(id, code);
subjectFacade.addStudent(id,code);
request.setAttribute("subjectCode", code);
request.getRequestDispatcher("ListSubStd").forward(request, response);
String code = (String) request.getParameter("subjectCode");
System.out.println("Subject code: " + code+"\n");
//this prints null when called from the above servlet code
List<Student> students = subjectFacade.getStudents(code);
Subject subject = subjectFacade.find(code);
request.setAttribute("subjectStudentList",students);
request.setAttribute("subject", subject);
request.getRequestDispatcher("ListSubjectStudents.jsp").forward(request, response);
I am getting an issue where subjectCode is being received as null in the second servlet.
Same issue happens with the following two servlets:
int id = Integer.parseInt((String) request.getParameter("stdId"));
String code = (String) request.getParameter("subToAdd");
studentFacade.addSubject(id, code);
subjectFacade.addStudent(id,code);
request.setAttribute("studentId", id);
request.getRequestDispatcher("ListStdSub").forward(request, response);
System.out.println("String passed is : "+request.getParameter("studentId"));
//prints null here as well, but only when called from the servlet above
int id = Integer.parseInt((String) request.getParameter("studentId"));
List subjects = studentFacade.getSubjects(id);
Student student = studentFacade.find(id);
request.setAttribute("studentSubjectList",subjects);
request.setAttribute("student",student);
request.getRequestDispatcher("ListStudentSubjects.jsp").forward(request, response);
The servlets properly edit the relationships, but there is an issue with the parameters being sent to the second servlet.
Any advice appreciated.

You are setting attribute to the request but using request.getParameter().
instead you should use request.getAttribute() method
first part
String code = (String) request.getAttribute("subjectCode");
System.out.println("Subject code: " + code+"\n");
Second part
System.out.println("String passed is : "+request.getAttribute("studentId"));
int id = Integer.parseInt((String) request.getAttribute("studentId"));

Related

Put Method To Update A 'Hotel' Object Ends With System.Text.Json.JsonException

Put request is handled very well as far as I have observed but something goes wrong after an updated hotel object is passed to HotelManager layer from HotelRepository.
That's the error: System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
here is the code in HotelRepository:
public async Task<int> UpdateHotel(Hotel hotel)
{
var sql = "UPDATE Hotels " +
"SET name = #name, city = #city " +
"WHERE Id = #id";
var updatedHotel = new Hotel()
{
Name = hotel.Name,
City = hotel.City,
Id = hotel.Id
};
using (var connection = new SqlConnection(CONNECTION_STRING))
{
return await connection.ExecuteAsync(sql, updatedHotel);
}
}
At first I though it was about the spaces in the sql commands. I realized I did not add any spaces after the ends of the lines so I fixed that but I guess that's not the issue since I still get the same error.
The other routes work well.
Hotel object in the request contains id, name, and city.
Do you know what's wrong?
That's the error: System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
You can try to install the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package to add support for Newtonsoft.Json based features, and check if it can help fix above issue.
services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});

How to avoid Java request.getQueryString() get escaped string [duplicate]

This question already has answers here:
request.getQueryString() seems to need some encoding
(5 answers)
Closed 2 years ago.
I have a Servlet that process a QueryString from a JSP form.
When the JSP send the information to the Servlet, it puts on the URL the query, like this:
https://www.mywebsite.com/search?query=Barcelona
And i receive the data inside the Servlet in this way:
String query = request.getQueryString();
// query will receive "Barcelona"
Everything works alright. The problem comes when the string contains characters from other encodings like russian, chinese, arabic, etc. So, if I put the URL like:
https://www.mywebsite.com/search?query=Медеуский
I will receive in the query variable the following text:
String query = request.getQueryString();
// query will receive " %D0%9C%D0%B5%D0%B4%D0%B5%D1%83%D1%81%D0%BA%D0%B8%D0%B9"
So, how could I avoid the escaped conversion?
Thanks!
You can use URLDecoder.decode(request.getQueryString(), "UTF-8")
or
String unicodeQuery = new String(query.getBytes(), StandardCharsets.UTF_8);
String unicodeQuery = new String(query.getBytes("ISO_8859_1"), StandardCharsets.UTF_8);
String unicodeQuery = new String(query.getBytes(Charset.defaultCharset()), StandardCharsets.UTF_8);

Accessing the query string value using ASP.NET

I have been trying to find the question to my answer but I'm unable to and finally I'm here. What I want to do is access the value passed to a webpage (GET, POST request) using asp.net. To be more clear, for example:
URL: http://www.foobar.com/SaleVoucher.aspx?sr=34
Using asp.net I want to get the sr value i.e 34.
I'm from the background of C# and new to ASP.NET and don't know much about ASP.NET.
Thanx.
Can you refer to this QueryString
Here he says how to access the query string using:
Request.Url.Query
That is not called a Header, but the Query String.
the object document.location.search will contain that and the javascript to get any query string value based on the key would be something like:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
code from other question: https://stackoverflow.com/a/901144/28004

XML validation error when updating Keyword metadata

Following on from my earlier question about creating Address Books (many thanks Peter!), I have a small throw-away console application doing just that and working great - but in addition I'm trying to update the metadata of a Keyword with the Item Id of the created Address Book.
Slightly shortened snippet ...
StaticAddressBook ab = new StaticAddressBook();
ab.Title = title;
ab.Key = key;
ab.Save();
// id is a correct Keyword TCM ID
Keyword k = tdse.GetObject(id, EnumOpenMode.OpenModeEdit);
if (k != null)
{
k.MetadataFields["addressbookid"].value[0] = ab.Id.ItemId;
k.Save(true);
}
I keep getting the following error on Save():
XML validation error. Reason: The element 'Metadata' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188' has invalid child element
'addressbookid' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188'. List of possible elements
expected: 'contact_us_email' in namespace
'uuid:2065d525-a365-4b45-b68e-bf45f0fba188'
But I know the Keyword has the correct Metadata assigned, (thats why I don't bother checking!). Shortened Tridion XML from a current keyword in question:
<tcm:Keyword>
<tcm:Data>
<tcm:MetadataSchemaxlink:type="simple"xlink:title="IP.Location.Metadata" xlink:href="tcm:49-2142-8" />
<tcm:Metadata>
<Metadata xmlns="uuid:2065d525-a365-4b45-b68e-bf45f0fba188">
<email>...</email>
<addressbookid>3</addressbookid>
<contact_us_email>...</contact_us_email>
<request_a_sample_email>...</request_a_sample_email>
<webinar_feedback_email>....</webinar_feedback_email>
</Metadata>
</tcm:Metadata>
<tcm:IsRoot>true</tcm:IsRoot>
</tcm:Data>
</tcm:Keyword>
Have I missed something can Keyword metadata not be updated in this way?
I guess I could look at the Core Service to update Keywords, but it seemed to to make sense to do everything within this application.
UPDATE
Order was key here, strangely!
The following code works:
ItemFields fields = k.MetadataFields;
System.Diagnostics.Debug.WriteLine(fields.Count);
string email = fields[1].value[1];
string contact = fields[3].value[1];
string request = fields[4].value[1];
string webinar = fields[5].value[1];
fields[1].value[1] = email;
fields[2].value[1] = ab.Id.ItemId;
fields[3].value[1] = contact;
fields[4].value[1] = request;
fields[5].value[1] = webinar;
k.Save(true);
Got caught out by the non-0-based index when getting/setting values and had to reassign existing fields back, in order.
Cheers
It seems that the order of the fields has changed in the Schema since that Component was created. At least the Schema expects contact_us_email in the position where you current have addressbookid.
There may be other changes, so I'd verify the order of fields in the Schema and make sure the Component(s) match, before you run your tool.

Passing a variable from one servlet to another servlet

How do I pass a variable array from one servlet to another servlet?
If you're passing the current request to another servlet, then just set it as request attribute.
request.setAttribute("array", array);
request.getRequestDispatcher("/servleturl").include(request, response);
It'll be available in another servlet as follows:
Object[] array = (Object[]) request.getAttribute("array");
Or, if you're firing a brand new request to another servlet, then just set it as request parameters.
StringBuilder queryString = new StringBuilder();
for (Object item : array) {
queryString.append("array=").append(URLEncoder.encode(item, "UTF-8")).append("&");
}
response.sendRedirect("/servleturl?" + queryString);
It'll be available in another servlet as follows:
String[] array = request.getParameterValues("array");
Or, if the data is too large to be passed as request parameters (safe max length is 255 ASCII characters), then just store it in session and pass some unique key as parameter isntead.
String arrayID = UUID.randomUUID().toString();
request.getSession().setAttribute(arrayID, array);
response.sendRedirect("/servleturl?arrayID=" + arrayID);
It'll be available in another servlet as follows:
String arrayID = request.getParameter("arrayID");
Object[] array = (Object[]) request.getSession().getAttribute(arrayID);
request.getSession().removeAttribute(arrayID);

Resources